Scippy

SCIP

Solving Constraint Integer Programs

branch_strongcoloring.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-2024 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 branch_strongcoloring.c
26 * @brief branching rule performing strong branching for the vertex coloring problem
27 * @author Gerald Gamrath
28 *
29 * This file implements an additional branching rule for the coloring algorithm.
30 *
31 * We are looking for two nodes v and w, which are not adjacent in the current graph, and consider
32 * the following two constraints: SAME(v,w) and DIFFER(v,w). More information about the meaning of
33 * these constraints can be found in the documentation of the branching rule in branch_coloring.c.
34 *
35 * This branching rule puts some more effort into the choice of the two nodes and performs a
36 * strongbranching. This means that for every possible choice of two nodes, it solves the LPs of the
37 * created children and computes a score with respect to the increase of the lower bound in both
38 * nodes. After that, it takes the combination of nodes yielding the best score. The interesting
39 * point is that the strongbranching is not performed for each variable, as it is done in some
40 * default branching rules of SCIP and supported by the LP-solver, but is done for a constraint,
41 * since we are branching on constraints. Look at executeStrongBranching() to see how it is
42 * done. There are also some improvements, since testing all possible combination of nodes is very
43 * expensive. The first possibility to avoid this is to stop the computation of scores once a
44 * possible branching is found that has only one feasible child. This results in more restrictions
45 * in this child without increasing the number of unprocessed nodes.
46 *
47 * The second improvement is to compute a priority for all possible combinations, w.r.t. the
48 * fractional values of the variables. Then, only the first best k combinations are investigated by
49 * strongbranching.
50 *
51 * This code is not optimized and in most cases inferior to the standard branching rule. It is only
52 * a demonstration of how to perform strongbranching on constraints!
53 */
54
55/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
56#include <assert.h>
57#include <string.h>
58
60#include "pricer_coloring.h"
61
62#define BRANCHRULE_NAME "strongcoloring"
63#define BRANCHRULE_DESC "branching rule template"
64#define BRANCHRULE_PRIORITY 15000
65#define BRANCHRULE_MAXDEPTH -1
66#define BRANCHRULE_MAXBOUNDDIST 1.0
67
68/* default values for parameters */
69#define DEFAULT_BRANCHINGMODE 2
70#define DEFAULT_FIXINGSSCOREMODE 3
71#define DEFAULT_MAXPRICINGROUNDS -1
72#define DEFAULT_USETCLIQUE TRUE
73#define DEFAULT_LOOKAHEAD 10
74
75
76
77/*
78 * Data structures
79 */
80
81/** branching rule data */
82struct SCIP_BranchruleData
83{
84 int branchingmode; /* determines the branchingmode, 0: for fullstrong branching,
85 1: strong branching, take first possible branching with only one child-node
86 2: strong branching with prior sorting of candidates w.r.t. the fractional value of concerned sets */
87 int length; /* length of the arrays samevalue and differvalue, length = n*(n-1)/2 with n = NNodes*/
88 SCIP_Real* samevalue; /* value of variables, that would be fixed to 0 for same(i,j), index = nodes2index(i,j) */
89 SCIP_Real* differvalue; /* value of variables, that would be fixed to 0 for differ(i,j), index = nodes2index(i,j) */
90 SCIP_Real* combinedvalue; /* combination of samevalue and differvalue, computed by computeScore*/
91 int* permutation; /* permutation of the indexes of the array combinedvalue, s.t. it is sorted */
92 SCIP_Bool usetclique; /* should the exact pricing with the tclique-algorithm be used for the strongbranchings? */
93 int maxpricingrounds; /* maximal number of pricing rounds used for each probing node in the strongbranching */
94 int lookahead; /* number of candidates to be considered in branchingmode 2 */
95 int fixingsscoremode; /* determines the weightings of the two factors for prior sorting by fractional LP value */
96
97};
98
99
100
101
102/*
103 * Local methods
104 */
105
106/** computes a score for the two improvements that are achieved in the two sons for a branching decision */
107static
109 SCIP_Real val1, /**< the first value */
110 SCIP_Real val2 /**< the second value */
111 )
112{
113 return 0.2 * MAX( val1, val2 ) + 0.8 * MIN( val1, val2 );
114}
115
116/** computes a score for the fractional values of the variables that would be fixed to zero for a same- or differ-branching */
117static
119 SCIP_Real samevalue, /**< value of the fractional variables fixed to 0 for a same-branching*/
120 SCIP_Real differvalue, /**< value of the fractional variables fixed to 0 for a differ-branching*/
121 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
122 )
123{
124 if ( branchruledata->fixingsscoremode == 1 )
125 {
126 return 3*samevalue+differvalue;
127 }
128 if ( branchruledata->fixingsscoremode == 2 )
129 {
130 return 2*samevalue+differvalue;
131 }
132 if ( branchruledata->fixingsscoremode == 3 )
133 {
134 return samevalue+10*differvalue;
135 }
136 if ( branchruledata->fixingsscoremode == 4 )
137 {
138 if ( samevalue == -1 && differvalue == -1 )
139 return -1;
140 return samevalue*differvalue;
141 }
142 return samevalue*differvalue;
143}
144
145/** for given nodes node1, node2, compute the corresponding index in the arrays branchruledata->same-/differvalue */
146static
148 SCIP* scip, /**< SCIP data structure */
149 int node1, /**< the first node */
150 int node2 /**< the second node */
151 )
152{
153 int ind;
154 int nnodes;
155 int i;
156
157 assert(scip != NULL);
158 assert(node1 >= 0 && node2 >= 0);
159
160 /* node 1 has to be smaller than node 2 */
161 if ( node1 > node2 )
162 {
163 ind = node1;
164 node1 = node2;
165 node2 = ind;
166 }
168 assert(node1 < nnodes && node2 < nnodes);
169 ind = 0;
170 for ( i = 0; i < node1; i++ )
171 ind += (nnodes - i - 1);
172 ind += ( node2-node1-1);
173 return ind;
174}
175
176/** for given index of the arrays branchruledata->same-/differvalue, compute the two nodes, the index represents */
177static
179 SCIP* scip, /**< SCIP data structure */
180 int ind, /**< the given index in the arrays */
181 int* node1, /**< return value: the first node */
182 int* node2 /**< return value: the second node */
183 )
184{
185 int nnodes;
186 int value;
187
188 assert(scip != NULL);
189 assert(node2 != NULL && node1 != NULL);
190
192 *node1 = 0;
193 value = 0;
194 while ( value + nnodes - 1 - *node1 <= ind )
195 {
196 value += (nnodes - 1 - *node1);
197 *node1 = *node1 + 1;
198 }
199 *node2 = *node1 + 1 + (ind - value);
200}
201
202/** computes for each pair of nodes (i,j) two values, one for same (i,j), the other for differ(i,j) which are the sum of
203 the values of variables with fractional parts, that would be fixed for this decision
204 asd */
205static
207 SCIP* scip, /**< SCIP data structure */
208 SCIP_BRANCHRULEDATA* branchruledata /**< the data of the branching rule */
209 )
210{
211 SCIP_VAR** lpcands;
212 SCIP_Real* lpcandsfrac;
213 TCLIQUE_GRAPH* graph;
214 int nlpcands;
215 int i;
216 int j;
217 int k;
218 int node1;
219 int node2;
220 SCIP_VAR* var;
221 int setindex;
222 int* set;
223 int setlength;
224 int nnodes;
225
226 assert(scip != NULL);
227 assert(branchruledata != NULL);
228
229 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, NULL, &lpcandsfrac, &nlpcands, NULL, NULL) );
232
233 assert(graph != NULL);
234 assert(nnodes >= 0);
235
236 /* fill array samevalue, differvalue with zeroes, or -1 for impossible branchings */
237 for ( i = 0; i < branchruledata->length; i++ )
238 {
239 index2nodes(scip, i, &node1, &node2);
240 /* there is an edge between node1 and node2 --> no branching possible --> set value to -1 */
241 if ( tcliqueIsEdge(graph, node1, node2) )
242 {
243 branchruledata->samevalue[i] = -1;
244 branchruledata->differvalue[i] = -1;
245 continue;
246 }
247 branchruledata->samevalue[i] = 0;
248 branchruledata->differvalue[i] = 0;
249 }
250
251 /* for all branching candidates (variables with fractional value) check for which branching decisions they would be
252 fixed to 0 and add the fractional part to the related entry in the array samevalue or differvalue */
253 for ( i = 0; i < nlpcands; i++ )
254 {
255 assert(SCIPisFeasPositive(scip, lpcandsfrac[i]));
256 var = lpcands[i];
257 setindex = (int)(size_t) SCIPvarGetData(var);
258 COLORprobGetStableSet(scip, setindex, &set, &setlength);
259 for ( j = 0; j < setlength; j++ )
260 {
261 node1 = set[j];
262 /* if node1 is part of a union and not its representant, continue */
263 if ( COLORconsGetRepresentative(scip, node1) != node1 )
264 {
265 continue;
266 }
267 k = 0;
268 for ( node2 = nnodes-1; node2 >= 0; node2-- )
269 {
270 /* if k is a node, which is part of, but not representant of a union, increment k */
271 while ( k < setlength && COLORconsGetRepresentative(scip, set[k]) != set[k] )
272 {
273 k++;
274 }
275 /* node1 is equal to node2 -> increment k and continue */
276 if ( node2 == node1 )
277 {
278 assert(k == j);
279 k++;
280 continue;
281 }
282 /* if node2 is part of a union and not its representant, continue */
283 if ( COLORconsGetRepresentative(scip, node2) != node2 )
284 continue;
285 /* if there is an edge between node1 and node2 in the current graph, continue */
286 if ( branchruledata->differvalue[nodes2index(scip, node1, node2)] == -1 )
287 {
288 continue;
289 }
290 /* node2 is also in the set --> the variable would be fixed to 0 for differ(node1, node2) */
291 if ( k < setlength && node2 == set[k] )
292 {
293 branchruledata->differvalue[nodes2index(scip, node1, node2)] += lpcandsfrac[i];
294 assert(COLORprobIsNodeInStableSet(scip, setindex, node1) && COLORprobIsNodeInStableSet(scip, setindex, node2));
295 k++;
296 }
297 /* node2 is not in the set --> the variable would be fixed to 0 for same(node1, node2) */
298 else
299 {
300 branchruledata->samevalue[nodes2index(scip, node1, node2)] += lpcandsfrac[i];
301 assert(COLORprobIsNodeInStableSet(scip, setindex, node1) && !COLORprobIsNodeInStableSet(scip, setindex, node2));
302 }
303 }
304 assert(k == setlength);
305 }
306 }
307
308 return SCIP_OKAY;
309
310}
311
312
313
314/** computes the lower bound that would a child node with the given branching decision would have */
315static
317 SCIP* scip, /**< SCIP data structure */
318 COLOR_CONSTYPE constype, /**< the type of the contraint: SAME or DIFFER */
319 int node1, /**< the first node for the branching constraint */
320 int node2, /**< the second node for the branching constraint */
321 SCIP_BRANCHRULEDATA* branchruledata, /**< the data of the branching rule */
322 SCIP_Real* newlb /**< pointer to store the resulting value */
323 )
324{
325 SCIP_NODE* newnode;
326 SCIP_CONS* currentcons;
327 SCIP_CONS* cons;
328 SCIP_Bool cutoff;
329 SCIP_Bool lperror;
330
331 assert(scip != NULL);
332 assert(newlb != NULL);
333
334 /* get the constraint of the current Node in the B&B-Tree */
336
337 /* start Probing */
339
340 /* create new probing node and add store graph cons to it with same(node1, node2) */
342 newnode = SCIPgetCurrentNode(scip);
343 SCIP_CALL( COLORcreateConsStoreGraph(scip, &cons, "probingcons", currentcons, constype, node1, node2, newnode) );
344 SCIP_CALL( SCIPaddConsNode(scip, newnode, cons, NULL) );
345 /* propagate the new b&b-node, i.e. fix vars to 0 that don't contain both node1 and node2 */
346 SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
347 /* solve the LP using pricing */
348 SCIP_CALL( SCIPsolveProbingLPWithPricing(scip, FALSE, FALSE, branchruledata->maxpricingrounds, &lperror, &cutoff) );
349 assert(!lperror);
350 assert(!cutoff);
351 /* get the changed objective value */
352 *newlb = SCIPgetLPObjval(scip);
353
354 SCIP_CALL( SCIPdelCons(scip, cons) );
355 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
357
358 return SCIP_OKAY;
359}
360
361
362/** index comparison method two values in a real array */
363static
364SCIP_DECL_SORTINDCOMP(consdataCompValues)
365{
366 SCIP_Real* values;
367
368 values = (SCIP_Real*)dataptr;
369
370 assert(values != NULL);
371
372 if ( values[ind1] > values[ind2] )
373 {
374 return -1;
375 }
376 if ( values[ind1] < values[ind2] )
377 {
378 return 1;
379 }
380 return 0;
381}
382
383
384/*
385 * Callback methods of branching rule
386 */
387
388/** copy method for branchrule plugins (called when SCIP copies plugins) */
389static
390SCIP_DECL_BRANCHCOPY(branchCopyStrongcoloring)
391{ /*lint --e{715}*/
392 assert(scip != NULL);
393 assert(branchrule != NULL);
394 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
395
396 return SCIP_OKAY;
397}
398
399
400/** branching execution method for fractional LP solutions */
401static
402SCIP_DECL_BRANCHEXECLP(branchExeclpStrongcoloring)
403{
404 /* the 2 nodes, for which the branching is done by DIFFER and SAME */
405 int node1;
406 int node2;
407 /* the nodes in the branch&bound-tree which are created */
408 SCIP_NODE* childsame;
409 SCIP_NODE* childdiffer;
410 /* the constraints for the created b&b-nodes */
411 SCIP_CONS* conssame;
412 SCIP_CONS* consdiffer;
413 /* the constraint of the processed b&b-node */
414 SCIP_CONS* currentcons;
415
416 int i;
417 int j;
418 int nnodes;
419
420 SCIP_Bool* wasnode1;
421 SCIP_Bool* wasnode2;
422 SCIP_Bool start;
423 TCLIQUE_GRAPH* graph;
424 SCIP_Real currLb;
425 SCIP_Real sameLb;
426 SCIP_Real differLb;
427
428 SCIP_Real bestscore;
429 SCIP_Real bestdiffer;
430 SCIP_Real bestsame;
431 SCIP_Real score;
432 int bestnode2;
433 int bestnode1;
434
435 SCIP_BRANCHRULEDATA* branchruledata;
436
437#ifndef NDEBUG
438 SCIP_NODE* node;
439#endif
440
441 assert(scip != NULL);
442 assert(branchrule != NULL);
443 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
444 assert(result != NULL);
445
446 *result = SCIP_DIDNOTRUN;
447
448 /* get branching rule data */
449 branchruledata = SCIPbranchruleGetData(branchrule);
452
453 if ( branchruledata->branchingmode == 2 )
454 {
455 SCIP_CALL( computeBranchingPriorities(scip, branchruledata) );
456
457 for ( i = 0; i < branchruledata->length; i++ )
458 {
459 branchruledata->combinedvalue[i] = computeFixingsScore(branchruledata->samevalue[i], branchruledata->differvalue[i], branchruledata);
460 }
461 /* get permutation of indexes, so that the array is sorted */
462 /** @todo could be improved by only getting the k best indexes */
463 SCIPsort(branchruledata->permutation, consdataCompValues, branchruledata->combinedvalue, branchruledata->length);
464
465 bestscore = -1;
466 bestnode1 = -1;
467 bestnode2 = -1;
468 bestdiffer = -1;
469 bestsame = -1;
470
471 for ( i = 0; i < branchruledata->lookahead && i < branchruledata->length; i++ )
472 {
473 index2nodes(scip, branchruledata->permutation[i], &node1, &node2);
474 currLb = SCIPgetLPObjval(scip);
475
476 /* SAME */
477 SCIP_CALL( executeStrongBranching(scip, COLOR_CONSTYPE_SAME, node1, node2, branchruledata, &sameLb) );
478 if ( sameLb-currLb > 1000 )
479 {
480 sameLb = currLb + 1000;
481 }
482
483 /* DIFFER */
484 SCIP_CALL( executeStrongBranching(scip, COLOR_CONSTYPE_DIFFER, node1, node2, branchruledata, &differLb) );
485 if ( differLb-currLb > 1000 )
486 {
487 differLb = currLb + 1000;
488 }
489
490 score = computeScore( sameLb - currLb, differLb-currLb );
491 assert( !SCIPisFeasZero(scip, score) || (SCIPisFeasZero(scip, 0.2 * (sameLb-currLb)) && SCIPisFeasZero(scip, 0.2 * (differLb-currLb))
492 && (SCIPisFeasZero(scip, sameLb-currLb) || SCIPisFeasZero(scip, differLb-currLb))) );
493
494 if ( score > bestscore )
495 {
496 bestscore = score;
497 bestnode1 = node1;
498 bestnode2 = node2;
499 bestdiffer = differLb-currLb;
500 bestsame = sameLb-currLb;
501 }
502 if ( bestdiffer > 999 || bestsame > 999 )
503 {
504 break;
505 }
506 }
507
508 }
509 else
510 {
511 assert(branchruledata->branchingmode == 0 || branchruledata->branchingmode == 1);
512 /* create array wasnode1 and wasnode2 and fill them with FALSE */
514 BMSclearMemoryArray(wasnode1, nnodes);
516
517 bestscore = -1;
518 bestnode1 = -1;
519 bestnode2 = -1;
520 bestdiffer = -1;
521 bestsame = -1;
522
523 SCIP_CALL( SCIPsetBoolParam(scip, "pricers/coloring/usetclique", branchruledata->usetclique) );
524#ifndef NDEBUG
525 node = SCIPgetCurrentNode(scip);
526#endif
528
529 start = TRUE;
530 for ( i = SCIPgetDepth(scip)%nnodes; (start || (i != SCIPgetDepth(scip)%nnodes)); i=((i+1)%nnodes) )
531 {
532 start = FALSE;
534 /* check whether node1 was already tested */
535 if ( wasnode1[node1] == TRUE )
536 {
537 continue;
538 }
539 else
540 {
541 wasnode1[node1] = TRUE;
542 }
543 BMSclearMemoryArray(wasnode2, nnodes);
544
545 for ( j = i+1; j < nnodes; j++ )
546 {
548 if ( node2 == node1 || tcliqueIsEdge(graph, node1, node2) || node2 < i )
549 {
550 continue;
551 }
552 else
553 {
554 /* check whether node2 was already tested */
555 if ( wasnode2[node2] == TRUE ) continue;
556 else wasnode2[node2] = TRUE;
557
558 currLb = SCIPgetLPObjval(scip);
559
560 assert(currentcons == COLORconsGetActiveStoreGraphCons(scip));
561 assert(node == SCIPgetCurrentNode(scip));
562
563 /* compute lower bounds for possible branchings */
564
565 /* SAME */
566 SCIP_CALL( executeStrongBranching(scip, COLOR_CONSTYPE_SAME, node1, node2, branchruledata, &sameLb) );
567 if ( sameLb-currLb > 1000 )
568 {
569 sameLb = currLb + 1000;
570 }
571
572 /* DIFFER */
573 SCIP_CALL( executeStrongBranching(scip, COLOR_CONSTYPE_DIFFER, node1, node2, branchruledata, &differLb) );
574 if ( differLb-currLb > 1000 )
575 {
576 differLb = currLb + 1000;
577 }
578
579 score = computeScore( sameLb-currLb, differLb-currLb );
580 if ( score > bestscore )
581 {
582 bestscore = score;
583 bestnode1 = node1;
584 bestnode2 = node2;
585 bestdiffer = differLb-currLb;
586 bestsame = sameLb-currLb;
587 }
588 if ( (branchruledata->branchingmode == 1) && (bestdiffer > 999 || bestsame > 999) )
589 {
590 break;
591 }
592
593 }
594 }
595 if ( (branchruledata->branchingmode == 1) && (bestdiffer > 999 || bestsame > 999) )
596 {
597 break;
598 }
599 }
600
601 SCIP_CALL( SCIPsetBoolParam(scip, "pricers/coloring/usetclique", TRUE) );
602 assert(node == SCIPgetCurrentNode(scip));
603 assert(currentcons == COLORconsGetActiveStoreGraphCons(scip));
604
605 SCIPfreeBufferArray(scip, &wasnode2);
606 SCIPfreeBufferArray(scip, &wasnode1);
607
608 }
609
610 assert(!SCIPisSumNegative(scip, bestscore));
611
612 node1 = bestnode1;
613 node2 = bestnode2;
614
615 /* branchingmode >= 1 --> only create nodes, that do not have a LP solution that is much bigger than the lower bound */
616 if ( branchruledata->branchingmode >= 1 && branchruledata->usetclique == TRUE )
617 {
618 *result = SCIP_CUTOFF;
620
621 if ( bestdiffer <= 999 )
622 {
623 /* create the b&b-tree child-nodes of the current node */
625
626 /* create corresponding constraints */
627 SCIP_CALL( COLORcreateConsStoreGraph(scip, &consdiffer, "differ", currentcons, COLOR_CONSTYPE_DIFFER, node1, node2, childdiffer) );
628
629 /* add constraints to nodes */
630 SCIP_CALL( SCIPaddConsNode(scip, childdiffer, consdiffer, NULL) );
631
632 /* release constraints */
633 SCIP_CALL( SCIPreleaseCons(scip, &consdiffer) );
634
635 *result = SCIP_BRANCHED;
636 }
637
638 if ( bestsame <= 999 )
639 {
640 /* create the b&b-tree child-nodes of the current node */
642
643 /* create corresponding constraints */
644 SCIP_CALL( COLORcreateConsStoreGraph(scip, &conssame, "same", currentcons, COLOR_CONSTYPE_SAME, node1, node2, childsame) );
645
646 /* add constraints to nodes */
647 SCIP_CALL( SCIPaddConsNode(scip, childsame, conssame, NULL) );
648
649 /* release constraints */
650 SCIP_CALL( SCIPreleaseCons(scip, &conssame) );
651
652 *result = SCIP_BRANCHED;
653 }
654 }
655 /* create both children */
656 else
657 {
660
661 /* create the b&b-tree child-nodes of the current node */
664
665 /* create corresponding constraints */
667 SCIP_CALL( COLORcreateConsStoreGraph(scip, &conssame, "same", currentcons, COLOR_CONSTYPE_SAME, node1, node2, childsame) );
668 SCIP_CALL( COLORcreateConsStoreGraph(scip, &consdiffer, "differ", currentcons, COLOR_CONSTYPE_DIFFER, node1, node2, childdiffer) );
669
670 /* add constraints to nodes */
671 SCIP_CALL( SCIPaddConsNode(scip, childsame, conssame, NULL) );
672 SCIP_CALL( SCIPaddConsNode(scip, childdiffer, consdiffer, NULL) );
673
674 /* release constraints */
675 SCIP_CALL( SCIPreleaseCons(scip, &conssame) );
676 SCIP_CALL( SCIPreleaseCons(scip, &consdiffer) );
677
678 *result = SCIP_BRANCHED;
679 }
680
681 return SCIP_OKAY;
682}/*lint !e715*/
683
684
685/** destructor of branching rule to free user data (called when SCIP is exiting) */
686static
687SCIP_DECL_BRANCHFREE(branchFreeStrongcoloring)
688{
689 SCIP_BRANCHRULEDATA* branchruledata;
690
691 /* free branching rule data */
692 branchruledata = SCIPbranchruleGetData(branchrule);
693 SCIPfreeBlockMemory(scip, &branchruledata);
694 SCIPbranchruleSetData(branchrule, NULL);
695
696 return SCIP_OKAY;
697}
698
699/** initialization method of branching rule (called after problem was transformed) */
700static
701SCIP_DECL_BRANCHINIT(branchInitStrongcoloring)
702{
703 SCIP_BRANCHRULEDATA* branchruledata;
704
705 /* get branching rule data */
706 branchruledata = SCIPbranchruleGetData(branchrule);
707 assert(branchruledata != NULL);
708
709 /* get memory for the arrays */
710 branchruledata->length = (COLORprobGetNNodes(scip)*(COLORprobGetNNodes(scip)-1))/2;
711 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(branchruledata->samevalue), branchruledata->length) );
712 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(branchruledata->differvalue), branchruledata->length) );
713 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(branchruledata->combinedvalue), branchruledata->length) );
714 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(branchruledata->permutation), branchruledata->length) );
715
716 return SCIP_OKAY;
717}
718
719/** deinitialization method of branching rule (called before transformed problem is freed) */
720static
721SCIP_DECL_BRANCHEXIT(branchExitStrongcoloring)
722{
723 SCIP_BRANCHRULEDATA* branchruledata;
724
725 /* get branching rule data */
726 branchruledata = SCIPbranchruleGetData(branchrule);
727 assert(branchruledata != NULL);
728
729 /* free arrays */
730 SCIPfreeBlockMemoryArray(scip, &(branchruledata->samevalue), branchruledata->length);
731 SCIPfreeBlockMemoryArray(scip, &(branchruledata->differvalue), branchruledata->length);
732 SCIPfreeBlockMemoryArray(scip, &(branchruledata->combinedvalue), branchruledata->length);
733 SCIPfreeBlockMemoryArray(scip, &(branchruledata->permutation), branchruledata->length);
734
735 return SCIP_OKAY;
736}
737
738/*
739 * branching rule specific interface methods
740 */
741
742/** creates the coloring branching rule and includes it in SCIP */
744 SCIP* scip /**< SCIP data structure */
745 )
746{
747 SCIP_BRANCHRULEDATA* branchruledata;
748 SCIP_BRANCHRULE* branchrule;
749
750 assert(scip != NULL);
751
752 /* create branching rule data */
753 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
754
755 branchrule = NULL;
756 /* include branching rule */
758 BRANCHRULE_MAXBOUNDDIST, branchruledata) );
759 assert(branchrule != NULL);
760
761 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyStrongcoloring) );
762 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeStrongcoloring) );
763 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpStrongcoloring) );
764 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitStrongcoloring) );
765 SCIP_CALL( SCIPsetBranchruleExit(scip, branchrule, branchExitStrongcoloring) );
766
767
769 "branching/strongcoloring/lookahead",
770 "number of candidates to be considered in branchingmode 2",
771 &branchruledata->lookahead, TRUE, DEFAULT_LOOKAHEAD, 0, INT_MAX, NULL, NULL) );
772
774 "branching/strongcoloring/usetclique",
775 "should the exact pricing with the tclique-algorithm be used for the strongbranchings?",
776 &branchruledata->usetclique, FALSE, DEFAULT_USETCLIQUE, NULL, NULL) );
777
779 "branching/strongcoloring/maxpricingrounds",
780 "maximal number of pricing rounds used for each probing node in the strongbranching",
781 &branchruledata->maxpricingrounds, TRUE, DEFAULT_MAXPRICINGROUNDS, -1, INT_MAX, NULL, NULL) );
782
784 "branching/strongcoloring/branchingmode",
785 "determines the branchingmode, 0: fullstrong branching, 1: strong branching, take first possible branching with only one child-node, 2: strong branching with prior sorting of candidates w.r.t. the fractional value of concerned sets */",
786 &branchruledata->branchingmode, FALSE, DEFAULT_BRANCHINGMODE, 0, 2, NULL, NULL) );
787
789 "branching/strongcoloring/fixingsscoremode",
790 "determines the weightings of the two factors for prior sorting by fractional LP value",
791 &branchruledata->fixingsscoremode, TRUE, DEFAULT_FIXINGSSCOREMODE, 0, 4, NULL, NULL) );
792
793 return SCIP_OKAY;
794}
#define BRANCHRULE_DESC
static SCIP_DECL_SORTINDCOMP(consdataCompValues)
#define BRANCHRULE_PRIORITY
static double computeScore(SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE executeStrongBranching(SCIP *scip, COLOR_CONSTYPE constype, int node1, int node2, SCIP_BRANCHRULEDATA *branchruledata, SCIP_Real *newlb)
SCIP_RETCODE SCIPincludeBranchruleStrongcoloring(SCIP *scip)
static SCIP_DECL_BRANCHEXIT(branchExitStrongcoloring)
static int nodes2index(SCIP *scip, int node1, int node2)
static SCIP_DECL_BRANCHCOPY(branchCopyStrongcoloring)
#define BRANCHRULE_NAME
static void index2nodes(SCIP *scip, int ind, int *node1, int *node2)
#define DEFAULT_MAXPRICINGROUNDS
#define DEFAULT_USETCLIQUE
static SCIP_DECL_BRANCHINIT(branchInitStrongcoloring)
static SCIP_DECL_BRANCHFREE(branchFreeStrongcoloring)
#define DEFAULT_BRANCHINGMODE
#define DEFAULT_LOOKAHEAD
static SCIP_DECL_BRANCHEXECLP(branchExeclpStrongcoloring)
static SCIP_Real computeFixingsScore(SCIP_Real samevalue, SCIP_Real differvalue, SCIP_BRANCHRULEDATA *branchruledata)
#define BRANCHRULE_MAXDEPTH
static SCIP_RETCODE computeBranchingPriorities(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata)
#define DEFAULT_FIXINGSSCOREMODE
#define BRANCHRULE_MAXBOUNDDIST
branching rule performing strong branching for the vertex coloring problem
TCLIQUE_GRAPH * COLORconsGetCurrentGraph(SCIP *scip)
SCIP_RETCODE COLORcreateConsStoreGraph(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONS *fatherconstraint, COLOR_CONSTYPE type, int node1, int node2, SCIP_NODE *stickingnode)
int COLORconsGetRepresentative(SCIP *scip, int node)
SCIP_CONS * COLORconsGetActiveStoreGraphCons(SCIP *scip)
@ COLOR_CONSTYPE_DIFFER
@ COLOR_CONSTYPE_SAME
enum COLOR_ConsType COLOR_CONSTYPE
#define NULL
Definition: def.h:266
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:242
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:238
#define SCIP_CALL(x)
Definition: def.h:373
#define nnodes
Definition: gastrans.c:74
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2843
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip_prob.c:3324
SCIP_Real SCIPgetLocalTransEstimate(SCIP *scip)
Definition: scip_prob.c:3547
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:83
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 SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:429
SCIP_RETCODE SCIPsetBranchruleExit(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXIT((*branchexit)))
Definition: scip_branch.c:201
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
Definition: scip_branch.c:249
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
Definition: scip_branch.c:153
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
Definition: scip_branch.c:116
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition: branch.c:1971
SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition: branch.c:1849
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
Definition: scip_branch.c:169
SCIP_RETCODE SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINIT((*branchinit)))
Definition: scip_branch.c:185
void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
Definition: branch.c:1859
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip_branch.c:395
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
Definition: scip_branch.c:1017
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8311
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:247
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:580
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:119
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:165
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:260
SCIP_RETCODE SCIPsolveProbingLPWithPricing(SCIP *scip, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:844
SCIP_Bool SCIPisSumNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:672
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_VARDATA * SCIPvarGetData(SCIP_VAR *var)
Definition: var.c:17438
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:5541
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
variable pricer for the vertex coloring problem
void COLORprobGetStableSet(SCIP *scip, int setindex, int **stableset, int *nelements)
int COLORprobGetNNodes(SCIP *scip)
SCIP_CONS * COLORprobGetConstraint(SCIP *scip, int node)
SCIP_Bool COLORprobIsNodeInStableSet(SCIP *scip, int setindex, int node)
Definition: heur_padm.c:135
struct TCLIQUE_Graph TCLIQUE_GRAPH
Definition: tclique.h:49
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition: type_branch.h:57
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_CUTOFF
Definition: type_result.h:48
@ SCIP_BRANCHED
Definition: type_result.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63