SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_cycgreedy.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file heur_cycgreedy.c
26 * @brief Greedy primal heuristic. States are assigned to clusters iteratively. At each iteration all possible
27 * assignments are computed and the one with the best change in objective value is selected.
28 * @author Leon Eifler
29 */
30
31#include "heur_cycgreedy.h"
32
33#include <time.h>
34#include <stdlib.h>
35#include "scip/misc.h"
36#include "probdata_cyc.h"
37#include "scip/cons_and.h"
38
39#define HEUR_NAME "cycgreedy"
40#define HEUR_DESC "primal heuristic template"
41#define HEUR_DISPCHAR 'h'
42#define HEUR_PRIORITY 536870911
43#define HEUR_FREQ 1
44#define HEUR_FREQOFS 0
45#define HEUR_MAXDEPTH -1
46#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
47#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
48
49/** primal heuristic data */
50struct SCIP_HeurData
51{
52 int lasteffectrootdepth;/**< index of the last solution for which oneopt was performed */
53 SCIP_Bool local; /**< the heuristic only computes assignments until any improvement is found */
54};
55
56/** calculate the current objective value for a q-matrix */
57static
59 SCIP* scip, /**< SCIP data structure */
60 SCIP_Real** qmatrix, /**< the irreversibility matrix*/
61 SCIP_Real scale, /**< the scaling parameter in the objective function */
62 int ncluster /**< the number of cluster*/
63 )
64{
65 SCIP_Real objective = 0.0;
66 int c;
67 int c2;
68
69 for( c = 0; c < ncluster; ++c )
70 {
71 c2 = ( c + 1 ) % ncluster;
72 objective += qmatrix[c][c2] - qmatrix[c2][c];
73 objective += scale * qmatrix[c][c];
74 }
75
76 /* if we have no transitions at all then irreversibility should be set to 0 */
77 return objective;
78}
79
80/** initialize the q-matrix from a given (possibly incomplete) clusterassignment */
81static
83 SCIP_Real** clusterassignment, /**< the matrix containing the (incomplete) clusterassignment */
84 SCIP_Real** qmatrix, /**< the returned matrix with the irreversibility between two clusters */
85 SCIP_Real** cmatrix, /**< the transition-matrix containg the probability-data */
86 int nbins, /**< the number of bins */
87 int ncluster /**< the number of possible clusters */
88 )
89{
90 int i;
91 int j;
92 int k;
93 int l;
94
95 for( k = 0; k < ncluster; ++k )
96 {
97 for( l = 0; l < ncluster; ++l )
98 {
99 qmatrix[k][l] = 0;
100
101 for( i = 0; i < nbins; ++i )
102 {
103 for( j = 0; j < nbins; ++j )
104 {
105 /* as -1 and 0 are both interpreted as 0, this check is necessary. Compute x_ik*x_jl*c_ij */
106 if( clusterassignment[i][k] < 1 || clusterassignment[j][l] < 1 )
107 continue;
108
109 qmatrix[k][l] += cmatrix[i][j];
110 }
111 }
112 }
113 }
114}
115
116/** update the irreversibility matrix, after the clusterassignment[newcluster][newbin] was either set
117 * from 0 to 1 or from 1 to 0
118 */
119static
121 SCIP_Real** clusterassignment, /**< the matrix containing the (incomplete) clusterassignment */
122 SCIP_Real** qmatrix, /**< the returned matrix with the irreversibility between two clusters */
123 SCIP_Real** cmatrix, /**< the transition-matrix containg the probability-data */
124 int newbin, /**< the bin to be added to the assignment */
125 int newcluster, /**< the bluster in which the bin was changed */
126 int nbins, /**< the number of bins */
127 int ncluster /**< the number of clusters */
128 )
129{
130 int bin;
131 int cluster;
132
133 for( cluster = 0; cluster < ncluster; ++cluster )
134 {
135 for( bin = 0; bin < nbins; ++bin )
136 {
137 /* multiplier is 1 if clusterassignment is 1, and 0 if it is 0 (set to 0) or -1 (unassigned) */
138 int temp = 0;
139 if( clusterassignment[bin][cluster] == 1 )
140 temp = 1;
141
142 if( cluster != newcluster )
143 {
144 qmatrix[newcluster][cluster] += temp * cmatrix[newbin][bin];
145 qmatrix[cluster][newcluster] += temp * cmatrix[bin][newbin];
146 }
147 else
148 {
149 if( bin == newbin )
150 qmatrix[newcluster][newcluster] += cmatrix[newbin][bin];
151 else
152 qmatrix[newcluster][newcluster] += (cmatrix[newbin][bin] + cmatrix[bin][newbin]) * temp;
153 }
154 }
155 }
156}
157
158/** get the temporary objective value bound after newbin would be added to newcluster
159 * but dont not change anything with the clustering
160 */
161static
163 SCIP* scip, /**< SCIP data structure */
164 SCIP_Real** qmatrix, /**< the irreversibility matrix */
165 SCIP_Real** cmatrix, /**< the transition matrix */
166 SCIP_Real** clusterassignment, /**< the clusterassignment */
167 int newbin, /**< the bin that would be added to cluster */
168 int newcluster, /**< the cluster the bin would be added to */
169 int nbins, /**< the number of bins */
170 int ncluster /**< the number of cluster */
171 )
172{
174 SCIP_Real temp;
175 int i;
176
177 obj = getObjective(scip, qmatrix, SCIPcycGetScale(scip), ncluster);
178
179 /* the coh in cluster changes as well as the flow to the next and the previous cluster */
180 for( i = 0; i < nbins; ++i )
181 {
182 temp = (clusterassignment[i][phiinv(newcluster, ncluster)] < 1 ? 0 : 1);
183 obj += (cmatrix[i][newbin] - cmatrix[newbin][i]) * temp;
184 temp = (clusterassignment[i][phi(newcluster, ncluster)] < 1 ? 0 : 1);
185 obj -= (cmatrix[i][newbin] - cmatrix[newbin][i]) * temp;
186 temp = (clusterassignment[i][newcluster] < 1 ? 0 : 1);
187 obj += (cmatrix[i][newbin] + cmatrix[newbin][i]) * temp;
188 }
189
190 return obj;
191}
192
193/* find and assign the next unassigned bin to an appropriate cluster */
194static
196 SCIP* scip, /**< SCIP data structure */
197 SCIP_Bool localheur, /**< should the heuristic only compute local optimal assignment */
198 SCIP_Real** clusterassignment, /**< the matrix with the Clusterassignment */
199 SCIP_Real** cmatrix, /**< the transition matrix */
200 SCIP_Real** qmatrix, /**< the irreversibility matrix */
201 SCIP_Bool* isassigned, /**< TRUE, if the bin i was already assigned to a cluster*/
202 int nbins, /**< the number of bins*/
203 int ncluster, /**< the number of cluster*/
204 int* amountassigned, /**< the total amount of bins already assigned*/
205 int* binsincluster, /**< the number of bins currently in a cluster*/
206 SCIP_Real* objective /**< the objective */
207 )
208{
209 SCIP_Real* binobjective;
210 SCIP_Bool** clusterispossible;
211 int* bestcluster;
212 SCIP_Real tempobj;
214 int i;
215 int c;
216 int c1;
217 int c2;
218 int save = -1;
219 int ind = -1;
220
221 /* allocate memory */
222 SCIP_CALL( SCIPallocClearBufferArray(scip, &binobjective, nbins) );
223 SCIP_CALL( SCIPallocClearBufferArray(scip, &bestcluster, nbins) );
224 SCIP_CALL( SCIPallocClearBufferArray(scip, &clusterispossible, nbins) );
225
226 for( i = 0; i < nbins; ++i )
227 {
228 SCIP_CALL( SCIPallocClearBufferArray(scip, &clusterispossible[i], ncluster) ); /*lint !e866*/
229 }
230
231 /* make ceratin that each cluster is non-empty*/
232 for( c = 0; c < ncluster; ++c )
233 {
234 tempobj = 0;
235
236 if( binsincluster[c] == 0 )
237 {
238 for( i = 0; i < nbins; ++i )
239 {
240 /* if already assigned do nothing */
241 if( isassigned[i] )
242 continue;
243
244 /* check if assigning this state is better than the previous best state */
245 binobjective[i] = getTempObj(scip, qmatrix, cmatrix, clusterassignment, i, c, nbins, ncluster);
246
247 if( binobjective[i] > tempobj )
248 {
249 save = i;
250 tempobj = binobjective[i];
251 }
252
253 /* ensure that a state is assigned */
254 if( save == -1 )
255 save = i;
256 }
257
258 /* assign the found state to the cluster */
259 for( c1 = 0; c1 < ncluster; ++c1 )
260 {
261 clusterassignment[save][c1] = 0;
262 }
263
264 clusterassignment[save][c] = 1;
265 binsincluster[c]++;
266
267 assert(binsincluster[c] == 1);
268
269 isassigned[save] = TRUE;
270 *amountassigned += 1;
271
272 /* update the q-matrix */
273 updateIrrevMat(clusterassignment, qmatrix, cmatrix, save, c, nbins, ncluster);
274 }
275 }
276
277 /*phase 2: iteratively assign states such that at each iteration the highest objective improvement is achieved */
278 for( i = 0; i < nbins; ++i )
279 {
280 bestcluster[i] = 0;
281 binobjective[i] = -SCIPinfinity(scip);
282 }
283
284 for( i = 0; i < nbins; ++i )
285 {
286 if( isassigned[i] )
287 continue;
288
289 /* check which clusters the bin can be assigned to. -1 means unassigned, 0 means fixed to 0. */
290 for( c1 = 0; c1 < ncluster; ++c1 )
291 {
292 /* if assignment to i would violate abs-var assignment then set clusterpossible to FALSE */
293 if( 0 != clusterassignment[i][c1] )
294 clusterispossible[i][c1] = TRUE;
295 else
296 clusterispossible[i][c1] = FALSE;
297 }
298
299 /* calculate the irrevbound for all possible clusterassignments */
300 for( c2 = 0; c2 < ncluster; ++c2 )
301 {
302 if( !clusterispossible[i][c2] || clusterassignment[i][c2] == 0 )
303 continue;
304
305 /* temporarily assign i to c2 */
306 save = (int) clusterassignment[i][c2];
307 clusterassignment[i][c2] = 1;
308
309 /* save the best possible irrevbound for each bin */
310 tempobj = getTempObj(scip, qmatrix, cmatrix, clusterassignment, i, c2, nbins, ncluster);
311
312 /* check if this is an improvement compared to the best known assignment */
313 if( SCIPisGT(scip, tempobj, binobjective[i]) )
314 {
315 binobjective[i] = tempobj;
316 bestcluster[i] = c2;
317 }
318
319 clusterassignment[i][c2] = save;
320 }
321
322 /* if localheur is true, then the heuristic assigns a state as soon as any improvement is found */
323 if( localheur && SCIPisGT(scip, binobjective[i], *objective) )
324 break;
325 }
326
327 /* take the bin with the highest increase in irrev-bound */
328 for( i = 0; i < nbins; ++i )
329 {
330 if( SCIPisLT(scip, max, binobjective[i]) )
331 {
332 max = binobjective[i];
333 ind = i;
334 }
335 }
336
337 assert(!isassigned[ind] && ind > -1 && ind < nbins);
338
339 /* assign this bin to the found cluster */
340 for( c1 = 0; c1 < ncluster; ++c1 )
341 {
342 clusterassignment[ind][c1] = 0;
343 }
344
345 clusterassignment[ind][bestcluster[ind]] = 1;
346 binsincluster[bestcluster[ind]]++;
347 *amountassigned += 1;
348 isassigned[ind] = TRUE;
349
350 /* update the Irreversibility matrix */
351 updateIrrevMat(clusterassignment, qmatrix, cmatrix, ind, bestcluster[ind], nbins, ncluster);
352 *objective = getObjective(scip, qmatrix, SCIPcycGetScale(scip), ncluster);
353
354 /* free the allocated memory */
355 for( i = 0; i < nbins; ++i )
356 {
357 SCIPfreeBufferArray(scip, &(clusterispossible[i]));
358 }
359 SCIPfreeBufferArray(scip, &clusterispossible);
360 SCIPfreeBufferArray(scip, &bestcluster);
361 SCIPfreeBufferArray(scip, &binobjective);
362
363 return SCIP_OKAY;
364}
365
366/*
367 * Callback methods of primal heuristic
368 */
369
370/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
371static
372SCIP_DECL_HEURCOPY(heurCopyCycGreedy)
373{ /*lint --e{715}*/
374 assert(scip != NULL);
375 assert(heur != NULL);
376
378
379 /* call inclusion method of primal heuristic */
381
382 return SCIP_OKAY;
383}
384
385/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
386static
387SCIP_DECL_HEURFREE(heurFreeCycGreedy)
388{ /*lint --e{715}*/
390
391 assert(heur != NULL);
392 assert(scip != NULL);
393
395
396 /* free heuristic data */
398
399 assert(heurdata != NULL);
400
402 SCIPheurSetData(heur, NULL);
403
404 return SCIP_OKAY;
405}
406
407/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
408static
409SCIP_DECL_HEUREXITSOL(heurExitsolCycGreedy)
410{ /*lint --e{715}*/
411 assert(heur != NULL);
412
414
415 /* reset the timing mask to its default value */
417
418 return SCIP_OKAY;
419}
420
421/** initialization method of primal heuristic (called after problem was transformed) */
422static
423SCIP_DECL_HEURINIT(heurInitCycGreedy)
424{ /*lint --e{715}*/
426
427 assert(heur != NULL);
428 assert(scip != NULL);
429
430 /* get heuristic data */
432 assert(heurdata != NULL);
433
434 /* initialize last solution index */
435 heurdata->lasteffectrootdepth = -1;
436
437 return SCIP_OKAY;
438}
439
440/** execution method of primal heuristic */
441static
442SCIP_DECL_HEUREXEC(heurExecCycGreedy)
443{ /*lint --e{715}*/
444 SCIP_Real** cmatrix; /* the transition matrixx */
445 SCIP_Real** qmatrix; /* the low-dimensional transition matrix between clusters */
446 SCIP_VAR*** binvars; /* SCIP variables */
447 SCIP_Real** clustering; /* matrix for the assignment of the binary variables */
448 int* binsincluster; /* amount of bins in a given cluster */
449 SCIP_Bool* isassigned; /* TRUE if a bin has already bin assigned to a cluster */
450 SCIP_HEURDATA* heurdata; /* the heurdata */
451 SCIP_SOL* sol; /* pointer to solution */
452 SCIP_Bool possible = TRUE; /* can the heuristic be run */
453 SCIP_Bool feasible = FALSE; /* is the solution feasible */
454 SCIP_Real obj = 0.0; /* objective value */
455 int amountassigned; /* total amount of bins assigned */
456 int nbins; /* number of bins */
457 int ncluster; /* number of cluster */
458 int i; /* running indices */
459 int j;
460 int c;
461
463 amountassigned = 0;
464
465 /* for now: do not use heurisitc if weighted objective is used */
467 if( SCIPgetEffectiveRootDepth(scip) == heurdata->lasteffectrootdepth )
468 return SCIP_OKAY;
469
470 heurdata->lasteffectrootdepth = SCIPgetEffectiveRootDepth(scip);
471
472 /* get the problem data from scip */
473 cmatrix = SCIPcycGetCmatrix(scip);
474 nbins = SCIPcycGetNBins(scip);
475 ncluster = SCIPcycGetNCluster(scip);
476 binvars = SCIPcycGetBinvars(scip);
477
478 assert(nbins > 0 && ncluster > 0);
479
480 /* allocate memory for the assignment */
481 SCIP_CALL( SCIPallocClearBufferArray(scip, &clustering, nbins) );
482 SCIP_CALL( SCIPallocClearBufferArray(scip, &binsincluster, ncluster) );
483 SCIP_CALL( SCIPallocClearBufferArray(scip, &qmatrix, ncluster) );
484 SCIP_CALL( SCIPallocClearBufferArray(scip, &isassigned, nbins) );
485
486 for ( i = 0; i < nbins; ++i )
487 {
488 if( i < ncluster )
489 {
490 SCIP_CALL( SCIPallocClearBufferArray(scip, &qmatrix[i], ncluster) ); /*lint !e866*/
491 }
492
493 SCIP_CALL( SCIPallocClearBufferArray(scip, &clustering[i], ncluster) ); /*lint !e866*/
494
495 for( j = 0; j < ncluster; ++j )
496 {
497 /* unassigned is set to -1 so we can differentiate unassigned and fixed in the branch and bound tree */
498 clustering[i][j] = -1;
499 }
500 }
501
502 /* get the already fixed bin-variables from scip. An assignment of -1 one means unassigned.
503 * 0 is fixed to 0, 1 is fixed to 1
504 */
505 for( i = 0; i < nbins; ++i )
506 {
507 for( j = 0; j < ncluster; ++j )
508 {
509 if( NULL == binvars[i][j] )
510 {
511 possible = FALSE;
512 break;
513 }
514
515 /* if the bounds determine a fixed binary variable, then fix the variable in the clusterassignment */
516 if( SCIPisEQ(scip, SCIPvarGetLbGlobal(binvars[i][j]), SCIPvarGetUbGlobal(binvars[i][j])) )
517 {
518 clustering[i][j] = SCIPvarGetLbGlobal(binvars[i][j]);
519
520 if( SCIPisEQ(scip, 1.0, clustering[i][j]) )
521 {
522 binsincluster[j]++;
523 isassigned[i] = TRUE;
524 amountassigned += 1;
525
526 for( c = 0; c < ncluster; ++c )
527 {
528 if( clustering[i][c] == -1 )
529 clustering[i][c] = 0;
530 }
531 }
532 }
533 }
534 }
535
536 /* check if the assignment violates paritioning, e.g. because we are in a subscip */
537 for( i = 0; i < nbins; ++i )
538 {
539 int amountzeros = 0;
540 int sum = 0;
541
542 for( j = 0; j < ncluster; ++j )
543 {
544 if( 0 == clustering[i][j] )
545 amountzeros++;
546 if( 1 == clustering[i][j] )
547 sum++;
548 }
549
550 if( ncluster == amountzeros || sum > 1 )
551 possible = FALSE;
552 }
553
554 if( amountassigned < nbins && possible )
555 {
556 /* initialize the qmatrix and the lower irreversibility bound */
557 computeIrrevMat(clustering, qmatrix, cmatrix, nbins, ncluster);
558 obj = getObjective(scip, qmatrix, SCIPcycGetScale(scip), ncluster);
559
560 /* assign bins iteratively until all bins are assigned */
561 while( amountassigned < nbins )
562 {
563 SCIP_CALL( assignNextBin(scip, heurdata->local, clustering, cmatrix, qmatrix,
564 isassigned, nbins, ncluster, &amountassigned, binsincluster, &obj ) );
565 }
566
567 /* assert that the assignment is valid in the sense that it is a partition of the bins.
568 * Feasibility is not checked in this method
569 */
570 assert(isPartition(scip,clustering, nbins, ncluster));
571
572 /* update the qmatrix */
573 computeIrrevMat(clustering, qmatrix, cmatrix, nbins, ncluster);
574
575 /* set the variables the problem to the found clustering and test feasibility */
576 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
577 SCIP_CALL( assignVars( scip, sol, clustering, nbins, ncluster) );
578 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, TRUE, TRUE, TRUE, TRUE, &feasible) );
579 }
580
581 if( feasible )
583 else
585
586 /* free allocated memory */
587 for ( i = 0; i < nbins; ++i )
588 {
589 SCIPfreeBufferArray(scip, &clustering[i]);
590
591 if( i < ncluster )
592 SCIPfreeBufferArray(scip, &qmatrix[i]);
593 }
594
595 SCIPfreeBufferArray(scip, &isassigned);
596 SCIPfreeBufferArray(scip, &qmatrix);
597 SCIPfreeBufferArray(scip, &binsincluster);
598 SCIPfreeBufferArray(scip, &clustering);
599
600 return SCIP_OKAY;
601}
602
603/*
604 * * primal heuristic specific interface methods
605 */
606
607/** creates the CycGreedy - primal heuristic and includes it in SCIP */
609 SCIP* scip /**< SCIP data structure */
610 )
611{
613 SCIP_HEUR* heur;
614
615 /* create greedy primal heuristic data */
617
618 /* include primal heuristic */
619
622 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCycGreedy, heurdata) );
623
624 assert(heur != NULL);
625
626 /* set non fundamental callbacks via setter functions */
627 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCycGreedy) );
628 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCycGreedy) );
629 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolCycGreedy) );
630 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitCycGreedy) );
631
633 "localheur", "If set to true, heuristic assigns bins as soon as any improvement is found",
634 &heurdata->local, FALSE, TRUE, NULL, NULL) );
635
636 return SCIP_OKAY;
637}
Constraint handler for AND constraints, .
#define NULL
Definition def.h:257
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition heur.c:1507
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:247
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition scip_mem.h:126
#define SCIPallocMemory(scip, ptr)
Definition scip_mem.h:60
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPfreeMemory(scip, ptr)
Definition scip_mem.h:78
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition scip_sol.c:4114
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetEffectiveRootDepth(SCIP *scip)
Definition scip_tree.c:127
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
static SCIP_Real getObjective(SCIP *scip, SCIP_Real **qmatrix, SCIP_Real scale, int ncluster)
SCIP_RETCODE SCIPincludeHeurCycGreedy(SCIP *scip)
static void computeIrrevMat(SCIP_Real **clusterassignment, SCIP_Real **qmatrix, SCIP_Real **cmatrix, int nbins, int ncluster)
static void updateIrrevMat(SCIP_Real **clusterassignment, SCIP_Real **qmatrix, SCIP_Real **cmatrix, int newbin, int newcluster, int nbins, int ncluster)
static SCIP_RETCODE assignNextBin(SCIP *scip, SCIP_Bool localheur, SCIP_Real **clusterassignment, SCIP_Real **cmatrix, SCIP_Real **qmatrix, SCIP_Bool *isassigned, int nbins, int ncluster, int *amountassigned, int *binsincluster, SCIP_Real *objective)
static SCIP_Real getTempObj(SCIP *scip, SCIP_Real **qmatrix, SCIP_Real **cmatrix, SCIP_Real **clusterassignment, int newbin, int newcluster, int nbins, int ncluster)
Greedy primal heuristic. States are assigned to clusters iteratively. At each iteration all possible ...
int c
static SCIP_SOL * sol
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
internal miscellaneous methods
SCIP_RETCODE assignVars(SCIP *scip, SCIP_SOL *sol, SCIP_Real **clustering, int nbins, int ncluster)
int SCIPcycGetNBins(SCIP *scip)
int phiinv(int k, int ncluster)
SCIP_Real SCIPcycGetScale(SCIP *scip)
int SCIPcycGetNCluster(SCIP *scip)
SCIP_VAR *** SCIPcycGetBinvars(SCIP *scip)
SCIP_Real ** SCIPcycGetCmatrix(SCIP *scip)
SCIP_Bool isPartition(SCIP *scip, SCIP_Real **solclustering, int nbins, int ncluster)
problem data for cycle clustering problem
static SCIP_Real phi(SCIP *scip, SCIP_Real val, SCIP_Real lb, SCIP_Real ub)
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXITSOL(x)
Definition type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_FOUNDSOL
Definition type_result.h:56
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166