SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-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 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
58#include "pricer_coloring.h"
59
60#define BRANCHRULE_NAME "strongcoloring"
61#define BRANCHRULE_DESC "branching rule template"
62#define BRANCHRULE_PRIORITY 15000
63#define BRANCHRULE_MAXDEPTH -1
64#define BRANCHRULE_MAXBOUNDDIST 1.0
65
66/* default values for parameters */
67#define DEFAULT_BRANCHINGMODE 2
68#define DEFAULT_FIXINGSSCOREMODE 3
69#define DEFAULT_MAXPRICINGROUNDS -1
70#define DEFAULT_USETCLIQUE TRUE
71#define DEFAULT_LOOKAHEAD 10
72
73
74
75/*
76 * Data structures
77 */
78
79/** branching rule data */
80struct SCIP_BranchruleData
81{
82 int branchingmode; /* determines the branchingmode, 0: for fullstrong branching,
83 1: strong branching, take first possible branching with only one child-node
84 2: strong branching with prior sorting of candidates w.r.t. the fractional value of concerned sets */
85 int length; /* length of the arrays samevalue and differvalue, length = n*(n-1)/2 with n = NNodes*/
86 SCIP_Real* samevalue; /* value of variables, that would be fixed to 0 for same(i,j), index = nodes2index(i,j) */
87 SCIP_Real* differvalue; /* value of variables, that would be fixed to 0 for differ(i,j), index = nodes2index(i,j) */
88 SCIP_Real* combinedvalue; /* combination of samevalue and differvalue, computed by computeScore*/
89 int* permutation; /* permutation of the indexes of the array combinedvalue, s.t. it is sorted */
90 SCIP_Bool usetclique; /* should the exact pricing with the tclique-algorithm be used for the strongbranchings? */
91 int maxpricingrounds; /* maximal number of pricing rounds used for each probing node in the strongbranching */
92 int lookahead; /* number of candidates to be considered in branchingmode 2 */
93 int fixingsscoremode; /* determines the weightings of the two factors for prior sorting by fractional LP value */
94
95};
96
97
98
99
100/*
101 * Local methods
102 */
103
104/** computes a score for the two improvements that are achieved in the two sons for a branching decision */
105static
107 SCIP_Real val1, /**< the first value */
108 SCIP_Real val2 /**< the second value */
109 )
110{
111 return 0.2 * MAX( val1, val2 ) + 0.8 * MIN( val1, val2 );
112}
113
114/** computes a score for the fractional values of the variables that would be fixed to zero for a same- or differ-branching */
115static
117 SCIP_Real samevalue, /**< value of the fractional variables fixed to 0 for a same-branching*/
118 SCIP_Real differvalue, /**< value of the fractional variables fixed to 0 for a differ-branching*/
119 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
120 )
121{
122 if ( branchruledata->fixingsscoremode == 1 )
123 {
124 return 3*samevalue+differvalue;
125 }
126 if ( branchruledata->fixingsscoremode == 2 )
127 {
128 return 2*samevalue+differvalue;
129 }
130 if ( branchruledata->fixingsscoremode == 3 )
131 {
132 return samevalue+10*differvalue;
133 }
134 if ( branchruledata->fixingsscoremode == 4 )
135 {
136 if ( samevalue == -1 && differvalue == -1 )
137 return -1;
138 return samevalue*differvalue;
139 }
140 return samevalue*differvalue;
141}
142
143/** for given nodes node1, node2, compute the corresponding index in the arrays branchruledata->same-/differvalue */
144static
146 SCIP* scip, /**< SCIP data structure */
147 int node1, /**< the first node */
148 int node2 /**< the second node */
149 )
150{
151 int ind;
152 int nnodes;
153 int i;
154
155 assert(scip != NULL);
156 assert(node1 >= 0 && node2 >= 0);
157
158 /* node 1 has to be smaller than node 2 */
159 if ( node1 > node2 )
160 {
161 ind = node1;
162 node1 = node2;
163 node2 = ind;
164 }
166 assert(node1 < nnodes && node2 < nnodes);
167 ind = 0;
168 for ( i = 0; i < node1; i++ )
169 ind += (nnodes - i - 1);
170 ind += ( node2-node1-1);
171 return ind;
172}
173
174/** for given index of the arrays branchruledata->same-/differvalue, compute the two nodes, the index represents */
175static
177 SCIP* scip, /**< SCIP data structure */
178 int ind, /**< the given index in the arrays */
179 int* node1, /**< return value: the first node */
180 int* node2 /**< return value: the second node */
181 )
182{
183 int nnodes;
184 int value;
185
186 assert(scip != NULL);
187 assert(node2 != NULL && node1 != NULL);
188
190 *node1 = 0;
191 value = 0;
192 while ( value + nnodes - 1 - *node1 <= ind )
193 {
194 value += (nnodes - 1 - *node1);
195 *node1 = *node1 + 1;
196 }
197 *node2 = *node1 + 1 + (ind - value);
198}
199
200/** 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
201 the values of variables with fractional parts, that would be fixed for this decision
202 asd */
203static
205 SCIP* scip, /**< SCIP data structure */
206 SCIP_BRANCHRULEDATA* branchruledata /**< the data of the branching rule */
207 )
208{
211 TCLIQUE_GRAPH* graph;
212 int nlpcands;
213 int i;
214 int j;
215 int k;
216 int node1;
217 int node2;
218 SCIP_VAR* var;
219 int setindex;
220 int* set;
221 int setlength;
222 int nnodes;
223
224 assert(scip != NULL);
225 assert(branchruledata != NULL);
226
230
231 assert(graph != NULL);
232 assert(nnodes >= 0);
233
234 /* fill array samevalue, differvalue with zeroes, or -1 for impossible branchings */
235 for ( i = 0; i < branchruledata->length; i++ )
236 {
237 index2nodes(scip, i, &node1, &node2);
238 /* there is an edge between node1 and node2 --> no branching possible --> set value to -1 */
239 if ( tcliqueIsEdge(graph, node1, node2) )
240 {
241 branchruledata->samevalue[i] = -1;
242 branchruledata->differvalue[i] = -1;
243 continue;
244 }
245 branchruledata->samevalue[i] = 0;
246 branchruledata->differvalue[i] = 0;
247 }
248
249 /* for all branching candidates (variables with fractional value) check for which branching decisions they would be
250 fixed to 0 and add the fractional part to the related entry in the array samevalue or differvalue */
251 for ( i = 0; i < nlpcands; i++ )
252 {
254 var = lpcands[i];
255 setindex = (int)(size_t) SCIPvarGetData(var);
256 COLORprobGetStableSet(scip, setindex, &set, &setlength);
257 for ( j = 0; j < setlength; j++ )
258 {
259 node1 = set[j];
260 /* if node1 is part of a union and not its representant, continue */
261 if ( COLORconsGetRepresentative(scip, node1) != node1 )
262 {
263 continue;
264 }
265 k = 0;
266 for ( node2 = nnodes-1; node2 >= 0; node2-- )
267 {
268 /* if k is a node, which is part of, but not representant of a union, increment k */
269 while ( k < setlength && COLORconsGetRepresentative(scip, set[k]) != set[k] )
270 {
271 k++;
272 }
273 /* node1 is equal to node2 -> increment k and continue */
274 if ( node2 == node1 )
275 {
276 assert(k == j);
277 k++;
278 continue;
279 }
280 /* if node2 is part of a union and not its representant, continue */
281 if ( COLORconsGetRepresentative(scip, node2) != node2 )
282 continue;
283 /* if there is an edge between node1 and node2 in the current graph, continue */
284 if ( branchruledata->differvalue[nodes2index(scip, node1, node2)] == -1 )
285 {
286 continue;
287 }
288 /* node2 is also in the set --> the variable would be fixed to 0 for differ(node1, node2) */
289 if ( k < setlength && node2 == set[k] )
290 {
291 branchruledata->differvalue[nodes2index(scip, node1, node2)] += lpcandsfrac[i];
292 assert(COLORprobIsNodeInStableSet(scip, setindex, node1) && COLORprobIsNodeInStableSet(scip, setindex, node2));
293 k++;
294 }
295 /* node2 is not in the set --> the variable would be fixed to 0 for same(node1, node2) */
296 else
297 {
298 branchruledata->samevalue[nodes2index(scip, node1, node2)] += lpcandsfrac[i];
299 assert(COLORprobIsNodeInStableSet(scip, setindex, node1) && !COLORprobIsNodeInStableSet(scip, setindex, node2));
300 }
301 }
302 assert(k == setlength);
303 }
304 }
305
306 return SCIP_OKAY;
307
308}
309
310
311
312/** computes the lower bound that would a child node with the given branching decision would have */
313static
315 SCIP* scip, /**< SCIP data structure */
316 COLOR_CONSTYPE constype, /**< the type of the contraint: SAME or DIFFER */
317 int node1, /**< the first node for the branching constraint */
318 int node2, /**< the second node for the branching constraint */
319 SCIP_BRANCHRULEDATA* branchruledata, /**< the data of the branching rule */
320 SCIP_Real* newlb /**< pointer to store the resulting value */
321 )
322{
323 SCIP_NODE* newnode;
324 SCIP_CONS* currentcons;
325 SCIP_CONS* cons;
328
329 assert(scip != NULL);
330 assert(newlb != NULL);
331
332 /* get the constraint of the current Node in the B&B-Tree */
334
335 /* start Probing */
337
338 /* create new probing node and add store graph cons to it with same(node1, node2) */
340 newnode = SCIPgetCurrentNode(scip);
341 SCIP_CALL( COLORcreateConsStoreGraph(scip, &cons, "probingcons", currentcons, constype, node1, node2, newnode) );
342 SCIP_CALL( SCIPaddConsNode(scip, newnode, cons, NULL) );
343 /* propagate the new b&b-node, i.e. fix vars to 0 that don't contain both node1 and node2 */
345 /* solve the LP using pricing */
346 SCIP_CALL( SCIPsolveProbingLPWithPricing(scip, FALSE, FALSE, branchruledata->maxpricingrounds, &lperror, &cutoff) );
347 assert(!lperror);
348 assert(!cutoff);
349 /* get the changed objective value */
350 *newlb = SCIPgetLPObjval(scip);
351
352 SCIP_CALL( SCIPdelCons(scip, cons) );
353 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
355
356 return SCIP_OKAY;
357}
358
359
360/** index comparison method two values in a real array */
361static
362SCIP_DECL_SORTINDCOMP(consdataCompValues)
363{
364 SCIP_Real* values;
365
366 values = (SCIP_Real*)dataptr;
367
368 assert(values != NULL);
369
370 if ( values[ind1] > values[ind2] )
371 {
372 return -1;
373 }
374 if ( values[ind1] < values[ind2] )
375 {
376 return 1;
377 }
378 return 0;
379}
380
381
382/*
383 * Callback methods of branching rule
384 */
385
386/** copy method for branchrule plugins (called when SCIP copies plugins) */
387static
388SCIP_DECL_BRANCHCOPY(branchCopyStrongcoloring)
389{ /*lint --e{715}*/
390 assert(scip != NULL);
391 assert(branchrule != NULL);
392
394
395 return SCIP_OKAY;
396}
397
398
399/** branching execution method for fractional LP solutions */
400static
401SCIP_DECL_BRANCHEXECLP(branchExeclpStrongcoloring)
402{
403 /* the 2 nodes, for which the branching is done by DIFFER and SAME */
404 int node1;
405 int node2;
406 /* the nodes in the branch&bound-tree which are created */
407 SCIP_NODE* childsame;
408 SCIP_NODE* childdiffer;
409 /* the constraints for the created b&b-nodes */
410 SCIP_CONS* conssame;
411 SCIP_CONS* consdiffer;
412 /* the constraint of the processed b&b-node */
413 SCIP_CONS* currentcons;
414
415 int i;
416 int j;
417 int nnodes;
418
419 SCIP_Bool* wasnode1;
420 SCIP_Bool* wasnode2;
421 SCIP_Bool start;
422 TCLIQUE_GRAPH* graph;
423 SCIP_Real currLb;
424 SCIP_Real sameLb;
425 SCIP_Real differLb;
426
427 SCIP_Real bestscore;
428 SCIP_Real bestdiffer;
429 SCIP_Real bestsame;
430 SCIP_Real score;
431 int bestnode2;
432 int bestnode1;
433
434 SCIP_BRANCHRULEDATA* branchruledata;
435
436#ifndef NDEBUG
437 SCIP_NODE* node;
438#endif
439
440 assert(scip != NULL);
441 assert(branchrule != NULL);
442 assert(result != NULL);
443
445
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) ) /*lint !e2840*/
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
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) );
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 {
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
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
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
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
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
#define BRANCHRULE_MAXBOUNDDIST
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 int nodes2index(SCIP *scip, int node1, int node2)
static void index2nodes(SCIP *scip, int ind, int *node1, int *node2)
#define DEFAULT_MAXPRICINGROUNDS
#define DEFAULT_USETCLIQUE
#define DEFAULT_BRANCHINGMODE
#define DEFAULT_LOOKAHEAD
static SCIP_Real computeFixingsScore(SCIP_Real samevalue, SCIP_Real differvalue, SCIP_BRANCHRULEDATA *branchruledata)
static SCIP_RETCODE computeBranchingPriorities(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata)
#define DEFAULT_FIXINGSSCOREMODE
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:257
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#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 MAX(x, y)
Definition def.h:229
#define SCIP_CALL(x)
Definition def.h:364
#define nnodes
Definition gastrans.c:74
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3420
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition scip_prob.c:3901
SCIP_Real SCIPgetLocalTransEstimate(SCIP *scip)
Definition scip_prob.c:4139
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 SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExit(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition branch.c:2018
SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition branch.c:1886
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
Definition branch.c:1896
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition cons.c:8490
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:253
#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)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPsolveProbingLPWithPricing(SCIP *scip, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
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:23319
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition misc.c:5581
return SCIP_OKAY
SCIP_Bool lperror
SCIPendProbing(scip))
SCIP_Bool cutoff
int nlpcands
SCIP_VAR ** lpcands
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR * var
SCIP_Real * lpcandsfrac
#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)
struct TCLIQUE_Graph TCLIQUE_GRAPH
Definition tclique.h:49
#define SCIP_DECL_BRANCHEXECLP(x)
#define SCIP_DECL_BRANCHINIT(x)
Definition type_branch.h:83
#define SCIP_DECL_BRANCHCOPY(x)
Definition type_branch.h:67
#define SCIP_DECL_BRANCHEXIT(x)
Definition type_branch.h:91
#define SCIP_DECL_BRANCHFREE(x)
Definition type_branch.h:75
struct SCIP_Branchrule SCIP_BRANCHRULE
Definition type_branch.h:56
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition type_branch.h:57
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_SORTINDCOMP(x)
Definition type_misc.h:181
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_BRANCHED
Definition type_result.h:54
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Node SCIP_NODE
Definition type_tree.h:63
struct SCIP_Var SCIP_VAR
Definition type_var.h:166