Skip to content

Commit 355fc9e

Browse files
committed
move callback to calculate extended master cons coefficients to the gcg branch rule struct
1 parent 6a85dd8 commit 355fc9e

25 files changed

+462
-144
lines changed

CHANGELOG

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ New/modified/removed API functions:
7474
- added function 'GCGpricingmodificationCreate'
7575
- added function 'GCGextendedmasterconsCreateFromCons'
7676
- added function 'GCGextendedmasterconsCreateFromRow'
77+
- added function 'GCGbranchCreateExtendedmastercons'
7778
- added function 'GCGextendedmasterconsFree'
7879
- added function 'GCGrelaxBranchNewCol'
7980
- added function 'GCGrelaxBranchGetExtendedMasterCons'
@@ -82,6 +83,7 @@ New/modified/removed API functions:
8283
- added callback 'GCG_DECL_BRANCHGETEXTENDEDMASTERCONS' to 'GCG_BRANCHRULE'
8384
- added parameter 'GCG_DECL_BRANCHNEWCOL ((*branchnewcol));' to 'GCGrelaxIncludeBranchrule'
8485
- added parameter 'GCG_DECL_BRANCHGETEXTENDEDMASTERCONS((*branchgetextendedmastercons))' to 'GCGrelaxIncludeBranchrule'
86+
- added parameter 'GCG_DECL_BRANCHGETEXTENDEDMASTERCONSCOEFF((*branchgetextendedmasterconscoeff))' to 'GCGrelaxIncludeBranchrule'
8587
- moved function 'SCIPincludeSepaMaster' to 'SCIPincludeSepaOriginal'
8688
- moved function 'GCGsepaGetOrigcuts' to 'GCGsepaGetOriginalSepaOrigcuts'
8789
- moved function 'GCGsepaGetNCuts' to 'GCGsepaGetNOriginalSepaCuts'

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ LIBOBJ = \
257257
gcg/branch_empty.o \
258258
gcg/branch_generic.o \
259259
gcg/benders_gcg.o \
260+
gcg/branchgcg.o \
260261
gcg/branch_orig.o \
261262
gcg/branch_relpsprob.o \
262263
gcg/branch_ryanfoster.o \

doc/resources/devs/howtoadd/own-branching-rule.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,7 @@ The BRANCHDATADELETE callback is called when a branch-and-bound node is freed an
220220
The BRANCHNEWCOL callback is called whenever a new column is added to the master problem. It can be used to update any branching constraints that were added to the master problem, e.g. to determine and add the coefficient of the new master variable to the corresponding branching constraint.
221221

222222
### BRANCHGETEXTENDEDMASTERCONS
223-
If the branching rule branches in the master problem, generating a constraint that can be enforced only if the pricing problem is modified, then the BRANCHGETEXTENDEDMASTERCONS callback will be used by GCG to retrieve the master branching constraint as well as the corresponding modifications to be applied in the pricing problems.
223+
If the branching rule branches in the master problem, generating a constraint that can be enforced only if the pricing problem is modified, then the BRANCHGETEXTENDEDMASTERCONS callback will be used by GCG to retrieve the master branching constraint as well as the corresponding modifications to be applied in the pricing problems.
224+
225+
### GCG_DECL_BRANCHGETEXTENDEDMASTERCONSCOEFF
226+
If the branching rule branches in the master problem, generating an extended master constraint, the callback will be used to determine the coefficient of a column solution in the extended master constraint.

doc/resources/devs/howtouse/masterextendedconss.md

+42-7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ We advise using the following interfaces:
4646
- create modifications with `GCGpricingmodificationCreate()`
4747
- create an extended master constraint around a `SCIP_CONS` with `GCGextendedmasterconsCreateFromCons()`
4848
- create an extended master constraint around a `SCIP_ROW` with `GCGextendedmasterconsCreateFromRow()`
49+
- to create an extended master constraint for branching use `GCGbranchCreateExtendedmastercons` that uses `GCGextendedmasterconsCreateFromCons()`
4950

5051

5152
## Usage
@@ -63,7 +64,7 @@ SCIP_VAR* coefvar = NULL;
6364
char coefvarName[SCIP_MAXSTRLEN];
6465
(void) SCIPsnprintf(coefvarName, SCIP_MAXSTRLEN, "y");
6566
// here, we create a binary variable
66-
SCIP_CALL( GCGcreateInferredPricingVar(pricingscip, coefvar, coefvarName, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY, blocknr) );
67+
SCIP_CALL( GCGcreateInferredPricingVar(pricingscip, coefvar, coefvarName, 0.0, 1.0, TRUE, 0.0, SCIP_VARTYPE_BINARY, blocknr) );
6768

6869
/* create additional constraints (and inferred pricing variables) */
6970
SCIP_CONS** additionalcons = NULL;
@@ -96,14 +97,14 @@ SCIP_CALL( GCGpricingmodificationCreate(
9697

9798
/* create the extended master constraint */
9899
GCG_EXTENDEDMASTERCONSDATA* extendedmasterconsdata = NULL;
99-
SCIP_CALL( GCGextendedmasterconsCreateFromCons(
100-
masterscip,
100+
SCIP_CALL( GCGbranchCreateExtendedmastercons(
101+
gcg,
102+
gcgbranchrule,
101103
extendedmasterconsdata,
102104
mastercons,
103105
pricingmods,
104106
npricingmods,
105-
branchdata,
106-
extendedmasterconsGetCoeffCompBnd
107+
branchdata
107108
) );
108109
```
109110

@@ -112,8 +113,42 @@ SCIP_CALL( GCGextendedmasterconsCreateFromCons(
112113
static
113114
GCG_DECL_BRANCHGETEXTENDEDMASTERCONS(branchGetExtendedmasterconsCompBnd)
114115
{
115-
// grab the extended master cons, e.g. from the branchdata
116-
*extendedmasterconsdata = branchdata->extendedmasterconsdata;
116+
assert(gcg != NULL);
117+
118+
assert(branchdata != NULL);
119+
assert(branchdata->mastercons != NULL);
120+
121+
*extendedmasterconsdata = branchdata->mastercons;
122+
123+
return SCIP_OKAY;
124+
}
125+
```
126+
127+
Furthermore, we implement a callback that calculates the coefficient of a column solution in the extended master constraint:
128+
```C
129+
static
130+
GCG_DECL_BRANCHGETEXTENDEDMASTERCONSCOEFF(branchGetExtendedmasterconsCoeffCompBnd)
131+
{
132+
SCIP* masterprob;
133+
134+
masterprob = GCGgetMasterprob(gcg);
135+
136+
assert(masterprob != NULL);
137+
assert(GCGisMaster(masterprob));
138+
139+
assert(branchdata != NULL);
140+
assert(branchdata->mastercons == extendedmasterconsdata);
141+
142+
*coef = 0.0;
143+
144+
if( probnr == -1 || probnr != branchdata->blocknr )
145+
return SCIP_OKAY;
146+
147+
if( !isColInCompBndSeq(masterprob, solvars, solvals, nsolvars, branchdata->compBndSeq, branchdata->compBndSeqSize) )
148+
return SCIP_OKAY;
149+
150+
*coef = 1.0;
151+
117152
return SCIP_OKAY;
118153
}
119154
```

src/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ set(CMAKE_C_STANDARD_REQUIRED on)
1515
set(gcgsources
1616
gcg/benders_gcg.c
1717
gcg/bendersplugins.c
18+
gcg/branchgcg.c
1819
gcg/branch_bpstrong.c
1920
gcg/branch_compbnd.c
2021
gcg/branch_empty.c
@@ -166,6 +167,7 @@ set(gcggraphsources
166167
)
167168

168169
set(gcgheaders
170+
gcg/branchgcg.h
169171
gcg/branch_empty.h
170172
gcg/branch_bpstrong.h
171173
gcg/branch_compbnd.h
@@ -268,6 +270,7 @@ set(gcgheaders
268270
gcg/pub_pricingcb.h
269271
gcg/pricingjob.h
270272
gcg/pricingprob.h
273+
gcg/pub_branchgcg.h
271274
gcg/pub_clscons.h
272275
gcg/pub_clsvar.h
273276
gcg/pub_colpool.h

src/gcg/branch_bpstrong.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1548,9 +1548,9 @@ SCIP_DECL_BRANCHINIT(branchInitBPStrong)
15481548

15491549
SCIPdebugMessage("Init BPStrong branching rule\n");
15501550

1551-
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, branchActiveMasterBPStrong,
1551+
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, NULL, branchActiveMasterBPStrong,
15521552
branchDeactiveMasterBPStrong, branchPropMasterBPStrong, branchMasterSolvedBPStrong,
1553-
branchDataDeleteBPStrong, NULL, NULL) );
1553+
branchDataDeleteBPStrong, NULL, NULL, NULL) );
15541554

15551555
/* free data if we already solved another instance but branchFreeBPStrong was not called inbetween */
15561556
if( branchruledata->initialized )

src/gcg/branch_compbnd.c

+14-11
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
struct SCIP_BranchruleData
8181
{
8282
GCG* gcg; /**< GCG data structure */
83+
GCG_BRANCHRULE* gcgbranchrule; /**< GCG branchrule structure */
8384
SCIP_Bool useMaxRangeMidrangeHeuristic; /** should the MaxRangeMidrangeHeuristic be used */
8485
SCIP_Bool useMostDistinctMedianHeuristic; /** should the MostDistinctMedianHeuristic be used */
8586
#ifdef COMPBND_STATS
@@ -387,7 +388,7 @@ SCIP_RETCODE addVarToMasterbranch(
387388

388389
*added = FALSE;
389390

390-
coef = GCGextendedmasterconsGetCoeff(gcg, branchdata->mastercons, origvars, origvals, norigvars, GCGvarGetBlock(mastervar));
391+
SCIP_CALL( GCGextendedmasterconsGetCoeff(gcg, branchdata->mastercons, origvars, origvals, norigvars, GCGvarGetBlock(mastervar), &coef) );
391392

392393
if( !SCIPisZero(masterprob, coef) )
393394
{
@@ -401,18 +402,15 @@ SCIP_RETCODE addVarToMasterbranch(
401402

402403
/** callback new column method */
403404
static
404-
GCG_DECL_EXTENDEDMASTERCONSGETCOEFF(extendedmasterconsGetCoeffCompBnd)
405+
GCG_DECL_BRANCHGETEXTENDEDMASTERCONSCOEFF(branchGetExtendedmasterconsCoeffCompBnd)
405406
{
406407
SCIP* masterprob;
407-
GCG_BRANCHDATA* branchdata;
408408

409409
masterprob = GCGgetMasterprob(gcg);
410410

411411
assert(masterprob != NULL);
412412
assert(GCGisMaster(masterprob));
413413

414-
branchdata = (GCG_BRANCHDATA*) GCGextendedmasterconsGetData(extendedmasterconsdata);
415-
416414
assert(branchdata != NULL);
417415
assert(branchdata->mastercons == extendedmasterconsdata);
418416

@@ -433,6 +431,7 @@ GCG_DECL_EXTENDEDMASTERCONSGETCOEFF(extendedmasterconsGetCoeffCompBnd)
433431
static
434432
SCIP_RETCODE createBranchingCons(
435433
GCG* gcg, /**< GCG data structure */
434+
SCIP_BRANCHRULE* branchrule, /**< branch rule structure */
436435
SCIP_NODE* node, /**< node to add constraint */
437436
GCG_BRANCHDATA* branchdata /**< branching data structure */
438437
)
@@ -441,6 +440,7 @@ SCIP_RETCODE createBranchingCons(
441440

442441
SCIP* pricingscip;
443442
SCIP* masterprob;
443+
SCIP_BRANCHRULEDATA* branchruledata;
444444

445445
SCIP_VAR** mastervars;
446446
int nmastervars;
@@ -466,6 +466,9 @@ SCIP_RETCODE createBranchingCons(
466466
assert(branchdata != NULL);
467467
assert(branchdata->mastercons == NULL);
468468

469+
branchruledata = SCIPbranchruleGetData(branchrule);
470+
assert(branchruledata != NULL);
471+
469472
uuid = SCIPnodeGetNumber(node);
470473

471474
mastervars = SCIPgetVars(masterprob);
@@ -634,7 +637,7 @@ SCIP_RETCODE createBranchingCons(
634637
) );
635638

636639
// create the master constraint
637-
SCIP_CALL( GCGextendedmasterconsCreateFromCons(gcg, &branchdata->mastercons, branchcons, pricingmods, 1, branchdata, extendedmasterconsGetCoeffCompBnd) );
640+
SCIP_CALL( GCGbranchCreateExtendedmastercons(gcg, branchruledata->gcgbranchrule, &branchdata->mastercons, branchcons, pricingmods, 1, branchdata) );
638641

639642
// add the variables to the constraint
640643
for( i = 0; i < nmastervars; i++ )
@@ -728,13 +731,13 @@ SCIP_RETCODE createChildNodesCompBndSeq(
728731
SCIP_CALL( GCGcreateConsMasterbranch(gcg, &downChildcons, downChildname, downChild,
729732
GCGconsMasterbranchGetActiveCons(gcg), branchrule, downBranchData, NULL, 0, 0) );
730733
SCIP_CALL( SCIPaddConsNode(masterprob, downChild, downChildcons, NULL) );
731-
SCIP_CALL( createBranchingCons(gcg, downChild, downBranchData) );
734+
SCIP_CALL( createBranchingCons(gcg, branchrule, downChild, downBranchData) );
732735

733736
SCIP_CALL( SCIPcreateChild(masterprob, &upChild, 0.0, SCIPgetLocalTransEstimate(masterprob)) );
734737
SCIP_CALL( GCGcreateConsMasterbranch(gcg, &upChildcons, upChildname, upChild,
735738
GCGconsMasterbranchGetActiveCons(gcg), branchrule, upBranchData, NULL, 0, 0) );
736739
SCIP_CALL( SCIPaddConsNode(masterprob, upChild, upChildcons, NULL) );
737-
SCIP_CALL( createBranchingCons(gcg, upChild, upBranchData) );
740+
SCIP_CALL( createBranchingCons(gcg, branchrule, upChild, upBranchData) );
738741

739742
/* release constraints */
740743
SCIP_CALL( SCIPreleaseCons(masterprob, &upChildcons) );
@@ -2066,7 +2069,6 @@ SCIP_DECL_BRANCHINIT(branchInitCompBnd)
20662069
{
20672070
SCIP_BRANCHRULEDATA* branchruledata;
20682071
#ifdef COMPBND_STATS
2069-
SCIP_BRANCHRULEDATA* branchruledata;
20702072
SCIP_Bool stabilization_tree;
20712073
#endif
20722074

@@ -2082,9 +2084,9 @@ SCIP_DECL_BRANCHINIT(branchInitCompBnd)
20822084

20832085
SCIPdebugMessage("Init method of component bound branching\n");
20842086

2085-
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, branchActiveMasterCompBnd,
2087+
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, &branchruledata->gcgbranchrule, branchActiveMasterCompBnd,
20862088
branchDeactiveMasterCompBnd, branchPropMasterCompBnd, branchMasterSolvedCompBnd, branchDataDeleteCompBnd,
2087-
branchNewColCompBnd, branchGetExtendedmasterconsCompBnd) );
2089+
branchNewColCompBnd, branchGetExtendedmasterconsCompBnd, branchGetExtendedmasterconsCoeffCompBnd) );
20882090

20892091
#ifdef COMPBND_STATS
20902092
/* determine the filename */
@@ -2139,6 +2141,7 @@ SCIP_RETCODE GCGincludeBranchruleCompBnd(
21392141
/* create compbnd branching rule data */
21402142
SCIP_CALL( SCIPallocBlockMemory(masterprob, &branchruledata) );
21412143
branchruledata->gcg = gcg;
2144+
branchruledata->gcgbranchrule = NULL;
21422145

21432146
SCIPdebugMessage("Include method of component bound branching\n");
21442147

src/gcg/branch_generic.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2986,8 +2986,8 @@ SCIP_DECL_BRANCHINIT(branchInitGeneric)
29862986

29872987
SCIPdebugMessage("Init method of Vanderbecks generic branching\n");
29882988

2989-
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, NULL,
2990-
NULL, branchPropMasterGeneric, NULL, branchDataDeleteGeneric, branchNewColGeneric, NULL) );
2989+
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, NULL, NULL,
2990+
NULL, branchPropMasterGeneric, NULL, branchDataDeleteGeneric, branchNewColGeneric, NULL, NULL) );
29912991

29922992
return SCIP_OKAY;
29932993
}

src/gcg/branch_orig.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -831,8 +831,8 @@ SCIP_DECL_BRANCHINIT(branchInitOrig)
831831

832832
SCIPdebugMessage("Init orig branching rule\n");
833833

834-
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, branchActiveMasterOrig,
835-
branchDeactiveMasterOrig, branchPropMasterOrig, branchMasterSolvedOrig, branchDataDeleteOrig, NULL, NULL) );
834+
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, NULL, branchActiveMasterOrig,
835+
branchDeactiveMasterOrig, branchPropMasterOrig, branchMasterSolvedOrig, branchDataDeleteOrig, NULL, NULL, NULL) );
836836

837837
return SCIP_OKAY;
838838
}

src/gcg/branch_ryanfoster.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -946,8 +946,8 @@ SCIP_DECL_BRANCHINIT(branchInitRyanfoster)
946946
branchruledata = SCIPbranchruleGetData(branchrule);
947947
assert(branchruledata != NULL);
948948

949-
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, branchActiveMasterRyanfoster,
950-
branchDeactiveMasterRyanfoster, branchPropMasterRyanfoster, NULL, branchDataDeleteRyanfoster, NULL, NULL) );
949+
SCIP_CALL( GCGrelaxIncludeBranchrule(branchruledata->gcg, branchrule, NULL, branchActiveMasterRyanfoster,
950+
branchDeactiveMasterRyanfoster, branchPropMasterRyanfoster, NULL, branchDataDeleteRyanfoster, NULL, NULL, NULL) );
951951

952952
return SCIP_OKAY;
953953
}

src/gcg/branch_xyz.c

+37-21
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,6 @@ SCIP_DECL_BRANCHFREE(branchFreeXyz)
108108
#endif
109109

110110

111-
/** initialization method of branching rule (called after problem was transformed) */
112-
#ifdef SCIP_DISABLED_CODE
113-
static
114-
SCIP_DECL_BRANCHINIT(branchInitXyz)
115-
{ /*lint --e{715}*/
116-
117-
/* inform relaxator of GCG about the branching rule */
118-
SCIP_CALL( GCGrelaxIncludeBranchrule(scip, branchrule, branchActiveMasterOrig,
119-
branchDeactiveMasterOrig, branchPropMasterOrig, branchMasterSolvedOrig, branchDataDeleteOrig,
120-
branchNewColXyz, branchGetExtendedMasterConsXyz) );
121-
122-
SCIPerrorMessage("method of xyz branching rule not implemented yet\n");
123-
SCIPABORT(); /*lint --e{527}*/
124-
125-
return SCIP_OKAY;
126-
}
127-
#else
128-
#define branchInitXyz NULL
129-
#endif
130-
131-
132111
/** deinitialization method of branching rule (called before transformed problem is freed) */
133112
#ifdef SCIP_DISABLED_CODE
134113
static
@@ -329,6 +308,43 @@ GCG_DECL_BRANCHGETEXTENDEDMASTERCONS(branchGetExtendedMasterConsXyz)
329308
#define branchGetExtendedmasterconsXyz NULL
330309
#endif
331310

311+
/** call to determine the coefficient of a column solution in the extended master cons */
312+
#ifdef SCIP_DISABLED_CODE
313+
static
314+
GCG_DECL_BRANCHGETEXTENDEDMASTERCONSCOEFF(branchGetExtendedmasterconsCoeffXyz)
315+
{ /*lint --e{715}*/
316+
SCIPerrorMessage("method of xyz branching rule not implemented yet\n");
317+
SCIPABORT(); /*lint --e{527}*/
318+
319+
return SCIP_OKAY;
320+
}
321+
#else
322+
#define branchGetExtendedmasterconsCoeffXyz NULL
323+
#endif
324+
325+
326+
/** initialization method of branching rule (called after problem was transformed) */
327+
#ifdef SCIP_DISABLED_CODE
328+
static
329+
SCIP_DECL_BRANCHINIT(branchInitXyz)
330+
{ /*lint --e{715}*/
331+
GCG_BRANCHRULE* gcgbranchrule = NULL;
332+
333+
/* inform relaxator of GCG about the branching rule */
334+
SCIP_CALL( GCGrelaxIncludeBranchrule(scip, branchrule, &gcgbranchrule, branchActiveMasterOrig,
335+
branchDeactiveMasterOrig, branchPropMasterOrig, branchMasterSolvedOrig, branchDataDeleteOrig,
336+
branchNewColXyz, branchGetExtendedMasterConsXyz, branchGetExtendedmasterconsCoeff) );
337+
338+
SCIPerrorMessage("method of xyz branching rule not implemented yet\n");
339+
SCIPABORT(); /*lint --e{527}*/
340+
341+
return SCIP_OKAY;
342+
}
343+
#else
344+
#define branchInitXyz NULL
345+
#endif
346+
347+
332348
/*
333349
* branching rule specific interface methods
334350
*/

0 commit comments

Comments
 (0)