39 #include "scip/scip.h"
47 #define SEPA_NAME "master"
48 #define SEPA_DESC "separator for separating cuts in the original problem, called in the master"
49 #define SEPA_PRIORITY 1000
52 #define SEPA_MAXBOUNDDIST 1.0
53 #define SEPA_USESSUBSCIP FALSE
54 #define SEPA_DELAY FALSE
56 #define STARTMAXCUTS 50
84 SCIP_SEPADATA* sepadata,
89 assert(sepadata != NULL);
90 assert(sepadata->mastercuts != NULL);
91 assert(sepadata->origcuts != NULL);
92 assert(sepadata->ncuts <= sepadata->maxcuts);
93 assert(sepadata->ncuts >= 0);
95 if( sepadata->maxcuts < size )
97 int newmaxcuts = SCIPcalcMemGrowSize(scip, size);
98 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(sepadata->mastercuts), sepadata->maxcuts, newmaxcuts) );
99 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(sepadata->origcuts), sepadata->maxcuts, newmaxcuts) );
100 sepadata->maxcuts = newmaxcuts;
102 assert(sepadata->maxcuts >= size);
111 #define sepaCopyMaster NULL
112 #define sepaInitMaster NULL
113 #define sepaInitsolMaster NULL
114 #define sepaExecsolMaster NULL
120 SCIP_SEPADATA* sepadata;
122 sepadata = SCIPsepaGetData(sepa);
124 SCIPfreeBlockMemoryArray(scip, &(sepadata->origcuts), sepadata->maxcuts);
125 SCIPfreeBlockMemoryArray(scip, &(sepadata->mastercuts), sepadata->maxcuts);
127 SCIPfreeBlockMemory(scip, &sepadata);
137 SCIP_SEPADATA* sepadata;
140 sepadata = SCIPsepaGetData(sepa);
141 assert(sepadata != NULL);
144 assert(origscip != NULL);
146 for( i = 0; i < sepadata->ncuts; i++ )
148 SCIP_CALL( SCIPreleaseRow(origscip, &(sepadata->origcuts[i])) );
160 SCIP_SEPADATA* sepadata;
163 sepadata = SCIPsepaGetData(sepa);
164 assert(sepadata != NULL);
168 for( i = 0; i < sepadata->ncuts; i++ )
170 SCIP_CALL( SCIPreleaseRow(scip, &(sepadata->mastercuts[i])) );
186 SCIP_SEPADATA* sepadata;
188 SCIP_VAR** mastervars;
189 SCIP_Real* mastervals;
192 char name[SCIP_MAXSTRLEN];
202 assert(scip != NULL);
203 assert(result != NULL);
206 assert(origscip != NULL);
208 sepadata = SCIPsepaGetData(sepa);
209 assert(sepadata != NULL);
211 SCIPdebugMessage(
"sepaExeclpMaster\n");
213 *result = SCIP_DIDNOTFIND;
215 if( !sepadata->enable )
217 *result = SCIP_DIDNOTRUN;
221 if( SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
223 SCIPdebugMessage(
"master LP not solved to optimality, do no separation!\n");
229 SCIPdebugMessage(
"aggregated pricing problems, do no separation!\n");
230 *result = SCIP_DIDNOTRUN;
239 SCIPdebugMessage(
"Current solution is feasible, no separation necessary!\n");
240 *result = SCIP_DIDNOTRUN;
244 isroot = SCIPgetCurrentNode(scip) == SCIPgetRootNode(scip);
247 SCIP_CALL( SCIPsetSeparating(origscip, (SCIP_PARAMSETTING) sepadata->separationsetting, TRUE) );
250 isroot, TRUE, FALSE, &delayed, &cutoff) );
252 SCIPdebugMessage(
"SCIPseparateSol() found %d cuts!\n", SCIPgetNCuts(origscip));
254 if( delayed && !cutoff )
256 SCIPdebugMessage(
"call delayed separators\n");
259 isroot, TRUE, TRUE, &delayed, &cutoff) );
265 *result = SCIP_CUTOFF;
266 SCIP_CALL( SCIPendProbing(origscip) );
269 SCIP_CALL( SCIPsetSeparating(origscip, SCIP_PARAMSETTING_OFF, TRUE) );
274 cuts = SCIPgetCuts(origscip);
275 ncuts = SCIPgetNCuts(origscip);
278 norigcuts = sepadata->ncuts;
279 SCIP_CALL(
ensureSizeCuts(scip, sepadata, sepadata->ncuts + ncuts) );
281 for( i = 0; i < ncuts; i++ )
283 sepadata->origcuts[norigcuts] = cuts[i];
284 SCIP_CALL( SCIPcaptureRow(origscip, sepadata->origcuts[norigcuts]) );
288 SCIP_CALL( SCIPclearCuts(origscip) );
290 mastervars = SCIPgetVars(scip);
291 nmastervars = SCIPgetNVars(scip);
292 SCIP_CALL( SCIPallocBufferArray(scip, &mastervals, nmastervars) );
294 for( i = 0; i < ncuts; i++ )
302 origcut = sepadata->origcuts[norigcuts-ncuts+i];
305 ncols = SCIProwGetNNonz(origcut);
306 cols = SCIProwGetCols(origcut);
307 vals = SCIProwGetVals(origcut);
310 SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, ncols) );
311 for( j = 0; j < ncols; j++ )
313 rowvars[j] = SCIPcolGetVar(cols[j]);
321 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN,
"mc_%s", SCIProwGetName(origcut));
322 SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &mastercut, sepa, name,
323 ( SCIPisInfinity(scip, -SCIProwGetLhs(origcut)) ?
324 SCIProwGetLhs(origcut) : SCIProwGetLhs(origcut) - SCIProwGetConstant(origcut) - shift),
325 ( SCIPisInfinity(scip, SCIProwGetRhs(origcut)) ?
326 SCIProwGetRhs(origcut) : SCIProwGetRhs(origcut) - SCIProwGetConstant(origcut) - shift),
327 SCIProwIsLocal(origcut), TRUE, FALSE) );
330 SCIP_CALL( SCIPaddVarsToRow(scip, mastercut, nmastervars, mastervars, mastervals) );
333 SCIP_CALL( SCIPaddRow(scip, mastercut, FALSE, &feasible) );
334 sepadata->mastercuts[sepadata->ncuts] = mastercut;
338 SCIPdebugMessage(
"Cut %d:\n", i);
339 SCIP_CALL( SCIPprintRow(scip, mastercut, NULL) );
340 SCIPdebugMessage(
"\n\n");
343 SCIPfreeBufferArray(scip, &rowvars);
346 assert(norigcuts == sepadata->ncuts);
349 *result = SCIP_SEPARATED;
351 SCIPdebugMessage(
"%d cuts are in the original sepastore!\n", SCIPgetNCuts(origscip));
352 SCIPdebugMessage(
"%d cuts are in the master sepastore!\n", SCIPgetNCuts(scip));
355 SCIP_CALL( SCIPsetSeparating(origscip, SCIP_PARAMSETTING_OFF, TRUE) );
357 SCIPfreeBufferArray(scip, &mastervals);
372 SCIP_SEPADATA* sepadata;
375 SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
377 sepadata->maxcuts = SCIPcalcMemGrowSize(scip,
STARTMAXCUTS);
378 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(sepadata->origcuts), sepadata->maxcuts) );
379 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(sepadata->mastercuts), sepadata->maxcuts) );
390 &(sepadata->enable), FALSE, TRUE, NULL, NULL) );
392 SCIP_CALL( SCIPaddIntParam(
GCGmasterGetOrigprob(scip),
"sepa/" SEPA_NAME "/paramsetting",
"parameter returns which parameter setting is used for "
393 "separation (default = 0, aggressive = 1, fast = 2", &(sepadata->separationsetting), FALSE, 1, 0, 2, NULL, NULL) );
405 SCIP_SEPADATA* sepadata;
407 assert(scip != NULL);
410 assert(sepa != NULL);
412 sepadata = SCIPsepaGetData(sepa);
413 assert(sepadata != NULL);
415 return sepadata->origcuts;
424 SCIP_SEPADATA* sepadata;
426 assert(scip != NULL);
429 assert(sepa != NULL);
431 sepadata = SCIPsepaGetData(sepa);
432 assert(sepadata != NULL);
434 return sepadata->ncuts;
443 SCIP_SEPADATA* sepadata;
445 assert(scip != NULL);
448 assert(sepa != NULL);
450 sepadata = SCIPsepaGetData(sepa);
451 assert(sepadata != NULL);
453 return sepadata->mastercuts;
464 SCIP_SEPADATA* sepadata;
466 assert(scip != NULL);
469 assert(sepa != NULL);
471 sepadata = SCIPsepaGetData(sepa);
472 assert(sepadata != NULL);
476 sepadata->origcuts[sepadata->ncuts] = origcut;
477 sepadata->mastercuts[sepadata->ncuts] = mastercut;
478 SCIP_CALL( SCIPcaptureRow(scip, sepadata->origcuts[sepadata->ncuts]) );
479 SCIP_CALL( SCIPcaptureRow(scip, sepadata->mastercuts[sepadata->ncuts]) );