47 #include "scip/scip.h" 48 #include "scip/misc.h" 49 #include "scip/cons_linear.h" 57 #define CONSHDLR_NAME "stp" 58 #define CONSHDLR_DESC "steiner tree constraint handler" 59 #define CONSHDLR_SEPAPRIORITY 0 60 #define CONSHDLR_ENFOPRIORITY 0 61 #define CONSHDLR_CHECKPRIORITY 9999999 62 #define CONSHDLR_SEPAFREQ 1 63 #define CONSHDLR_PROPFREQ 0 64 #define CONSHDLR_EAGERFREQ 1 66 #define CONSHDLR_DELAYSEPA FALSE 67 #define CONSHDLR_DELAYPROP FALSE 68 #define CONSHDLR_NEEDSCONS TRUE 70 #define DEFAULT_MAXROUNDS 5 71 #define DEFAULT_MAXROUNDSROOT -1 72 #define DEFAULT_MAXSEPACUTS INT_MAX 73 #define DEFAULT_MAXSEPACUTSROOT INT_MAX 76 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP 78 #define DEFAULT_BACKCUT FALSE 79 #define DEFAULT_CREEPFLOW TRUE 80 #define DEFAULT_DISJUNCTCUT FALSE 81 #define DEFAULT_NESTEDCUT FALSE 82 #define DEFAULT_FLOWSEP TRUE 84 #define DEFAULT_DAMAXDEVIATION 0.25 86 #define FLOW_FACTOR 100000 105 SCIP_Bool disjunctcut;
125 SCIP_CONSHDLR* conshdlr,
128 const SCIP_Real* xval,
130 const int updatecapa,
138 SCIP_Bool inccapa =
FALSE;
143 assert(scip != NULL);
145 assert((layer >= 0) && (layer < g->layers));
147 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"2cut", 1.0, SCIPinfinity(scip),
FALSE,
FALSE,
TRUE) );
149 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
151 for( i = 0; i < g->
edges; i++ )
156 ind = layer * g->
edges + i;
163 SCIPdebugMessage(
"set capa[%d] from %6d to %6d\n", i, capa[i],
FLOW_FACTOR);
168 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
169 SCIP_CALL( SCIPreleaseRow(scip, &row) );
178 if( SCIPisFeasGE(scip, sum, 1.0) )
180 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
181 SCIP_CALL( SCIPreleaseRow(scip, &row) );
185 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], 1.0) );
190 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
193 if( SCIPisCutEfficacious(scip, NULL, row) )
195 SCIP_Bool infeasible;
197 SCIPdebug( SCIP_CALL( SCIPprintRow(scip, row, NULL) ) );
199 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
204 SCIP_CALL( SCIPreleaseRow(scip, &row) );
221 assert(term != NULL);
223 for( i = 0; (i < terms); i++ )
225 if( w[term[i]] == 0 )
230 if( w[term[i]] > wmax )
241 term[k] = term[terms - 1];
250 const SCIP_Bool creep_flow,
253 const SCIP_Real* xval
259 assert(xval != NULL);
261 for( k = 0; k < g->
edges; k += 2 )
265 capa[k] = (int)(xval[layer * g->
edges + k ]
267 capa[k + 1] = (int)(xval[layer * g->
edges + k + 1]
272 capa[k] = (int)(xval[layer * g->
edges + k + 1]
274 capa[k + 1] = (int)(xval[layer * g->
edges + k ]
278 if( creep_flow && (capa[k] == 0) && (capa[k + 1] == 0) )
290 SCIP_CONSHDLR* conshdlr,
291 SCIP_CONSHDLRDATA* conshdlrdata,
292 SCIP_CONSDATA* consdata,
299 SCIP_ROW* row = NULL;
308 unsigned int flowsep;
310 assert(scip != NULL);
311 assert(conshdlr != NULL);
312 assert(conshdlrdata != NULL);
315 flowsep = conshdlrdata->flowsep;
322 assert(xval != NULL);
324 for(i = 0; i < g->
knots; i++)
326 for(layer = 0; layer < g->
layers; layer++)
329 if( i == g->
source[layer] )
335 if( g->
term[i] == layer )
341 ind = layer * g->
edges + k;
342 sum += (xval != NULL) ? xval[ind] : 0.0;
345 if( !SCIPisFeasEQ(scip, sum, 1.0) )
347 SCIP_Bool infeasible;
349 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"term", 1.0,
352 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
356 ind = layer * g->
edges + k;
358 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], 1.0) );
361 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
363 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
366 SCIP_CALL( SCIPreleaseRow(scip, &row) );
368 if( *ncuts + count >= maxcuts )
380 ind = layer * g->
edges + j;
381 sum = (xval != NULL) ? -xval[ind] : -1.0;
385 ind = layer * g->
edges + k;
386 sum += (xval != NULL) ? xval[ind] : 0.0;
388 if( SCIPisFeasNegative(scip, sum) )
390 SCIP_Bool infeasible;
392 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"flow", 0.0, SCIPinfinity(scip),
395 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
397 ind = layer * g->
edges + j;
399 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], -1.0) );
403 ind = layer * g->
edges + k;
405 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], 1.0) );
408 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
410 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
413 SCIP_CALL( SCIPreleaseRow(scip, &row) );
415 if( *ncuts + count >= maxcuts )
421 if( g->
term[i] == layer )
429 ind = layer * g->
edges + k;
430 sum += (xval != NULL) ? xval[ind] : 1.0;
432 if( SCIPisFeasGT(scip, sum, 1.0) )
434 SCIP_Bool infeasible;
436 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"infl", -SCIPinfinity(scip),
439 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
443 ind = layer * g->
edges + k;
445 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], 1.0) );
448 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
450 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
453 SCIP_CALL( SCIPreleaseRow(scip, &row) );
455 if( *ncuts + count >= maxcuts )
464 ind = layer * g->
edges + k;
465 sum -= (xval != NULL) ? xval[ind] : 1.0;
469 ind = layer * g->
edges + k;
470 sum += (xval != NULL) ? xval[ind] : 0.0;
472 if( SCIPisFeasNegative(scip, sum) )
474 SCIP_Bool infeasible;
476 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"bala", 0.0,
479 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
483 ind = layer * g->
edges + k;
485 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], -1.0) );
489 ind = layer * g->
edges + k;
491 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[ind], 1.0) );
494 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
496 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
499 SCIP_CALL( SCIPreleaseRow(scip, &row) );
501 if( *ncuts + count >= maxcuts )
509 SCIPdebugMessage(
"In/Out Separator: %d Inequalities added\n", count);
520 SCIP_CONSHDLR* conshdlr,
521 SCIP_CONSHDLRDATA* conshdlrdata,
522 SCIP_CONSDATA* consdata,
527 const SCIP_Bool nested_cut = conshdlrdata->nestedcut;
528 const SCIP_Bool back_cut = conshdlrdata->backcut;
529 const SCIP_Bool creep_flow = conshdlrdata->creepflow;
530 SCIP_Bool disjunct_cut;
531 const SCIP_Bool flowsep = conshdlrdata->flowsep;
551 assert(scip != NULL);
552 assert(conshdlr != NULL);
553 assert(conshdlrdata != NULL);
559 disjunct_cut = conshdlrdata->disjunctcut;
568 assert(xval != NULL);
570 SCIP_CALL( SCIPallocBufferArray(scip, &capa, nedges) );
571 SCIP_CALL( SCIPallocBufferArray(scip, &cost, nedges) );
572 SCIP_CALL( SCIPallocBufferArray(scip, &w, nnodes) );
573 SCIP_CALL( SCIPallocBufferArray(scip, &term, g->
terms) );
574 SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
576 for( layer = 0; layer < g->
layers; layer++ )
579 if( flowsep && (g->
locals[layer] == 2) )
582 for( i = 0; i < nedges; i++ )
583 cost[i] = SCIPisFeasLT(scip, xval[layer * nedges + i], 1.0) ? 1.0 : 0.0;
585 for( i = 0; i < nnodes; i++ )
594 for( i = 0, count = 0; i < nnodes; i++ )
596 if( (g->
term[i] == layer) && (i != g->
source[layer]) )
598 if( SCIPisPositive(scip, path[i].dist) )
604 SCIPdebugMessage(
"Cut Pretest: %d eliminations\n", count);
610 if( !nested_cut || disjunct_cut )
615 if( SCIPisStopped(scip) && terms % 100 == 0 )
623 assert(g->
term[i] == layer);
624 assert(g->
source[layer] != i);
626 if( nested_cut && !disjunct_cut )
636 for( k = 0; k < nnodes; k++ )
637 g->
mark[k] = (w[k] != 0);
639 SCIP_CALL(
cut_add(scip, conshdlr, g, layer, xval, capa, nested_cut || disjunct_cut, ncuts, &addedcut) );
644 if( *ncuts >= maxcuts )
656 if( !nested_cut || disjunct_cut )
668 assert(g->
term[i] == layer);
669 assert(g->
source[layer] != i);
671 if( nested_cut && !disjunct_cut )
682 for( k = 0; k < nnodes; k++ )
683 g->
mark[k] = (w[k] != 0) ? 1 : 0;
685 SCIP_CALL(
cut_add(scip, conshdlr, g, layer, xval, capa, nested_cut || disjunct_cut, ncuts, &addedcut) );
690 if( *ncuts >= maxcuts )
696 if (nested_cut || disjunct_cut)
697 for(k = p->beg[p->rcnt - 1]; k < p->nzcnt; k++)
698 capa[p->ind[k] % nedges
699 + (((p->ind[k] % nedges) % 2)
711 SCIPfreeBufferArray(scip, &path);
712 SCIPfreeBufferArray(scip, &term);
713 SCIPfreeBufferArray(scip, &w);
714 SCIPfreeBufferArray(scip, &cost);
715 SCIPfreeBufferArray(scip, &capa);
717 SCIPdebugMessage(
"2-cut Separator: %d Inequalities added\n", count);
736 assert(scip != NULL);
737 assert(conshdlr != NULL);
738 assert(strcmp(SCIPconshdlrGetName(conshdlr),
CONSHDLR_NAME) == 0);
752 SCIP_CONSHDLRDATA* conshdlrdata;
754 assert(scip != NULL);
755 assert(conshdlr != NULL);
756 assert(strcmp(SCIPconshdlrGetName(conshdlr),
CONSHDLR_NAME) == 0);
759 conshdlrdata = SCIPconshdlrGetData(conshdlr);
760 assert(conshdlrdata != NULL);
762 SCIPfreeMemory(scip, &conshdlrdata);
764 SCIPconshdlrSetData(conshdlr, NULL);
774 SCIP_PROBDATA* probdata;
777 probdata = SCIPgetProbData(scip);
778 assert(probdata != NULL);
781 assert(graph != NULL);
792 assert(conshdlr != NULL);
793 assert(strcmp(SCIPconshdlrGetName(conshdlr),
CONSHDLR_NAME) == 0);
794 assert(consdata != NULL);
795 assert(*consdata != NULL);
797 SCIPfreeBlockMemory(scip, consdata);
806 SCIP_CONSDATA* sourcedata;
807 SCIP_CONSDATA* targetdata;
809 assert(conshdlr != NULL);
810 assert(strcmp(SCIPconshdlrGetName(conshdlr),
CONSHDLR_NAME) == 0);
811 assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
812 assert(sourcecons != NULL);
813 assert(targetcons != NULL);
815 sourcedata = SCIPconsGetData(sourcecons);
816 assert(sourcedata != NULL);
819 SCIP_CALL( SCIPallocBlockMemory(scip, &targetdata) );
821 targetdata->graph = sourcedata->graph;
824 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
825 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
826 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
827 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
828 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
839 SCIP_PROBDATA* probdata;
845 probdata = SCIPgetProbData(scip);
846 assert(probdata != NULL);
849 assert(graph != NULL);
861 SCIP_CONSHDLRDATA* conshdlrdata;
866 *result = SCIP_DIDNOTRUN;
868 conshdlrdata = SCIPconshdlrGetData(conshdlr);
869 assert(conshdlrdata != NULL);
871 maxcuts = SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) == 0 ?
872 conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts;
874 for( i = 0; i < nconss; ++i )
876 SCIP_CONSDATA* consdata;
878 consdata = SCIPconsGetData(conss[i]);
880 SCIP_CALL(
sep_flow(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) );
882 SCIP_CALL(
sep_2cut(scip, conshdlr, conshdlrdata, consdata, maxcuts, &ncuts) );
886 *result = SCIP_SEPARATED;
897 SCIP_CONSDATA* consdata;
900 for( i = 0; i < nconss; i++ )
902 consdata = SCIPconsGetData(conss[i]);
908 *result = SCIP_INFEASIBLE;
912 *result = SCIP_FEASIBLE;
922 SCIP_CONSDATA* consdata;
925 for( i = 0; i < nconss; i++ )
927 consdata = SCIPconsGetData(conss[i]);
933 *result = SCIP_INFEASIBLE;
937 *result = SCIP_FEASIBLE;
947 SCIP_CONSDATA* consdata;
950 for( i = 0; i < nconss; i++ )
952 consdata = SCIPconsGetData(conss[i]);
958 *result = SCIP_INFEASIBLE;
962 *result = SCIP_FEASIBLE;
971 SCIP_PROBDATA* probdata;
974 probdata = SCIPgetProbData(scip);
975 assert(probdata != NULL);
978 assert(graph != NULL);
988 nnodes = graph->
knots;
991 assert(maxdegs != NULL);
994 for( k = 0; k < nnodes; k++ )
998 assert(maxdegs[k] > 0);
999 degsum += maxdegs[k] - 1;
1003 assert(maxdegs[k] >= 0);
1004 degsum += MAX(maxdegs[k] - 2, 0);
1008 if( degsum < graph->terms - 2 )
1009 *result = SCIP_CUTOFF;
1011 *result = SCIP_DIDNOTFIND;
1024 assert(scip != NULL);
1025 assert(cons != NULL);
1030 for( v = 0; v < nvars; ++v )
1031 SCIP_CALL( SCIPaddVarLocks(scip, vars[v], 1, 1) );
1040 const char* consname;
1041 SCIP_PROBDATA* probdata;
1044 probdata = SCIPgetProbData(scip);
1045 assert(probdata != NULL);
1048 assert(graph != NULL);
1050 consname = SCIPconsGetName(sourcecons);
1073 SCIP_CONSHDLRDATA* conshdlrdata;
1074 SCIP_CONSHDLR* conshdlr;
1077 SCIP_CALL( SCIPallocMemory(scip, &conshdlrdata) );
1083 consEnfolpStp, consEnfopsStp, consCheckStp, consLockStp,
1085 assert(conshdlr != NULL);
1087 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyStp, consCopyStp) );
1088 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteStp) );
1089 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransStp) );
1090 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolStp) );
1091 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpStp) );
1094 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpStp, NULL,
CONSHDLR_SEPAFREQ,
1096 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeStp) );
1098 SCIP_CALL( SCIPaddBoolParam(scip,
"constraints/stp/backcut",
"Try Back-Cuts",
1100 SCIP_CALL( SCIPaddBoolParam(scip,
"constraints/stp/creepflow",
"Use Creep-Flow",
1102 SCIP_CALL( SCIPaddBoolParam(scip,
"constraints/stp/disjunctcut",
"Only disjunct Cuts",
1104 SCIP_CALL( SCIPaddBoolParam(scip,
"constraints/stp/nestedcut",
"Try Nested-Cuts",
1106 SCIP_CALL( SCIPaddBoolParam(scip,
"constraints/stp/flowsep",
"Try Flow-Cuts",
1108 SCIP_CALL( SCIPaddIntParam(scip,
1110 "maximal number of separation rounds per node (-1: unlimited)",
1112 SCIP_CALL( SCIPaddIntParam(scip,
1114 "maximal number of separation rounds per node in the root node (-1: unlimited)",
1116 SCIP_CALL( SCIPaddIntParam(scip,
1118 "maximal number of cuts separated per separation round",
1120 SCIP_CALL( SCIPaddIntParam(scip,
1122 "maximal number of cuts separated per separation round in the root node",
1137 SCIP_CONSHDLR* conshdlr;
1138 SCIP_CONSDATA* consdata;
1142 if( conshdlr == NULL )
1144 SCIPerrorMessage(
"stp constraint handler not found\n");
1145 return SCIP_PLUGINNOTFOUND;
1148 SCIP_CALL( SCIPallocBlockMemory(scip, &consdata) );
1150 consdata->graph =
graph;
1153 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
1166 GNODE** gnodearrterms,
1176 SCIP_CONSHDLR* conshdlr;
1179 SCIP_PQUEUE* pqueue;
1185 SCIP_Real currscore;
1186 SCIP_Real maxdeviation;
1189 SCIP_Bool infeasible;
1214 assert(scip != NULL);
1216 assert(objval != NULL);
1225 assert(vars != NULL);
1238 conshdlr = SCIPfindConshdlr(scip,
"stp");
1251 if( redcost == NULL )
1253 SCIP_CALL( SCIPallocBufferArray(scip, &rescap, nedges) );
1260 if( edgearrchar == NULL )
1262 SCIP_CALL( SCIPallocBufferArray(scip, &sat, nedges) );
1269 if( nodearrchar == NULL )
1271 SCIP_CALL( SCIPallocBufferArray(scip, &active, nnodes) );
1275 active = nodearrchar;
1278 if( nodearrint == NULL )
1280 SCIP_CALL( SCIPallocBufferArray(scip, &cutverts, nnodes) );
1284 cutverts = nodearrint;
1287 if( edgearrint == NULL )
1289 SCIP_CALL( SCIPallocBufferArray(scip, &unsatarcs, nedges) );
1293 unsatarcs = edgearrint;
1297 if( gnodearrterms == NULL )
1299 SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
1300 for( i = 0; i < nterms - 1; i++ )
1302 SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) );
1307 gnodearr = gnodearrterms;
1310 SCIP_CALL( SCIPqueueCreate(&queue, nnodes - nterms + 1, 2.0) );
1311 SCIP_CALL( SCIPpqueueCreate(&pqueue, nterms, 2.0,
GNODECmpByDist) );
1316 for( i = 0; i < nnodes; i++ )
1321 assert(g->
grad[i] > 0);
1326 if( g->
grad[i] == 2 )
1329 if( SCIPisEQ(scip, g->
cost[a], 0.0) )
1335 printf(
"%d grad: %d grad2 %d, score %f\n", i, g->
grad[i], g->
grad[g->
tail[a]], gnodearr[k]->
dist);
1337 assert(gnodearr[k]->dist > 0);
1340 SCIP_CALL( SCIPpqueueInsert(pqueue, gnodearr[k++]) );
1351 for( i = 0; i < nedges; i++ )
1353 rescap[i] = g->
cost[i];
1355 if( SCIPisZero(scip, rescap[i]) )
1362 while( SCIPpqueueNElems(pqueue) > 0 && !SCIPisStopped(scip) )
1365 gnodeact = (
GNODE*) SCIPpqueueRemove(pqueue);
1368 prio1 = gnodeact->
dist;
1373 while( !SCIPisStopped(scip) )
1375 assert(SCIPqueueIsEmpty(queue));
1385 cutverts[ncutverts++] = v;
1386 SCIP_CALL( SCIPqueueInsert(queue, &(g->
tail[g->
outbeg[v]])) );
1391 for( i = norgcutverts; i < ncutverts; i++ )
1398 SCIPqueueClear(queue);
1402 SCIP_CALL( SCIPqueueInsert(queue, &(g->
tail[g->
outbeg[s]])) );
1406 while( !SCIPqueueIsEmpty(queue) )
1408 pnode = (SCIPqueueRemove(queue));
1416 if( !g->
mark[tail] )
1422 SCIPqueueClear(queue);
1425 score += g->
grad[tail];
1427 cutverts[ncutverts++] = tail;
1428 SCIP_CALL( SCIPqueueInsert(queue, &(g->
tail[a])) );
1431 else if( !g->
mark[tail] )
1433 unsatarcs[nunsatarcs++] = a;
1444 for( i = 0; i < nunsatarcs; i++ )
1455 if( SCIPisLT(scip, rescap[a], min) )
1458 unsatarcs[i - shift] = a;
1462 assert(SCIPisLT(scip, min,
FARAWAY));
1463 nunsatarcs -= shift;
1466 for( i = 0; i < nunsatarcs; i++ )
1467 printf(
"[%d]: %d ", i, unsatarcs[i]);
1471 assert(!g->
mark[g->
tail[unsatarcs[nunsatarcs-1]]]);
1475 currscore = score - (ncutverts - 1);
1476 assert(SCIPisGE(scip, currscore, prio1));
1477 norgcutverts = ncutverts;
1480 if( SCIPisLT(scip, (currscore - prio1) / prio1, maxdeviation) )
1485 SCIP_CONS* cons = NULL;
1489 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"dualascentcut", 1.0, SCIPinfinity(scip),
FALSE,
FALSE,
TRUE) );
1490 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
1496 SCIP_CALL( SCIPcreateConsLinear ( scip, &cons,
"da", 0, NULL, NULL,
1497 1.0, SCIPinfinity(scip),
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE) );
1499 SCIP_CALL( SCIPaddCons(scip, cons) );
1503 for( i = 0; i < nunsatarcs; i++ )
1511 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[a], 1.0) );
1515 assert(cons != NULL);
1516 assert(vars != NULL);
1517 SCIP_CALL( SCIPaddCoefLinear(scip, cons, vars[a], 1.0) );
1521 assert(SCIPisGE(scip, rescap[a], 0.0));
1523 if( SCIPisEQ(scip, rescap[a], 0.0) )
1529 score += g->
grad[tail];
1531 cutverts[ncutverts++] = tail;
1536 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
1537 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
1538 SCIP_CALL( SCIPreleaseRow(scip, &row) );
1542 assert(cons != NULL);
1543 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1546 currscore = score - (ncutverts - 1);
1552 gnodeact->
dist = currscore;
1553 SCIP_CALL( SCIPpqueueInsert(pqueue, gnodeact) );
1558 for( i = 0; i < ncutverts; i++ )
1566 SCIPdebugMessage(
"DA: dualglobal: %f \n", dualobj);
1571 SCIPpqueueFree(&pqueue);
1572 SCIPqueueFree(&queue);
1574 if( gnodearrterms == NULL )
1576 for( i = nterms - 2; i >= 0; i-- )
1577 SCIPfreeBuffer(scip, &gnodearr[i]);
1578 SCIPfreeBufferArray(scip, &gnodearr);
1581 if( edgearrint == NULL )
1582 SCIPfreeBufferArray(scip, &unsatarcs);
1584 if( nodearrint == NULL )
1585 SCIPfreeBufferArray(scip, &cutverts);
1587 if( nodearrchar == NULL )
1588 SCIPfreeBufferArray(scip, &active);
1590 if( edgearrchar == NULL )
1591 SCIPfreeBufferArray(scip, &sat);
1593 if( redcost == NULL )
1594 SCIPfreeBufferArray(scip, &rescap);
1611 SCIP_CONSHDLR* conshdlr;
1614 SCIP_PQUEUE* pqueue;
1622 SCIP_Real currscore;
1623 SCIP_Real maxdeviation;
1651 assert(scip != NULL);
1653 assert(objval != NULL);
1661 assert(vars != NULL);
1673 conshdlr = SCIPfindConshdlr(scip,
"stp");
1682 nnodes = transgraph->
knots;
1683 nedges = transgraph->
edges;
1684 nterms = transgraph->
terms;
1685 pseudoroot = nnodes - 1;
1687 if( redcost == NULL )
1689 SCIP_CALL( SCIPallocBufferArray(scip, &rescap, nedges) );
1696 SCIP_CALL( SCIPallocBufferArray(scip, &sat, nedges) );
1697 SCIP_CALL( SCIPallocBufferArray(scip, &active, nnodes) );
1698 SCIP_CALL( SCIPallocBufferArray(scip, &cutverts, nnodes) );
1699 SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
1700 SCIP_CALL( SCIPallocBufferArray(scip, &unsatarcs, nedges) );
1701 SCIP_CALL( SCIPallocBufferArray(scip, &origedge, nedges) );
1704 for( i = 0; i < nedges; i++ )
1705 if( !
Is_term(transgraph->
term[transgraph->
tail[i]]) && transgraph->
head[i] == pseudoroot )
1706 origedge[i] =
FALSE;
1707 else if( transgraph->
tail[i] == pseudoroot && !
Is_term(transgraph->
term[transgraph->
head[i]]) )
1708 origedge[i] =
FALSE;
1712 for( i = 0; i < nterms - 1; i++ )
1714 SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) );
1717 SCIP_CALL( SCIPqueueCreate(&queue, nnodes, 2.0) );
1718 SCIP_CALL( SCIPpqueueCreate( &pqueue, nnodes, 2.0,
GNODECmpByDist) );
1722 for( i = 0; i < nnodes; i++ )
1727 assert(transgraph->
grad[i] > 0);
1731 gnodearr[k]->
dist = transgraph->
grad[i];
1734 if( SCIPisEQ(scip, transgraph->
cost[a], 0.0) )
1738 gnodearr[k]->
dist += transgraph->
grad[transgraph->
tail[a]] - 1;
1740 assert(gnodearr[k]->dist > 0);
1742 SCIP_CALL( SCIPpqueueInsert(pqueue, gnodearr[k++]) );
1752 for( i = 0; i < nedges; i++ )
1754 rescap[i] = transgraph->
cost[i];
1755 if( SCIPisZero(scip, rescap[i]) )
1762 while( SCIPpqueueNElems(pqueue) > 0 && !SCIPisStopped(scip) )
1765 gnodeact = (
GNODE*) SCIPpqueueRemove(pqueue);
1768 prio1 = gnodeact->
dist;
1774 while( !SCIPisStopped(scip) )
1776 assert(SCIPqueueIsEmpty(queue));
1781 score = transgraph->
grad[v];
1786 cutverts[ncutverts++] = v;
1787 SCIP_CALL( SCIPqueueInsert(queue, &(transgraph->
tail[transgraph->
outbeg[v]])) );
1792 for( i = norgcutverts; i < ncutverts; i++ )
1795 assert(transgraph->
mark[s]);
1799 SCIPqueueClear(queue);
1803 SCIP_CALL( SCIPqueueInsert(queue, &(transgraph->
tail[transgraph->
outbeg[s]])) );
1807 while( !SCIPqueueIsEmpty(queue) )
1809 pnode = (SCIPqueueRemove(queue));
1814 tail = transgraph->
tail[a];
1817 if( !transgraph->
mark[tail] )
1823 SCIPqueueClear(queue);
1827 score += transgraph->
grad[tail];
1829 cutverts[ncutverts++] = tail;
1830 SCIP_CALL( SCIPqueueInsert(queue, &(transgraph->
tail[a])) );
1833 else if( !transgraph->
mark[tail] )
1835 unsatarcs[nunsatarcs++] = a;
1846 for( i = 0; i < nunsatarcs; i++ )
1849 if( transgraph->
mark[transgraph->
tail[a]] )
1857 if( SCIPisLT(scip, rescap[a], min) )
1860 unsatarcs[i - shift] = a;
1864 assert(SCIPisLT(scip, min,
FARAWAY));
1865 nunsatarcs -= shift;
1868 assert(!transgraph->
mark[transgraph->
tail[unsatarcs[nunsatarcs-1]]]);
1870 currscore = score - (ncutverts - 1);
1871 norgcutverts = ncutverts;
1873 assert(SCIPisGE(scip, currscore, prio1));
1877 if( SCIPisLE(scip, (currscore - prio1) / prio1, maxdeviation) )
1883 SCIP_CONS* cons = NULL;
1893 SCIP_CALL( SCIPcreateConsLinear ( scip, &cons,
"da", 0, NULL, NULL,
1894 1.0, SCIPinfinity(scip),
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE) );
1896 SCIP_CALL( SCIPaddCons(scip, cons) );
1898 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, conshdlr,
"dualascentcut", 1.0, SCIPinfinity(scip),
FALSE,
FALSE,
TRUE) );
1899 SCIP_CALL( SCIPflushRowExtensions(scip, row) );
1900 SCIP_CALL( SCIPaddCut(scip, NULL, row,
FALSE, &infeasible) );
1901 SCIP_CALL( SCIPcacheRowExtensions(scip, row) );
1907 for( i = 0; i < nunsatarcs; i++ )
1913 if( addcuts && origedge[a] )
1915 assert(vars != NULL);
1916 assert(cons != NULL);
1918 if( g->
tail[a] == root && g->
head[a ] == v )
1921 SCIP_CALL( SCIPaddCoefLinear(scip, cons, vars[a], 1.0) );
1923 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[a], 1.0) );
1928 assert(SCIPisGE(scip, rescap[a], 0.0));
1930 if( SCIPisEQ(scip, rescap[a], 0.0) )
1933 if( !(transgraph->
mark[transgraph->
tail[a]]) )
1935 tail = transgraph->
tail[a];
1936 score += transgraph->
grad[tail];
1938 cutverts[ncutverts++] = tail;
1947 assert(vars != NULL);
1950 if( g->
head[i] == v )
1952 SCIP_CALL( SCIPaddCoefLinear(scip, cons, vars[i], 1.0) );
1957 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1959 SCIP_CALL( SCIPreleaseRow(scip, &row) );
1963 currscore = score - (ncutverts - 1);
1969 gnodeact->
dist = currscore;
1970 SCIP_CALL( SCIPpqueueInsert(pqueue, gnodeact) );
1975 for( i = 0; i < ncutverts; i++ )
1984 *objval = dualobj + offset;
1988 SCIPpqueueFree(&pqueue);
1989 SCIPqueueFree(&queue);
1991 for( i = nterms - 2; i >= 0; i-- )
1992 SCIPfreeBuffer(scip, &gnodearr[i]);
1994 SCIPfreeBufferArray(scip, &origedge);
1995 SCIPfreeBufferArray(scip, &unsatarcs);
1996 SCIPfreeBufferArray(scip, &cutverts);
1997 SCIPfreeBufferArray(scip, &gnodearr);
1998 SCIPfreeBufferArray(scip, &active);
1999 SCIPfreeBufferArray(scip, &sat);
2001 if( redcost == NULL )
2002 SCIPfreeBufferArray(scip, &rescap);
2035 assert(scip != NULL);
2049 SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
2050 for( i = 0; i < nterms - 1; i++ )
2052 SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) );
2055 SCIP_CALL( SCIPallocBufferArray(scip, &root, nterms) );
2056 SCIP_CALL( SCIPallocBufferArray(scip, °s, nterms) );
2057 SCIP_CALL( SCIPallocBufferArray(scip, &redcost, nedges) );
2058 SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
2059 SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
2060 SCIP_CALL( SCIPallocBufferArray(scip, &edgearrchar, nedges) );
2061 SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
2063 for( i = 0; i < nnodes; i++ )
2067 degs[k] = g->
grad[i];
2071 nruns = MIN(nruns, k);
2072 SCIPsortIntInt(degs, root, nterms);
2074 for( i = 0; i < nruns; i++ )
2076 r = root[k - i - 1];
2078 SCIP_CALL(
SCIPdualAscentStp(scip, g, redcost, &objval,
FALSE, gnodearr, edgearrint, nodearrint, r, 1, edgearrchar, nodearrchar) );
2080 if( SCIPisGT(scip, objval, max ) )
2088 SCIP_CALL(
SCIPdualAscentStp(scip, g, redcost, &objval,
TRUE, gnodearr, edgearrint, nodearrint, maxroot, 1, edgearrchar, nodearrchar) );
2090 SCIPfreeBufferArray(scip, &nodearrchar);
2091 SCIPfreeBufferArray(scip, &edgearrchar);
2092 SCIPfreeBufferArray(scip, &nodearrint);
2093 SCIPfreeBufferArray(scip, &edgearrint);
2094 SCIPfreeBufferArray(scip, &redcost);
2095 SCIPfreeBufferArray(scip, °s);
2096 SCIPfreeBufferArray(scip, &root);
2098 for( i = nterms - 2; i >= 0; i-- )
2099 SCIPfreeBuffer(scip, &gnodearr[i]);
2100 SCIPfreeBufferArray(scip, &gnodearr);
#define CONSHDLR_PROPFREQ
#define DEFAULT_CREEPFLOW
static SCIP_DECL_CONSINITSOL(consInitsolStp)
#define DEFAULT_NESTEDCUT
SCIP_RETCODE SCIPdualAscentStp(SCIP *scip, GRAPH *g, SCIP_Real *redcost, SCIP_Real *objval, SCIP_Bool addcuts, GNODE **gnodearrterms, int *edgearrint, int *nodearrint, int root, int nruns, char *edgearrchar, char *nodearrchar)
static void set_capacity(const GRAPH *g, const int layer, const SCIP_Bool creep_flow, const int flip, int *capa, const SCIP_Real *xval)
static SCIP_DECL_CONSENFOLP(consEnfolpStp)
static SCIP_DECL_CONSSEPALP(consSepalpStp)
Constraint handler for Steiner problems.
SCIP_RETCODE SCIPdualAscentAddCutsStp(SCIP *scip, GRAPH *g, int nruns)
SCIP_RETCODE SCIPvalidateStpSol(SCIP *, const GRAPH *, const double *, SCIP_Bool *)
SCIP_VAR ** SCIPprobdataGetVars(SCIP *scip)
SCIP_RETCODE graph_PcSapCopy(SCIP *, GRAPH *, GRAPH **, SCIP_Real *)
static SCIP_RETCODE sep_flow(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONSDATA *consdata, int maxcuts, int *ncuts)
Problem data for stp problem.
int SCIPprobdataGetNVars(SCIP *scip)
void graph_free(SCIP *, GRAPH *, SCIP_Bool)
#define DEFAULT_MAXROUNDS
static SCIP_DECL_CONSFREE(consFreeStp)
#define DEFAULT_DISJUNCTCUT
static SCIP_RETCODE sep_2cut(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONSDATA *consdata, int maxcuts, int *ncuts)
#define CONSHDLR_CHECKPRIORITY
static SCIP_DECL_CONSLOCK(consLockStp)
GRAPH * SCIPprobdataGetGraph(SCIP_PROBDATA *probdata)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyStp)
static int graph_next_term(int terms, int *term, const int *w)
SCIP_Real SCIPprobdataGetOffset(SCIP *scip)
#define CONSHDLR_SEPAPRIORITY
SCIP_RETCODE SCIPincludeConshdlrStp(SCIP *scip)
#define DEFAULT_MAXROUNDSROOT
#define STP_MAX_NODE_WEIGHT
#define CONSHDLR_DELAYPROP
int GNODECmpByDist(void *first_arg, void *second_arg)
static SCIP_DECL_CONSENFOPS(consEnfopsStp)
#define DEFAULT_MAXSEPACUTS
static SCIP_DECL_CONSCOPY(consCopyStp)
static SCIP_DECL_CONSTRANS(consTransStp)
#define DEFAULT_DAMAXDEVIATION
static SCIP_DECL_CONSDELETE(consDeleteStp)
Constraint data for Stp constraints.
#define CONSHDLR_EAGERFREQ
SCIP_RETCODE SCIPdualAscentPcStp(SCIP *scip, GRAPH *g, SCIP_Real *redcost, SCIP_Real *objval, SCIP_Bool addcuts, int nruns)
SCIP_RETCODE SCIPcreateConsStp(SCIP *scip, SCIP_CONS **cons, const char *name, GRAPH *graph)
includes various files containing graph methods used for Steiner problems
#define DEFAULT_MAXSEPACUTSROOT
static SCIP_DECL_CONSINITLP(consInitlpStp)
#define CONSHDLR_DELAYSEPA
#define CONSHDLR_SEPAFREQ
Constraint handler data for Stp constraint handler.
#define CONSHDLR_PROP_TIMING
SCIP_Real * SCIPprobdataGetXval(SCIP *scip, SCIP_SOL *sol)
#define CONSHDLR_ENFOPRIORITY
#define CONSHDLR_NEEDSCONS
static SCIP_DECL_CONSCHECK(consCheckStp)
static SCIP_DECL_CONSPROP(consPropStp)
void graph_path_exec(SCIP *, const GRAPH *, int, int, SCIP_Real *, PATH *)
static SCIP_RETCODE cut_add(SCIP *scip, SCIP_CONSHDLR *conshdlr, const GRAPH *g, const int layer, const SCIP_Real *xval, int *capa, const int updatecapa, int *ncuts, SCIP_Bool *success)
void graph_mincut_exec(GRAPH *, int, int, const int *, int *, int)