56#define BETTERWEIGHTFORDEMANDNODES
83#define SEPA_NAME "mcf"
84#define SEPA_DESC "multi-commodity-flow network cut separator"
85#define SEPA_PRIORITY -10000
87#define SEPA_MAXBOUNDDIST 0.0
88#define SEPA_USESSUBSCIP FALSE
89#define SEPA_DELAY FALSE
92#define DEFAULT_NCLUSTERS 5
93#define DEFAULT_MAXWEIGHTRANGE 1e+06
94#define DEFAULT_MAXTESTDELTA 20
95#define DEFAULT_TRYNEGSCALING FALSE
96#define DEFAULT_FIXINTEGRALRHS TRUE
97#define DEFAULT_DYNAMICCUTS TRUE
98#define DEFAULT_MODELTYPE 0
99#define DEFAULT_MAXSEPACUTS 100
100#define DEFAULT_MAXSEPACUTSROOT 200
101#define DEFAULT_MAXINCONSISTENCYRATIO 0.02
102#define DEFAULT_MAXARCINCONSISTENCYRATIO 0.5
103#define DEFAULT_CHECKCUTSHORECONNECTIVITY TRUE
104#define DEFAULT_SEPARATESINGLENODECUTS TRUE
105#define DEFAULT_SEPARATEFLOWCUTSET TRUE
106#define DEFAULT_SEPARATEKNAPSACK TRUE
109#define BOUNDSWITCH 0.5
110#define POSTPROCESS TRUE
111#define VARTYPEUSEVBDS 2
116#define MAXCOLS 2000000
117#define MAXAGGRLEN(nvars) (0.1*(nvars)+1000)
118#define MINCOLROWRATIO 0.01
119#define MAXCOLROWRATIO 100.0
120#define MAXFLOWVARFLOWROWRATIO 100.0
121#define MAXARCNODERATIO 100.0
123#define MAXFLOWCANDDENSITY 0.1
124#define MINCOMNODESFRACTION 0.5
127#define MAXCAPACITYSLACK 0.1
128#define UNCAPACITATEDARCSTRESHOLD 0.8
129#define HASHSIZE_NODEPAIRS 500
141#define MCFdebugMessage printf
145#define MCFdebugMessage while(FALSE) printf
219 unsigned char* flowrowsigns;
222 unsigned char* capacityrowsigns;
231 int nemptycommodities;
233 int commoditysignssize;
254 int capacityrowssize;
281 int* representatives;
293#define LHSPOSSIBLE 1u
294#define RHSPOSSIBLE 2u
295#define LHSASSIGNED 4u
296#define RHSASSIGNED 8u
299#define UNDIRECTED 64u
312 (*mcfnetwork)->nodeflowrows =
NULL;
313 (*mcfnetwork)->nodeflowscales =
NULL;
314 (*mcfnetwork)->nodeflowinverted =
NULL;
315 (*mcfnetwork)->arccapacityrows =
NULL;
316 (*mcfnetwork)->arccapacityscales =
NULL;
317 (*mcfnetwork)->arcsources =
NULL;
318 (*mcfnetwork)->arctargets =
NULL;
319 (*mcfnetwork)->colcommodity =
NULL;
320 (*mcfnetwork)->nnodes = 0;
321 (*mcfnetwork)->nuncapacitatedarcs = 0;
322 (*mcfnetwork)->narcs = 0;
323 (*mcfnetwork)->ncommodities = 0;
337 if( *mcfnetwork !=
NULL )
342 for( v = 0; v < (*mcfnetwork)->nnodes; v++ )
346 for( k = 0; k < (*mcfnetwork)->ncommodities; k++ )
348 if( (*mcfnetwork)->nodeflowrows[v][k] !=
NULL )
357 for(
a = 0;
a < (*mcfnetwork)->narcs;
a++ )
359 if( (*mcfnetwork)->arccapacityrows[
a] !=
NULL )
392 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
393 SCIP_Real* flowrowscalars = mcfdata->flowrowscalars;
394 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
395 int* flowcands = mcfdata->flowcands;
396 int nflowcands = mcfdata->nflowcands;
397 int ncommodities = mcfdata->ncommodities;
398 int* commoditysigns = mcfdata->commoditysigns;
399 int* colcommodity = mcfdata->colcommodity;
400 int* rowcommodity = mcfdata->rowcommodity;
401 int* rownodeid = mcfdata->rownodeid;
402 SCIP_ROW** capacityrows = mcfdata->capacityrows;
411 int ncompcommodities;
420 assert(2 <= ncompnodes && ncompnodes <= mcfdata->
nnodes);
421 assert(1 <= ncomparcs && ncomparcs <= mcfdata->
narcs);
426 for( v = 0; v < mcfdata->nnodes; v++ )
427 assert(compnodeid[v] == -1);
438 for( k = 0; k < ncommodities; k++ )
439 compcommodity[k] = -1;
446 for(
i = 0;
i < ncompnodes;
i++ )
454 ncompcommodities = 0;
455 for(
i = 0;
i < nflowcands;
i++ )
464 if( rv >= 0 && compnodeid[rv] >= 0 )
467 assert(0 <= k && k < ncommodities);
468 if( compcommodity[k] == -1 )
470 compcommodity[k] = ncompcommodities;
481 mcfnetwork->
nnodes = ncompnodes;
482 mcfnetwork->
narcs = ncomparcs;
490 for( v = 0; v < mcfnetwork->
nnodes; v++ )
508 for(
a = 0;
a < mcfnetwork->
narcs;
a++ )
518 for(
i = 0;
i < nflowcands;
i++ )
527 if( rv >= 0 && compnodeid[rv] >= 0 )
533 rk = rowcommodity[
r];
535 assert(0 <= rk && rk < ncommodities);
538 k = compcommodity[rk];
539 assert(0 <= k && k < mcfnetwork->ncommodities);
544 scale = flowrowscalars[
r];
547 if( commoditysigns[rk] == -1 )
555 for(
a = 0;
a < mcfnetwork->
narcs;
a++ )
565 globala = comparcs[
a];
566 capacityrow = capacityrows[globala];
571 if( capacityrow !=
NULL)
577 assert(mcfdata->rowarcid[
r] == globala);
595 for( j = 0; j < rowlen; j++ )
602 if( comdemands[k] != 0.0 )
617 for( j = 0; j < rowlen; j++ )
622 if( k >= 0 && comdemands[k] == 0.0 )
634 if( mcfdata->arcsources[globala] >= 0 )
636 assert(mcfdata->arcsources[globala] < mcfdata->nnodes);
637 assert(0 <= compnodeid[mcfdata->arcsources[globala]] && compnodeid[mcfdata->arcsources[globala]] < mcfnetwork->
nnodes);
638 mcfnetwork->
arcsources[
a] = compnodeid[mcfdata->arcsources[globala]];
640 if( mcfdata->arctargets[globala] >= 0 )
642 assert(mcfdata->arctargets[globala] < mcfdata->nnodes);
643 assert(0 <= compnodeid[mcfdata->arctargets[globala]] && compnodeid[mcfdata->arctargets[globala]] < mcfnetwork->
nnodes);
644 mcfnetwork->
arctargets[
a] = compnodeid[mcfdata->arctargets[globala]];
649 for(
c = 0;
c < ncols;
c++ )
659 for(
i = 0;
i < ncompnodes;
i++ )
661 assert(0 <= compnodes[
i] && compnodes[
i] < mcfdata->nnodes);
662 assert(compnodeid[compnodes[
i]] ==
i);
663 compnodeid[compnodes[
i]] = -1;
680 if( mcfnetwork ==
NULL )
687 for( v = 0; v < mcfnetwork->
nnodes; v++ )
706 for(
a = 0;
a < mcfnetwork->
narcs;
a++ )
722void printCommodities(
727 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
728 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
729 int ncommodities = mcfdata->ncommodities;
730 int* commoditysigns = mcfdata->commoditysigns;
731 int* colcommodity = mcfdata->colcommodity;
732 int* rowcommodity = mcfdata->rowcommodity;
733 int* colarcid = mcfdata->colarcid;
734 int* rownodeid = mcfdata->rownodeid;
735 int nnodes = mcfdata->nnodes;
736 SCIP_ROW** capacityrows = mcfdata->capacityrows;
752 for( k = 0; k < ncommodities; k++ )
756 for(
c = 0;
c < ncols;
c++ )
758 if( colcommodity[
c] == k )
761 for(
r = 0;
r < nrows;
r++ )
763 if( rowcommodity[
r] == k )
766 (flowrowsigns[
r] &
INVERTED) != 0 ? -1 : +1);
771 if( rownodeid !=
NULL )
775 for( v = 0; v <
nnodes; v++ )
778 for(
r = 0;
r < nrows;
r++ )
780 if( rownodeid[
r] == v )
783 (flowrowsigns[
r] &
INVERTED) != 0 ? -1 : +1);
789 assert(capacityrows !=
NULL || mcfdata->narcs == 0);
792 for(
a = 0;
a < mcfdata->narcs;
a++ )
795 if( capacityrows[
a] !=
NULL )
812 for(
c = 0;
c < ncols;
c++ )
814 if( colcommodity[
c] == -1 )
823 for(
r = 0;
r < nrows;
r++ )
843 if( rowscores[ind2] < rowscores[ind1] )
845 else if( rowscores[ind2] > rowscores[ind1] )
858 unsigned char* flowrowsigns;
878 flowrowsigns = mcfdata->flowrowsigns;
879 flowrowscalars = mcfdata->flowrowscalars;
880 flowrowscores = mcfdata->flowrowscores;
881 flowcands = mcfdata->flowcands;
883 assert(mcfdata->nflowcands == 0);
886 for(
r = 0;
r < nrows;
r++ )
911 absdualsol =
ABS(absdualsol);
914 flowrowscalars[
r] = 0.0;
915 flowrowscores[
r] = 0.0;
936 coef =
ABS(rowvals[0]);
943 for(
i = 0;
i < rowlen;
i++ )
951 hasposcoef = (hasposcoef || rowvals[
i] > 0.0);
952 hasnegcoef = (hasnegcoef || rowvals[
i] < 0.0);
986 flowrowscalars[
r] = 1.0/coef;
987 flowcands[mcfdata->nflowcands] =
r;
988 mcfdata->nflowcands++;
996 flowrowscores[
r] += 1000.0;
999 if( hasposcoef && hasnegcoef )
1000 flowrowscores[
r] += 500.0;
1007 if( ncontvars == rowlen || nimplintvars == rowlen )
1008 flowrowscores[
r] += 1000.0;
1009 else if( nintvars + nimplintvars == rowlen )
1010 flowrowscores[
r] += 500.0;
1011 else if( nbinvars == rowlen )
1012 flowrowscores[
r] += 100.0;
1016 flowrowscores[
r] += 10.0*rowlen/(rowlen+10.0);
1020 flowrowscores[
r] += 50.0;
1022 assert(flowrowscores[
r] > 0.0);
1025 maxdualflow =
MAX(maxdualflow, absdualsol);
1038 for(
i = 0;
i < mcfdata->nflowcands;
i++ )
1048 dualsol =
ABS(dualsol);
1051 assert(maxdualflow > 0.0);
1052 flowrowscores[
r] += dualsol/maxdualflow + 1.0;
1053 assert(flowrowscores[
r] > 0.0);
1058 SCIPsortInd(mcfdata->flowcands, compCands, (
void*)flowrowscores, mcfdata->nflowcands);
1060 MCFdebugMessage(
"flow conservation candidates [%d]\n", mcfdata->nflowcands);
1062 for(
r = 0;
r < mcfdata->nflowcands;
r++ )
1065 SCIPdebugMsg(
scip,
"%4d [score: %2g]: %s\n", mcfdata->flowcands[
r], flowrowscores[mcfdata->flowcands[
r]],
1080 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1081 int* colcommodity = mcfdata->colcommodity;
1082 int ncommodities = mcfdata->ncommodities;
1083 int nactivecommodities = mcfdata->ncommodities - mcfdata->nemptycommodities;
1086 unsigned char* capacityrowsigns;
1095 int maxcolspercommoditylimit;
1096 int *ncolspercommodity;
1097 int *maxcolspercommodity;
1107 capacityrowsigns = mcfdata->capacityrowsigns;
1108 capacityrowscores = mcfdata->capacityrowscores;
1109 capacitycands = mcfdata->capacitycands;
1111 assert(mcfdata->ncapacitycands == 0);
1121 maxcolspercommoditylimit = 2;
1124 maxcolspercommoditylimit = 1;
1127 maxcolspercommoditylimit = 2;
1130 SCIPerrorMessage(
"invalid parameter value %d for model type\n", modeltype);
1134 maxdualcapacity = 0.0;
1135 directedcandsscore = 0.0;
1136 undirectedcandsscore = 0.0;
1137 for(
r = 0;
r < nrows;
r++ )
1147 int nposcapacitycoefs;
1148 int nnegcapacitycoefs;
1150 int ncoveredcommodities;
1155 unsigned char rowsign;
1161 capacityrowsigns[
r] = 0;
1162 capacityrowscores[
r] = 0.0;
1181 absdualsol =
ABS(absdualsol);
1190 maxcolspercommodity[
r] = 0;
1195 nposcapacitycoefs = 0;
1196 nnegcapacitycoefs = 0;
1198 ncoveredcommodities = 0;
1200 sameabsflowcoef = 0.0;
1201 maxabscapacitycoef = 0.0;
1208 for(
i = 0;
i < rowlen;
i++ )
1218 k = colcommodity[
c];
1219 assert(-1 <= k && k < ncommodities);
1224 abscoef =
ABS(rowvals[
i]);
1225 if( sameflowcoef == 0.0 )
1226 sameflowcoef = rowvals[
i];
1229 if( sameabsflowcoef == 0.0 )
1230 sameabsflowcoef = abscoef;
1234 if( rowvals[
i] > 0.0 )
1240 if( ncolspercommodity[k] == 0 )
1241 ncoveredcommodities++;
1242 ncolspercommodity[k]++;
1243 maxcolspercommodity[
r] =
MAX(maxcolspercommodity[
r], ncolspercommodity[k]);
1245 if( ncolspercommodity[k] >= 2 )
1254 abscoef =
ABS(rowvals[
i]);
1255 if( abscoef > maxabscapacitycoef )
1256 maxabscapacitycoef = abscoef;
1259 if( rowvals[
i] > 0.0 )
1260 nposcapacitycoefs++;
1262 nnegcapacitycoefs++;
1272 if( rowsign != 0 && nposflowcoefs + nnegflowcoefs > 0 )
1276 capacityrowsigns[
r] |= rowsign;
1277 capacitycands[mcfdata->ncapacitycands] =
r;
1278 mcfdata->ncapacitycands++;
1281 capacityrowscores[
r] = 1.0;
1285 assert(ncoveredcommodities > 0);
1287 commodityexcessratio =
1288 ABS((nposflowcoefs + nnegflowcoefs)/(
SCIP_Real)ncoveredcommodities - maxcolspercommoditylimit);
1290 capacityrowscores[
r] += 1000.0 *
MAX(0.0, 2.0 - commodityexcessratio);
1297 if( (capacityrowsigns[
r] &
RHSPOSSIBLE) != 0 && nnegflowcoefs == 0 && nposcapacitycoefs == 0 && nnegcapacitycoefs > 0 )
1298 capacityrowscores[
r] += 1000.0;
1299 if( (capacityrowsigns[
r] &
LHSPOSSIBLE) != 0 && nposflowcoefs == 0 && nposcapacitycoefs > 0 && nnegcapacitycoefs == 0 )
1300 capacityrowscores[
r] += 1000.0;
1309 assert(nactivecommodities + 3 > 0);
1310 capacityrowscores[
r] += 2000.0 * ncoveredcommodities/(
SCIP_Real)(nactivecommodities + 3);
1314 capacityrowscores[
r] += 500.0;
1318 capacityrowscores[
r] += 250.0;
1322 capacityrowscores[
r] += 100.0;
1325 if( maxabscapacitycoef > 0.0 && !
SCIPisEQ(
scip, maxabscapacitycoef, 1.0) )
1326 capacityrowscores[
r] += 100.0;
1329 capacityrowscores[
r] += 20.0 *
MAX(nposflowcoefs, nnegflowcoefs)/
MAX(1.0,(
SCIP_Real)(nposflowcoefs + nnegflowcoefs));
1332 capacityrowscores[
r] += 10.0 *
MAX(nposcapacitycoefs, nnegcapacitycoefs)/(
SCIP_Real)(nposcapacitycoefs+nnegcapacitycoefs+1.0);
1336 capacityrowscores[
r] += 10.0;
1340 capacityrowscores[
r] += 10.0;
1342 assert(capacityrowscores[
r] > 0.0);
1343 SCIPdebugMsg(
scip,
"row <%s>: maxcolspercommodity=%d capacityrowsign=%d nposflowcoefs=%d nnegflowcoefs=%d nposcapacitycoefs=%d nnegcapacitycoefs=%d nbadcoefs=%d nactivecommodities=%d sameflowcoef=%g -> score=%g\n",
1344 SCIProwGetName(row), maxcolspercommodity[
r], capacityrowsigns[
r], nposflowcoefs, nnegflowcoefs, nposcapacitycoefs, nnegcapacitycoefs, nbadcoefs, nactivecommodities, sameflowcoef, capacityrowscores[
r]);
1347 maxdualcapacity =
MAX(maxdualcapacity, absdualsol);
1352 assert(maxcolspercommoditylimit == 2);
1354 undirectedcandsscore += capacityrowscores[
r];
1356 directedcandsscore += capacityrowscores[
r];
1361 SCIPdebugMsg(
scip,
"row <%s>: rowsign = %d nposflowcoefs = %d nnegflowcoefs = %d -> discard\n",
1369 if( directedcandsscore > undirectedcandsscore )
1374 MCFdebugMessage(
"detected model type: %s (%g directed score, %g undirected score)\n",
1382 for(
i = 0;
i < mcfdata->ncapacitycands;
i++ )
1384 r = capacitycands[
i];
1389 if( maxcolspercommodity[
r] <= maxcolspercommoditylimit )
1390 capacityrowscores[
r] -= 1000.0;
1396 mcfdata->modeltype = modeltype;
1404 for(
i = 0;
i < mcfdata->ncapacitycands;
i++ )
1408 r = capacitycands[
i];
1414 dualsol =
ABS(dualsol);
1417 assert(maxdualcapacity > 0.0);
1418 capacityrowscores[
r] +=
MAX(dualsol, 0.0)/maxdualcapacity;
1419 assert(capacityrowscores[
r] > 0.0);
1424 SCIPsortInd(mcfdata->capacitycands, compCands, (
void*)capacityrowscores, mcfdata->ncapacitycands);
1426 MCFdebugMessage(
"capacity candidates [%d]\n", mcfdata->ncapacitycands);
1428 for(
r = 0;
r < mcfdata->ncapacitycands;
r++ )
1431 capacityrowscores[mcfdata->capacitycands[
r]],
SCIProwGetName(rows[mcfdata->capacitycands[
r]]));
1451 assert(mcfdata->ncommodities <= mcfdata->commoditysignssize);
1452 if( mcfdata->ncommodities == mcfdata->commoditysignssize )
1454 mcfdata->commoditysignssize =
MAX(2*mcfdata->commoditysignssize, mcfdata->ncommodities+1);
1457 assert(mcfdata->ncommodities < mcfdata->commoditysignssize);
1460 SCIPdebugMsg(
scip,
"**** creating new commodity %d ****\n", mcfdata->ncommodities);
1461 mcfdata->commoditysigns[mcfdata->ncommodities] = 0;
1462 mcfdata->ncommodities++;
1477 assert(source != target );
1482 *newarcid = mcfdata->narcs;
1485 assert(mcfdata->narcs <= mcfdata->arcarraysize);
1486 if( mcfdata->narcs == mcfdata->arcarraysize )
1488 mcfdata->arcarraysize =
MAX(2*mcfdata->arcarraysize, mcfdata->narcs+1);
1494 assert(mcfdata->narcs < mcfdata->arcarraysize);
1497 if( mcfdata->capacityrowssize < mcfdata->arcarraysize )
1499 mcfdata->capacityrowssize = mcfdata->arcarraysize;
1502 assert(mcfdata->narcs < mcfdata->capacityrowssize);
1505 SCIPdebugMsg(
scip,
"**** creating new arc %d: %d -> %d ****\n", mcfdata->narcs, source, target);
1507 mcfdata->arcsources[*newarcid] = source;
1508 mcfdata->arctargets[*newarcid] = target;
1509 mcfdata->nextoutarcs[*newarcid] = mcfdata->firstoutarcs[source];
1510 mcfdata->firstoutarcs[source] = *newarcid;
1511 mcfdata->nextinarcs[*newarcid] = mcfdata->firstinarcs[target];
1512 mcfdata->firstinarcs[target] = *newarcid;
1513 mcfdata->capacityrows[*newarcid] =
NULL;
1526 unsigned char rowsign,
1531 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1532 SCIP_Bool* plusflow = mcfdata->plusflow;
1533 SCIP_Bool* minusflow = mcfdata->minusflow;
1534 int ncommodities = mcfdata->ncommodities;
1535 int* commoditysigns = mcfdata->commoditysigns;
1536 int* colcommodity = mcfdata->colcommodity;
1537 int* rowcommodity = mcfdata->rowcommodity;
1538 int* newcols = mcfdata->newcols;
1559 invertrow = ((rowsign &
INVERTED) != 0);
1562 assert(rowcommodity[
r] == -1);
1563 assert((flowrowsigns[
r] | rowsign) == flowrowsigns[
r]);
1571 commoditysigns[k] = +1;
1600 else if( rowlhs > 0.0 )
1617 flowrowsigns[
r] |= rowsign;
1619 SCIPdebugMsg(
scip,
"adding flow row %d <%s> with sign %+d%s to commodity %d [score:%g]\n",
1621 k, mcfdata->flowrowscores[
r]);
1625 rowcommodity[
r] = k;
1629 for(
i = 0;
i < rowlen;
i++ )
1638 if( colcommodity[
c] == -1 )
1643 colcommodity[
c] = k;
1644 newcols[mcfdata->nnewcols] =
c;
1645 mcfdata->nnewcols++;
1646 comcolids[*ncomcolids] =
c;
1652 val = rowscale * rowvals[
i];
1661 minusflow[
c] =
TRUE;
1678 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1679 SCIP_Bool* plusflow = mcfdata->plusflow;
1680 SCIP_Bool* minusflow = mcfdata->minusflow;
1684 assert(mcfdata->commoditysigns[k] == 0);
1689 for(
i = 0;
i < ncomrows;
i++ )
1693 unsigned char rowsign;
1700 assert(mcfdata->rowcommodity[
r] == k);
1704 rowsign = flowrowsigns[
r];
1716 for(
i = 0;
i < ncomcolids;
i++ )
1723 assert(mcfdata->colcommodity[
c] == k);
1726 plusflow[
c] = minusflow[
c];
1743 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1744 SCIP_Bool* plusflow = mcfdata->plusflow;
1745 SCIP_Bool* minusflow = mcfdata->minusflow;
1746 int ncommodities = mcfdata->ncommodities;
1747 int* colcommodity = mcfdata->colcommodity;
1748 int* rowcommodity = mcfdata->rowcommodity;
1752 assert(0 <= k && k < ncommodities);
1757 SCIPdebugMsg(
scip,
"deleting commodity %d (%d total commodities) with %d flow rows\n", k, ncommodities, nrows);
1762 for( n = 0; n < nrows; n++ )
1782 rowcommodity[
r] = -1;
1785 for(
i = 0;
i < rowlen;
i++ )
1793 assert(colcommodity[
c] == k || colcommodity[
c] == -1);
1794 if(colcommodity[
c] == k)
1796 colcommodity[
c] = -1;
1809 if( k == ncommodities-1 )
1810 mcfdata->ncommodities--;
1812 mcfdata->nemptycommodities++;
1822 unsigned char* rowsign,
1826 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1827 SCIP_Bool* plusflow = mcfdata->plusflow;
1828 SCIP_Bool* minusflow = mcfdata->minusflow;
1829 int* colcommodity = mcfdata->colcommodity;
1830 int* rowcommodity = mcfdata->rowcommodity;
1831 int* commoditysigns = mcfdata->commoditysigns;
1836 unsigned char flowrowsign;
1837 unsigned char invflowrowsign;
1844 *invertcommodity =
FALSE;
1850 if( rowcommodity[
r] != -1 )
1854 flowrowsign = flowrowsigns[
r];
1860 invflowrowsign = flowrowsign;
1866 for( j = 0; j < rowlen && (flowrowsign != 0 || invflowrowsign != 0); j++ )
1874 if( colcommodity[rowc] == k )
1877 if( plusflow[rowc] )
1880 if( rowvals[j] > 0.0 )
1891 if( minusflow[rowc] )
1894 if( rowvals[j] > 0.0 )
1906 else if( colcommodity[rowc] != -1 )
1914 if( flowrowsign != 0 )
1917 *rowsign = flowrowsign;
1918 *invertcommodity =
FALSE;
1920 else if( invflowrowsign != 0 )
1926 if( commoditysigns ==
NULL || commoditysigns[k] == 0 )
1929 *rowsign = invflowrowsign;
1930 *invertcommodity =
TRUE;
1935 *rowsign = (invflowrowsign |
INVERTED);
1936 *invertcommodity =
FALSE;
1953 unsigned char* nextrowsign,
1957 SCIP_Real* flowrowscores = mcfdata->flowrowscores;
1958 SCIP_Bool* plusflow = mcfdata->plusflow;
1959 SCIP_Bool* minusflow = mcfdata->minusflow;
1960 int* newcols = mcfdata->newcols;
1961 int ncommodities = mcfdata->ncommodities;
1971 *nextinvertcommodity =
FALSE;
1979 while( mcfdata->nnewcols > 0 )
1985 unsigned char bestrowsign;
1992 c = newcols[mcfdata->nnewcols-1];
1993 mcfdata->nnewcols--;
1997 assert(plusflow[
c] || minusflow[
c]);
1998 if( plusflow[
c] && minusflow[
c] )
2004 bestinvertcommodity =
FALSE;
2009 for(
i = 0;
i < collen;
i++ )
2012 unsigned char flowrowsign;
2021 if( flowrowsign != 0 )
2028 score = flowrowscores[
r];
2035 if( (flowrowsign &
INVERTED) != 0 )
2038 if( score > bestscore )
2041 bestrowsign = flowrowsign;
2042 bestinvertcommodity = invertcommodity;
2052 if( bestrow !=
NULL )
2055 assert(bestrowsign != 0);
2057 *nextrowsign = bestrowsign;
2058 *nextinvertcommodity = bestinvertcommodity;
2073 int* flowcands = mcfdata->flowcands;
2109 plusflow = mcfdata->plusflow;
2110 minusflow = mcfdata->minusflow;
2111 colcommodity = mcfdata->colcommodity;
2112 rowcommodity = mcfdata->rowcommodity;
2124 for(
c = 0;
c < ncols;
c++ )
2125 colcommodity[
c] = -1;
2126 for(
r = 0;
r < nrows;
r++ )
2127 rowcommodity[
r] = -1;
2129 assert(flowcands !=
NULL || mcfdata->nflowcands == 0);
2140 for(
i = 0;
i < mcfdata->nflowcands;
i++ )
2143 unsigned char newrowsign;
2153 getFlowrowFit(
scip, mcfdata, newrow, mcfdata->ncommodities, &newrowsign, &newinvertcommodity);
2154 if( newrowsign == 0 )
2156 assert(!newinvertcommodity);
2160 SCIPdebugMsg(
scip,
" -------------------start new commodity %d--------------------- \n", mcfdata->ncommodities );
2169 if( newinvertcommodity )
2175 comrows[
nnodes] = newrow;
2182 while( newrow !=
NULL );
2184 ncomnodes[mcfdata->ncommodities-1] =
nnodes;
2186 nflowvars += ncomcolids;
2187 SCIPdebugMsg(
scip,
" -> finished commodity %d: identified %d nodes, maxnnodes=%d\n", mcfdata->ncommodities-1,
nnodes, maxnnodes);
2196 nflowrows -= ndelflowrows;
2197 nflowvars -= ndelflowvars;
2203 for( k = 0; k < mcfdata->ncommodities; k++ )
2215 for(
i = 0;
i < mcfdata->nflowcands;
i++ )
2219 if( rowcommodity[
r] == k )
2224 if(
nnodes == ncomnodes[k] )
2231 nflowrows -= ndelflowrows;
2232 nflowvars -= ndelflowvars;
2243 MCFdebugMessage(
"identified %d commodities (%d empty) with a maximum of %d nodes and %d flowrows, %d flowvars \n",
2244 mcfdata->ncommodities, mcfdata->nemptycommodities, maxnnodes, nflowrows, nflowvars);
2265 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
2266 int* colcommodity = mcfdata->colcommodity;
2268 unsigned char* flowrowsigns = mcfdata->capacityrowsigns;
2269 int* rowcommodity = mcfdata->rowcommodity;
2285 SCIP_Real* capacityrowscores = mcfdata->capacityrowscores;
2287 int *capacitycands = mcfdata->capacitycands;
2288 int ncapacitycands = mcfdata->ncapacitycands;
2290 assert(mcfdata->narcs == 0);
2291 assert(capacitycands !=
NULL || ncapacitycands == 0);
2300 colarcid = mcfdata->colarcid;
2301 rowarcid = mcfdata->rowarcid;
2304 for(
c = 0;
c < ncols;
c++ )
2306 for(
r = 0;
r < nrows;
r++ )
2310 for(
i = 0;
i < ncapacitycands;
i++ )
2315 int nassignedflowvars;
2316 int nunassignedflowvars;
2320 r = capacitycands[
i];
2322 capacityrow = rows[
r];
2332 assert(capacityrowscores[
r] > 0.0);
2339 assert( rowcommodity[
r] == -1 );
2345 nassignedflowvars = 0;
2346 nunassignedflowvars = 0;
2347 for( k = 0; k < rowlen; k++ )
2353 assert(-1 <= colcommodity[
c] && colcommodity[
c] < mcfdata->ncommodities);
2354 assert(-1 <= colarcid[
c] && colarcid[
c] < mcfdata->narcs);
2357 if( colcommodity[
c] == -1 )
2361 if( colarcid[
c] >= 0 )
2362 nassignedflowvars++;
2364 nunassignedflowvars++;
2371 if( nunassignedflowvars == 0 || nassignedflowvars >= nunassignedflowvars * 2 )
2373 SCIPdebugMsg(
scip,
"discarding capacity candidate row %d <%s> [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2374 r,
SCIProwGetName(capacityrow), mcfdata->capacityrowscores[
r], nassignedflowvars, nunassignedflowvars);
2380 assert(mcfdata->narcs <= mcfdata->capacityrowssize);
2381 if( mcfdata->narcs == mcfdata->capacityrowssize )
2383 mcfdata->capacityrowssize =
MAX(2*mcfdata->capacityrowssize, mcfdata->narcs+1);
2386 assert(mcfdata->narcs < mcfdata->capacityrowssize);
2387 assert(mcfdata->narcs < nrows);
2389 mcfdata->capacityrows[mcfdata->narcs] = capacityrow;
2393 rowarcid[
r] = mcfdata->narcs;
2404 SCIPdebugMsg(
scip,
"assigning capacity row %d <%s> with sign %+d to arc %d [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2406 mcfdata->capacityrowscores[
r], nassignedflowvars, nunassignedflowvars);
2409 for( k = 0; k < rowlen; k++ )
2412 assert(0 <= rowc && rowc < ncols);
2418 if( colcommodity[rowc] >= 0 && colarcid[rowc] == -1 )
2419 colarcid[rowc] = mcfdata->narcs;
2438 int* colcommodity = mcfdata->colcommodity;
2439 int* colarcid = mcfdata->colarcid;
2440 int* newcols = mcfdata->newcols;
2441 SCIP_ROW** capacityrows = mcfdata->capacityrows;
2442 SCIP_Bool* colisincident = mcfdata->colisincident;
2457 mcfdata->nnewcols = 0;
2459 for(
i = 0;
i < rowlen;
i++ )
2471 arcid = colarcid[
c];
2481 for( j = 0; j < capacityrowlen; j++ )
2489 if( colcommodity[caprowc] == -1 )
2491 assert(colarcid[caprowc] == -1);
2494 assert(colarcid[caprowc] <= arcid);
2497 if( colcommodity[caprowc] == basecommodity )
2501 if( !colisincident[caprowc] )
2504 colisincident[caprowc] =
TRUE;
2505 newcols[mcfdata->nnewcols] = caprowc;
2506 mcfdata->nnewcols++;
2520 int* basearcpattern,
2529 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2530 int* commoditysigns = mcfdata->commoditysigns;
2531 int narcs = mcfdata->narcs;
2532 int* rowcommodity = mcfdata->rowcommodity;
2533 int* colarcid = mcfdata->colarcid;
2534 int* arcpattern = mcfdata->zeroarcarray;
2547 int* overlappingarcs;
2548 int noverlappingarcs;
2553 *invertcommodity =
FALSE;
2566 rowcom = rowcommodity[
r];
2567 assert(0 <= rowcom && rowcom < mcfdata->ncommodities);
2568 rowcomsign = commoditysigns[rowcom];
2569 assert(-1 <= rowcomsign && rowcomsign <= +1);
2574 incompatible =
FALSE;
2575 noverlappingarcs = 0;
2579 for(
i = 0;
i < rowlen;
i++ )
2589 valsign = (rowvals[
i] > 0.0 ? +1 : -1);
2595 arcid = colarcid[
c];
2607 if( basearcpattern[arcid] != 0 )
2614 if( ( valsign * basearcpattern[arcid] ) > 0 )
2619 if( rowcomsign == 0 )
2622 rowcomsign = validcomsign;
2624 else if( rowcomsign != validcomsign )
2627 incompatible =
TRUE;
2638 if( arcpattern[arcid] == 0 )
2640 overlappingarcs[noverlappingarcs] = arcid;
2643 arcpattern[arcid] += valsign;
2649 for(
i = 0;
i < noverlappingarcs;
i++ )
2655 arcid = overlappingarcs[
i];
2659 basenum =
ABS(basearcpattern[arcid]);
2660 arcnum =
ABS(arcpattern[arcid]);
2664 if( basenum > arcnum )
2665 overlap += arcnum/basenum;
2667 overlap += basenum/arcnum;
2669 arcpattern[arcid] = 0;
2673 if( !incompatible && overlap > 0.0 )
2676 int rowarcs = rowlen - nposuncap - nneguncap;
2677 int baserowarcs = baserowlen - basenposuncap - basenneguncap;
2681 assert(noverlappingarcs >= 1);
2683 *invertcommodity = (rowcomsign == -1);
2687 if( noverlappingarcs >= 2 )
2690 assert(rowarcs >= 0 && baserowarcs >= 0 );
2693 *score = overlap - (rowarcs + baserowarcs - 2.0 * overlap)/(2.0 * ncols + 1.0);
2695 *score = overlap - (rowarcs + baserowarcs - 4.0 * overlap)/(2.0 * ncols + 1.0);
2698 if(*invertcommodity)
2699 *score += 1.0 - (
ABS(nneguncap - basenposuncap) +
ABS(nposuncap - basenneguncap))/(2.0 * ncols + 1.0);
2701 *score += 1.0 - (
ABS(nposuncap - basenposuncap) +
ABS(nneguncap - basenneguncap))/(2.0 * ncols + 1.0);
2703 *score =
MAX(*score, 1e-6);
2706 SCIPdebugMsg(
scip,
" -> node similarity: row <%s>: incompatible=%u overlap=%g rowlen=%d baserowlen=%d score=%g\n",
2707 SCIProwGetName(row), incompatible, overlap, rowlen, baserowlen, *score);
2722 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2723 int ncommodities = mcfdata->ncommodities;
2724 int* commoditysigns = mcfdata->commoditysigns;
2725 int narcs = mcfdata->narcs;
2726 int* flowcands = mcfdata->flowcands;
2727 int nflowcands = mcfdata->nflowcands;
2728 int* rowcommodity = mcfdata->rowcommodity;
2729 int* colarcid = mcfdata->colarcid;
2730 int* newcols = mcfdata->newcols;
2751 assert(mcfdata->nnodes == 0);
2763 rownodeid = mcfdata->rownodeid;
2764 colisincident = mcfdata->colisincident;
2774 for(
r = 0;
r < nrows;
r++ )
2776 for(
c = 0;
c < ncols;
c++ )
2777 colisincident[
c] =
FALSE;
2779 assert(flowcands !=
NULL || nflowcands == 0);
2782 for( n = 0; n < nflowcands; n++ )
2797 basecommodity = rowcommodity[
r];
2798 if( basecommodity == -1 )
2801 assert(mcfdata->rowarcid[
r] == -1);
2804 if( rownodeid[
r] >= 0 )
2808 SCIPdebugMsg(
scip,
"assigning row %d <%s> of commodity %d to node %d [score: %g]\n",
2809 r,
SCIProwGetName(rows[
r]), basecommodity, mcfdata->nnodes, mcfdata->flowrowscores[
r]);
2810 rownodeid[
r] = mcfdata->nnodes;
2818 if(ncommodities == 1)
2838 if( commoditysigns[basecommodity] == -1 )
2841 for(
i = 0;
i < rowlen;
i++ )
2847 arcid = colarcid[
c];
2852 arcpattern[arcid]++;
2854 arcpattern[arcid]--;
2867 for(
i = 0;
i < ncommodities;
i++ )
2869 bestflowrows[
i] =
NULL;
2870 bestscores[
i] = 0.0;
2883 for(
i = 0;
i < mcfdata->nnewcols;
i++ )
2892 assert(mcfdata->colcommodity[
c] >= 0);
2893 assert(mcfdata->colcommodity[
c] != basecommodity);
2897 colisincident[
c] =
FALSE;
2903 for( j = 0; j < collen; j++ )
2911 assert(0 <= colr && colr < nrows);
2914 if( rowprocessed[colr] )
2916 rowprocessed[colr] =
TRUE;
2919 rowcom = rowcommodity[colr];
2920 assert(rowcom != basecommodity);
2924 assert(rowcom == mcfdata->colcommodity[
c]);
2926 assert(mcfdata->rowarcid[colr] == -1);
2929 if( rownodeid[colr] >= 0 )
2934 nposuncap, nneguncap, colrows[j], &score, &invertcommodity) );
2937 if( score > bestscores[rowcom] )
2939 bestflowrows[rowcom] = colrows[j];
2940 bestscores[rowcom] = score;
2941 bestinverted[rowcom] = invertcommodity;
2948 for(
i = 0;
i < ncommodities;
i++ )
2952 if( bestflowrows[
i] ==
NULL )
2956 assert(0 <= comr && comr < nrows);
2957 assert(rowcommodity[comr] ==
i);
2959 assert(rownodeid[comr] == -1);
2960 assert(mcfdata->nnodes >= 1);
2962 SCIPdebugMsg(
scip,
" -> assigning row %d <%s> of commodity %d to node %d [invert:%u]\n",
2964 rownodeid[comr] = mcfdata->nnodes-1;
2967 if( bestinverted[
i] )
2969 assert(commoditysigns[
i] != +1);
2970 commoditysigns[
i] = -1;
2974 assert(commoditysigns[
i] != -1);
2975 commoditysigns[
i] = +1;
2997 int* commoditysigns = mcfdata->commoditysigns;
3000 for( k = 0; k < mcfdata->ncommodities; k++ )
3002 if( commoditysigns[k] == 0 )
3003 commoditysigns[k] = +1;
3018 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3019 int* commoditysigns = mcfdata->commoditysigns;
3020 int* rowcommodity = mcfdata->rowcommodity;
3021 int* rownodeid = mcfdata->rownodeid;
3022 int* colsources = mcfdata->colsources;
3023 int* coltargets = mcfdata->coltargets;
3040 if( colsources[
c] >= -1 )
3043 *sourcenode = colsources[
c];
3044 *targetnode = coltargets[
c];
3055 for(
i = 0;
i < collen;
i++ )
3062 if( rownodeid[
r] >= 0 )
3069 k = rowcommodity[
r];
3071 assert(0 <= k && k < mcfdata->ncommodities);
3080 if( commoditysigns[k] == -1 )
3084 if( ( scale * colvals[
i] ) > 0.0 )
3086 assert(*sourcenode == -1);
3088 if( *targetnode >= 0 )
3093 assert(*targetnode == -1);
3095 if( *sourcenode >= 0 )
3102 colsources[
c] = *sourcenode;
3103 coltargets[
c] = *targetnode;
3114 int* flowcands = mcfdata->flowcands;
3115 int nflowcands = mcfdata->nflowcands;
3117 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3118 int* colcommodity = mcfdata->colcommodity;
3119 int* rowcommodity = mcfdata->rowcommodity;
3121 int* rownodeid = mcfdata->rownodeid;
3122 int* colarcid = mcfdata->colarcid;
3123 int nnodes = mcfdata->nnodes;
3124 int ncommodities = mcfdata->ncommodities;
3131 int* sortedflowcands;
3132 int* sortedflowcandnodeid;
3145 assert(mcfdata->nemptycommodities == 0);
3146 assert(ncommodities >= 0);
3150 if( ncommodities == 0 || nflowcands == 0 ||
nnodes == 0 )
3171 for( n = 0; n < nflowcands; n++ )
3173 sortedflowcands[n] = flowcands[n];
3174 sortedflowcandnodeid[n] = rownodeid[flowcands[n]];
3178 SCIPsortIntInt(sortedflowcandnodeid, sortedflowcands, nflowcands);
3179 assert(sortedflowcandnodeid[0] <= 0);
3180 assert(sortedflowcandnodeid[nflowcands-1] ==
nnodes-1);
3183 for( v = 0; v <
nnodes; v++ )
3199 for( n = 0; n < nflowcands; n++ )
3201 if( sortedflowcandnodeid[n] >= 0 )
3204 assert(rowcommodity[sortedflowcands[n]] == -1);
3207 assert(sortedflowcandnodeid[n] == 0);
3212 for( v = 0; n < nflowcands; v++ )
3218 assert(rowcommodity[sortedflowcands[n]] >= 0);
3219 assert(rownodeid[sortedflowcands[n]] == sortedflowcandnodeid[n]);
3220 assert(sortedflowcandnodeid[n] == v);
3227 for( ; n < nflowcands && sortedflowcandnodeid[n] == v; n++ )
3234 r = sortedflowcands[n];
3236 assert(mcfdata->rowarcid[
r] == -1);
3241 for(
i = 0;
i < rowlen;
i++ )
3252 arcid = colarcid[
c];
3254 assert(rowcommodity[
r] == colcommodity[
c]);
3264 else if( arcid == -1 )
3276 assert(s == v || t == v);
3287 if( s < 0 || t < 0 )
3295 assert(ninccols < ncols);
3296 inccols[ninccols] =
c;
3312 if( sourcecount[u] + targetcount[u] == 1 )
3315 adjnodes[nadjnodes] = u;
3323 for( l = 0; l < nadjnodes; l++ )
3329 assert(sourcecount[u] > 0 || targetcount[u] > 0);
3334 if( sourcecount[u] >= arcsthreshold )
3344 for( m = 0; m < ninccols; m++ )
3355 assert(s == v || t == v);
3360 colarcid[
c] = arcid;
3363 inccols[m] = inccols[ninccols-1];
3371 if( targetcount[u] >= arcsthreshold )
3381 for( m = 0; m < ninccols; m++ )
3392 assert(s == v || t == v);
3397 colarcid[
c] = arcid;
3400 inccols[m] = inccols[ninccols-1];
3409 for( l = 0; l < nadjnodes; l++ )
3417 for( l = 0; l < ninccols; l++ )
3419 assert(colarcid[inccols[l]] == -1);
3420 colarcid[inccols[l]] = -2;
3429 for( n = 0; n < ncols; n++ )
3430 assert(colarcid[n] >= -1);
3441 MCFdebugMessage(
"network after finding uncapacitated arcs has %d nodes, %d arcs, and %d commodities\n",
3442 mcfdata->nnodes, mcfdata->narcs, mcfdata->ncommodities);
3454 int* flowcands = mcfdata->flowcands;
3455 int nflowcands = mcfdata->nflowcands;
3456 int* colcommodity = mcfdata->colcommodity;
3457 int* rowcommodity = mcfdata->rowcommodity;
3458 int* colarcid = mcfdata->colarcid;
3459 int* rowarcid = mcfdata->rowarcid;
3460 int* rownodeid = mcfdata->rownodeid;
3461 int ncommodities = mcfdata->ncommodities;
3462 int* commoditysigns = mcfdata->commoditysigns;
3463 int narcs = mcfdata->narcs;
3464 int nnodes = mcfdata->nnodes;
3465 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3477 int nnodesthreshold;
3478 int newncommodities;
3491 permsize = ncommodities;
3503 assert(flowcands !=
NULL || nflowcands == 0);
3506 for(
i = 0;
i < nflowcands;
i++ )
3513 assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3514 if( rowcommodity[
r] >= 0 )
3516 assert(rowcommodity[
r] < ncommodities);
3517 nnodespercom[rowcommodity[
r]]++;
3540 for( j = 0; j < rowlen; j++ )
3546 if( colcommodity[
c] >= 0 && colarcid[
c] ==
a )
3548 assert(colcommodity[
c] < ncommodities);
3549 arcisincom[colcommodity[
c]] =
TRUE;
3554 for( k = 0; k < ncommodities; k++ )
3563 for( k = 0; k < ncommodities; k++ )
3564 maxnnodes =
MAX(maxnnodes, nnodespercom[k]);
3575 newncommodities = 0;
3576 for( k = 0; k < ncommodities; k++ )
3578 SCIPdebugMsg(
scip,
" -> commodity %d: %d nodes, %d arcs\n", k, nnodespercom[k], narcspercom[k]);
3581 if( nnodespercom[k] >= nnodesthreshold && narcspercom[k] >= 1 )
3583 assert(newncommodities <= k);
3584 perm[k] = newncommodities;
3585 commoditysigns[newncommodities] = commoditysigns[k];
3592 if( newncommodities < ncommodities )
3601 SCIPdebugMsg(
scip,
" -> discarding %d of %d commodities\n", ncommodities - newncommodities, ncommodities);
3609 for(
c = 0;
c < ncols;
c++ )
3611 if( colcommodity[
c] >= 0 )
3614 assert(colcommodity[
c] < mcfdata->ncommodities);
3615 colcommodity[
c] = perm[colcommodity[
c]];
3616 assert(colcommodity[
c] < newncommodities);
3617 if( colcommodity[
c] == -1 )
3622 else if( colarcid[
c] >= 0 )
3623 arcisused[colarcid[
c]] =
TRUE;
3626 for(
i = 0;
i < nflowcands;
i++ )
3633 assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3634 if( rowcommodity[
r] >= 0 )
3637 assert(rowcommodity[
r] < mcfdata->ncommodities);
3638 rowcommodity[
r] = perm[rowcommodity[
r]];
3639 assert(rowcommodity[
r] < newncommodities);
3640 if( rowcommodity[
r] == -1 )
3646 nodeisused[rownodeid[
r]] =
TRUE;
3650 mcfdata->ncommodities = newncommodities;
3651 ncommodities = newncommodities;
3665 capacityrows[newnarcs] = capacityrows[
a];
3676 rowarcid[
r] = perm[
a];
3680 if( newnarcs <
narcs )
3684 for(
c = 0;
c < ncols;
c++ )
3686 if( colarcid[
c] >= 0 )
3688 colarcid[
c] = perm[colarcid[
c]];
3692 mcfdata->narcs = newnarcs;
3708 for( v = 0; v <
nnodes; v++ )
3713 perm[v] = newnnodes;
3725 for(
i = 0;
i < nflowcands;
i++ )
3732 assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3733 if( rowcommodity[
r] >= 0 )
3735 assert(rowcommodity[
r] < ncommodities);
3736 rownodeid[
r] = perm[rownodeid[
r]];
3740 mcfdata->nnodes = newnnodes;
3752 mcfdata->nemptycommodities = 0;
3774 int* colarcid = mcfdata->colarcid;
3775 int* colcommodity = mcfdata->colcommodity;
3776 int narcs = mcfdata->narcs;
3777 int nnodes = mcfdata->nnodes;
3778 int ncommodities = mcfdata->ncommodities;
3779 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3794 int *flowvarspercom;
3821 arcsources = mcfdata->arcsources;
3822 arctargets = mcfdata->arctargets;
3823 colsources = mcfdata->colsources;
3824 coltargets = mcfdata->coltargets;
3825 firstoutarcs = mcfdata->firstoutarcs;
3826 firstinarcs = mcfdata->firstinarcs;
3827 nextoutarcs = mcfdata->nextoutarcs;
3828 nextinarcs = mcfdata->nextinarcs;
3830 mcfdata->arcarraysize =
narcs;
3833 for(
c = 0;
c < ncols;
c++ )
3840 for( v = 0; v <
nnodes; v++ )
3842 firstoutarcs[v] = -1;
3843 firstinarcs[v] = -1;
3847 nextoutarcs[
a] = -1;
3861 mcfdata->ninconsistencies = 0.0;
3892 assert(sourcenodecnt[
i] == 0);
3893 assert(targetnodecnt[
i] == 0);
3904 for(
i = 0;
i < rowlen;
i++ )
3908 if( colarcid[
c] >= 0 )
3910 int k = colcommodity[
c];
3911 assert (0 <= k && k < ncommodities);
3912 flowvarspercom[k]++;
3913 if( !comtouched[k] )
3916 comtouched[k] =
TRUE;
3922 if( ntouchedcoms == 0 )
3924 capacityrows[
a] =
NULL;
3932 totalsourcecnt = 0.0;
3933 totaltargetcnt = 0.0;
3935 for(
i = 0;
i < rowlen;
i++ )
3939 if( colarcid[
c] >= 0 )
3941 int k = colcommodity[
c];
3946 assert (0 <= k && k < ncommodities);
3948 assert (flowvarspercom[k] >= 1);
3954 weight = 1.0/flowvarspercom[k];
3957 if( sourcenodecnt[sourcev] == 0.0 && targetnodecnt[sourcev] == 0.0 )
3959 touchednodes[ntouchednodes] = sourcev;
3962 sourcenodecnt[sourcev] += weight;
3963 totalsourcecnt += weight;
3967 if( sourcenodecnt[targetv] == 0.0 && targetnodecnt[targetv] == 0.0 )
3969 touchednodes[ntouchednodes] = targetv;
3972 targetnodecnt[targetv] += weight;
3973 totaltargetcnt += weight;
3975 if( sourcev >= 0 || targetv >= 0 )
3976 totalnodecnt += weight;
3983 bestsourcecnt = 0.0;
3984 besttargetcnt = 0.0;
3985 for(
i = 0;
i < ntouchednodes;
i++ )
3987 v = touchednodes[
i];
3993 if( sourcenodecnt[v] >= targetnodecnt[v] )
3995 if( sourcenodecnt[v] > bestsourcecnt )
3998 bestsourcecnt = sourcenodecnt[v];
4003 if( targetnodecnt[v] > besttargetcnt )
4006 besttargetcnt = targetnodecnt[v];
4012 SCIP_Real nodecnt = sourcenodecnt[v] + targetnodecnt[v];
4016 if( nodecnt > bestsourcecnt )
4018 besttargetv = bestsourcev;
4019 besttargetcnt = bestsourcecnt;
4021 bestsourcecnt = nodecnt;
4023 else if( nodecnt > besttargetcnt )
4026 besttargetcnt = nodecnt;
4031 sourcenodecnt[v] = 0;
4032 targetnodecnt[v] = 0;
4038 totalsourcecnt = totalnodecnt;
4039 totaltargetcnt = totalnodecnt;
4043 nsourceinconsistencies = (totalsourcecnt - bestsourcecnt)/ntouchedcoms;
4044 ntargetinconsistencies = (totaltargetcnt - besttargetcnt)/ntouchedcoms;
4047 if( nsourceinconsistencies > maxarcinconsistencyratio )
4053 if( ntargetinconsistencies > maxarcinconsistencyratio )
4060 assert(bestsourcev == -1 || bestsourcev != besttargetv);
4061 arcsources[
a] = bestsourcev;
4062 arctargets[
a] = besttargetv;
4063 SCIPdebugMsg(
scip,
"arc %d: %d -> %d (len=%d, sourcecnt=%g/%g, targetcnt=%g/%g, %g/%g inconsistencies)\n",
4064 a, bestsourcev, besttargetv, rowlen,
4065 bestsourcecnt, totalsourcecnt, besttargetcnt, totaltargetcnt,
4066 nsourceinconsistencies, ntargetinconsistencies);
4069 if( bestsourcev != -1 )
4071 nextoutarcs[
a] = firstoutarcs[bestsourcev];
4072 firstoutarcs[bestsourcev] =
a;
4074 if( besttargetv != -1 )
4076 nextinarcs[
a] = firstinarcs[besttargetv];
4077 firstinarcs[besttargetv] =
a;
4081 mcfdata->ninconsistencies += 0.5*(nsourceinconsistencies + ntargetinconsistencies);
4083 if( mcfdata->ninconsistencies > maxninconsistencies )
4085 MCFdebugMessage(
" -> reached maximal number of inconsistencies: %g > %g\n",
4086 mcfdata->ninconsistencies, maxninconsistencies);
4092 if( mcfdata->ninconsistencies <= maxninconsistencies &&
narcs > 0 && ncommodities > 0 )
4097 MCFdebugMessage(
"extracted network has %g inconsistencies (ratio %g) -> separating with effort %d\n",
4098 mcfdata->ninconsistencies, mcfdata->ninconsistencies/(
SCIP_Real)
narcs, *effortlevel);
4127 int* arcsources = mcfdata->arcsources;
4128 int* arctargets = mcfdata->arctargets;
4129 int* firstoutarcs = mcfdata->firstoutarcs;
4130 int* firstinarcs = mcfdata->firstinarcs;
4131 int* nextoutarcs = mcfdata->nextoutarcs;
4132 int* nextinarcs = mcfdata->nextinarcs;
4133 int nnodes = mcfdata->nnodes;
4153 stacknodes[0] = startv;
4155 nodevisited[startv] =
ONSTACK;
4158 while( nstacknodes > 0 )
4169 v = stacknodes[nstacknodes-1];
4177 compnodes[*ncompnodes] = v;
4181 for(
a = firstoutarcs[v];
a != -1;
a = nextoutarcs[
a] )
4188 targetv = arctargets[
a];
4191 if( targetv != -1 && nodevisited[targetv] ==
VISITED )
4196 comparcs[*ncomparcs] =
a;
4200 if( targetv != -1 && nodevisited[targetv] ==
UNKNOWN )
4203 stacknodes[nstacknodes] = targetv;
4205 nodevisited[targetv] =
ONSTACK;
4210 for(
a = firstinarcs[v];
a != -1;
a = nextinarcs[
a] )
4217 sourcev = arcsources[
a];
4220 if( sourcev != -1 && nodevisited[sourcev] ==
VISITED )
4225 comparcs[*ncomparcs] =
a;
4229 if( sourcev != -1 && nodevisited[sourcev] ==
UNKNOWN )
4232 stacknodes[nstacknodes] = sourcev;
4234 nodevisited[sourcev] =
ONSTACK;
4265 int mcfnetworkssize;
4273 *mcfnetworks =
NULL;
4275 mcfnetworkssize = 0;
4306 mcfdata.flowrowsigns =
NULL;
4307 mcfdata.flowrowscalars =
NULL;
4308 mcfdata.flowrowscores =
NULL;
4309 mcfdata.capacityrowsigns =
NULL;
4310 mcfdata.capacityrowscores =
NULL;
4311 mcfdata.flowcands =
NULL;
4312 mcfdata.nflowcands = 0;
4313 mcfdata.capacitycands =
NULL;
4314 mcfdata.ncapacitycands = 0;
4315 mcfdata.plusflow =
NULL;
4316 mcfdata.minusflow =
NULL;
4317 mcfdata.ncommodities = 0;
4318 mcfdata.nemptycommodities = 0;
4319 mcfdata.commoditysigns =
NULL;
4320 mcfdata.commoditysignssize = 0;
4321 mcfdata.colcommodity =
NULL;
4322 mcfdata.rowcommodity =
NULL;
4323 mcfdata.colarcid =
NULL;
4324 mcfdata.rowarcid =
NULL;
4325 mcfdata.rownodeid =
NULL;
4326 mcfdata.arcarraysize = 0;
4327 mcfdata.arcsources =
NULL;
4328 mcfdata.arctargets =
NULL;
4329 mcfdata.colsources =
NULL;
4330 mcfdata.coltargets =
NULL;
4331 mcfdata.firstoutarcs =
NULL;
4332 mcfdata.firstinarcs =
NULL;
4333 mcfdata.nextoutarcs =
NULL;
4334 mcfdata.nextinarcs =
NULL;
4335 mcfdata.newcols =
NULL;
4336 mcfdata.nnewcols = 0;
4339 mcfdata.ninconsistencies = 0.0;
4340 mcfdata.capacityrows =
NULL;
4341 mcfdata.capacityrowssize = 0;
4342 mcfdata.colisincident =
NULL;
4343 mcfdata.zeroarcarray =
NULL;
4344 mcfdata.modeltype = modeltype;
4355 if( mcfdata.nflowcands == 0 )
4373 printCommodities(
scip, &mcfdata);
4384 if( mcfdata.ncapacitycands == 0 )
4433 printCommodities(
scip, &mcfdata);
4446 for( v = 0; v < mcfdata.nnodes; v++ )
4450 for( v = 0; v < mcfdata.nnodes; v++ )
4457 if( nodevisited[v] ==
VISITED )
4463 assert(compnodes[0] == v);
4467 if( ncompnodes >= minnodes && ncomparcs >=
MINARCS )
4474 assert(*nmcfnetworks <= mcfnetworkssize);
4475 if( *nmcfnetworks == mcfnetworkssize )
4477 mcfnetworkssize =
MAX(2*mcfnetworkssize, *nmcfnetworks+1);
4480 assert(*nmcfnetworks < mcfnetworkssize);
4490 for(
i = *nmcfnetworks;
i > 0 && mcfnetwork->
nnodes > (*mcfnetworks)[
i-1]->nnodes;
i-- )
4491 (*mcfnetworks)[
i] = (*mcfnetworks)[
i-1];
4492 (*mcfnetworks)[
i] = mcfnetwork;
4497 minnodes =
MAX(minnodes, (*mcfnetworks)[*nmcfnetworks-1]->
nnodes);
4502 SCIPdebugMsg(
scip,
" -> discarded network with %d nodes and %d arcs due to maxnetworks (minnodes=%d)\n",
4503 (*mcfnetworks)[*nmcfnetworks-1]->
nnodes, (*mcfnetworks)[*nmcfnetworks-1]->
narcs, minnodes);
4511 SCIPdebugMsg(
scip,
" -> discarded component with %d nodes and %d arcs\n", ncompnodes, ncomparcs);
4553#ifdef COUNTNETWORKVARIABLETYPES
4575 int nintflowvars = 0;
4576 int nbinflowvars = 0;
4577 int ncontflowvars = 0;
4579 int nintcapvars = 0;
4580 int nbincapvars = 0;
4581 int ncontcapvars = 0;
4589 for(
c=0;
c < ncols;
c++)
4594 for(m=0; m < nmcfnetworks; m++)
4606 for(
c=0;
c < ncols;
c++)
4610 if(colcommodity[
c] >= 0 && ! colvisited[
c])
4615 colvisited[
c] =
TRUE;
4643 row = arccapacityrows[
a];
4655 for(
i = 0;
i < rowlen;
i++ )
4660 if(colcommodity[
c] == -1 && ! colvisited[
c] )
4663 colvisited[
c] =
TRUE;
4690 for( k = 0; k < ncommodities; k++ )
4692 for( v = 0; v <
nnodes; v++ )
4695 row = nodeflowrows[v][k];
4705 MCFdebugMessage(
" nof flowvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4706 nflowvars, ncontflowvars, nintflowvars, nbinflowvars);
4707 MCFdebugMessage(
" nof capvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4708 ncapvars, ncontcapvars, nintcapvars, nbincapvars);
4727 int* representatives,
4734 for( v = 0; v < nelems; v++ )
4735 representatives[v] = v;
4741 int* representatives,
4747 while( v != representatives[v] )
4749 representatives[v] = representatives[representatives[v]];
4750 v = representatives[v];
4759 int* representatives,
4765 assert(representatives[rep1] == rep1);
4766 assert(representatives[rep2] == rep2);
4772 representatives[rep2] = rep1;
4774 representatives[rep1] = rep2;
4790 if( nodepair1->weight > nodepair2->weight )
4792 else if( nodepair1->weight < nodepair2->weight )
4836 source1 = nodepair1->node1;
4837 source2 = nodepair2->node1;
4838 target1 = nodepair1->node2;
4839 target2 = nodepair2->node2;
4845 assert(source1 <= target1);
4846 assert(source2 <= target2);
4848 return (source1 == source2 && target1 == target2);
4862 unsigned int hashval;
4872 source = nodepair->node1;
4873 target = nodepair->node2;
4877 assert(source <= target);
4879 hashval = (unsigned)((source << 16) + target);
4902#ifdef BETTERWEIGHTFORDEMANDNODES
4924#ifdef BETTERWEIGHTFORDEMANDNODES
4941 hashtablesize = mcfnetwork->
narcs;
4944 hashGetKeyNodepairs, hashKeyEqNodepairs, hashKeyValNodepairs, (
void*) mcfnetwork) );
4951 for(
a = 0;
a < mcfnetwork->
narcs;
a++ )
4975 if( nodepair.node1 == -1 || nodepair.node2 == -1 )
4979 if( capacityrow !=
NULL )
4995 slack =
MAX(slack, 0.0);
5009 for(
i = 0;
i < rowlen;
i++ )
5016 if(colcommodity[
c] >= 0)
5028 SCIPdebugMsg(
scip,
"cap arc -- slack:%g -- dual:%g -- flow:%g -- cap:%g \n", scale * slack, dualsol/scale, totalflow * scale, totalcap * scale);
5030 SCIPdebugMsg(
scip,
"cap arc -- slack:%g -- dual:%g1\n", scale * slack, dualsol/scale);
5034 nodepair.weight = scale * slack -
ABS(dualsol)/scale;
5035#ifdef USEFLOWFORTIEBREAKING
5038 nodepair.weight += totalflow * scale;
5039 nodepair.weight =
MIN( nodepair.weight, -0.0001);
5042#ifdef USECAPACITYFORTIEBREAKING
5045 nodepair.weight += totalcap * scale;
5046 nodepair.weight =
MIN( nodepair.weight, -0.0001);
5061 if( nodepairptr !=
NULL )
5064 SCIPdebugMsg(
scip,
"nodepair known [%d,%d] -- old weight:%g -- new weight:%g\n", nodepair.node1,nodepair.node2,nodepairptr->weight,
5065 MIN(nodepair.weight, nodepairptr->weight));
5066 nodepairptr->weight =
MIN(nodepair.weight, nodepairptr->weight);
5071 nodepairs = (*nodepairqueue)->nodepairs;
5074 nodepairs[nnodepairs] = nodepair;
5077 SCIPdebugMsg(
scip,
"new nodepair [%d,%d]-- weight:%g\n", nodepair.node1, nodepair.node2, nodepair.weight);
5088#ifdef BETTERWEIGHTFORDEMANDNODES
5096 nodepairs = (*nodepairqueue)->nodepairs;
5097 for( n = 0; n < nnodepairs; n++ )
5101 maxweight =
MAX(maxweight, nodepairs[n].weight);
5103 minweight =
MIN(minweight, nodepairs[n].weight);
5113 for( n = 0; n < nnodepairs; n++ )
5115 int node1 = nodepairs[n].node1;
5116 int node2 = nodepairs[n].node2;
5118#ifdef BETTERWEIGHTFORDEMANDNODES
5125 SCIPdebugMsg(
scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5131 for( k = 0; k < ncommodities; k++ )
5133 if( nodeflowrows[node1][k] ==
NULL )
5136 if( nodeflowscales[node1][k] > 0.0 )
5151 for( k = 0; k < ncommodities; k++ )
5153 if( nodeflowrows[node2][k] ==
NULL )
5156 if( nodeflowscales[node2][k] > 0.0 )
5178 if( !hasdemand1 || !hasdemand2 )
5179 nodepairs[n].weight += maxweight;
5185 if( hasdemand1 && hasdemand2)
5186 nodepairs[n].weight += minweight;
5189 SCIPdebugMsg(
scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5291 (*nodepartition)->nclusters = 0;
5300 nclustersleft = mcfnetwork->
nnodes;
5312 node1 = nodepair->node1;
5313 node2 = nodepair->node2;
5321 assert(0 <= node1rep && node1rep < mcfnetwork->
nnodes);
5322 assert(0 <= node2rep && node2rep < mcfnetwork->
nnodes);
5325 if( node1rep == node2rep )
5329 SCIPdebugMsg(
scip,
"shrinking nodepair (%d,%d) with weight %g: join representatives %d and %d\n",
5330 node1, node2, nodepair->weight, node1rep, node2rep);
5336 assert((*nodepartition)->representatives[0] == 0);
5341 if( nclustersleft > nclusters )
5343 for( v = 1; v < mcfnetwork->
nnodes && nclustersleft > nclusters; v++ )
5355 assert(nclustersleft <= nclusters);
5360 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5370 c = (*nodepartition)->nclusters;
5371 (*nodepartition)->nclusters++;
5374 c = (*nodepartition)->nodeclusters[rep];
5378 (*nodepartition)->nodeclusters[v] =
c;
5384 for(
c = 0;
c < (*nodepartition)->nclusters;
c++ )
5386 (*nodepartition)->clusterbegin[
c] = pos;
5387 pos += clustersize[
c];
5390 (*nodepartition)->clusterbegin[(*nodepartition)->nclusters] = mcfnetwork->
nnodes;
5394 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5396 c = (*nodepartition)->nodeclusters[v];
5397 assert(0 <=
c &&
c < (*nodepartition)->nclusters);
5398 pos = (*nodepartition)->clusterbegin[
c] + clustersize[
c];
5399 assert(pos < (*nodepartition)->clusterbegin[
c+1]);
5400 (*nodepartition)->clusternodes[pos] = v;
5434 unsigned int partition,
5445 if( nodepartition ==
NULL )
5446 return ((v == (
int)partition) == !inverted);
5450 unsigned int clusterbit;
5452 cluster = nodepartition->nodeclusters[v];
5453 assert(0 <= cluster && cluster < nodepartition->nclusters);
5454 clusterbit = (1 << cluster);
5456 return (((partition & clusterbit) != 0) == !inverted);
5466 unsigned int partition
5469 const int* nodeclusters = nodepartition->nodeclusters;
5470 const int* arcsources = mcfnetwork->
arcsources;
5471 const int* arctargets = mcfnetwork->
arctargets;
5480 nclusters = nodepartition->nclusters;
5487 ncomponents = nclusters;
5488 assert(ncomponents >= 2);
5493 int s = arcsources[
a];
5494 int t = arctargets[
a];
5497 if( s == -1 || t == -1 )
5512 cs = nodeclusters[s];
5513 ct = nodeclusters[t];
5514 assert(0 <= cs && cs < nclusters);
5515 assert(0 <= ct && ct < nclusters);
5524 if( repcs == repct )
5531 if( ncomponents <= 2 )
5541 assert(ncomponents >= 2);
5543 return (ncomponents == 2);
5548void nodepartitionPrint(
5554 for(
c = 0;
c < nodepartition->nclusters;
c++ )
5574 unsigned int partition
5583 if( nodepartition ==
NULL )
5588 file = fopen(filename,
"w");
5596 fprintf(file,
"graph\n");
5597 fprintf(file,
"[\n");
5598 fprintf(file,
" hierarchic 1\n");
5599 fprintf(file,
" label \"\"\n");
5600 fprintf(file,
" directed 1\n");
5603 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5614 fprintf(file,
" node\n");
5615 fprintf(file,
" [\n");
5616 fprintf(file,
" id %d\n", v);
5617 fprintf(file,
" label \"%s\"\n", label);
5618 fprintf(file,
" graphics\n");
5619 fprintf(file,
" [\n");
5620 fprintf(file,
" w 30.0\n");
5621 fprintf(file,
" h 30.0\n");
5622 fprintf(file,
" type \"ellipse\"\n");
5624 fprintf(file,
" fill \"#FF0000\"\n");
5626 fprintf(file,
" fill \"#00FF00\"\n");
5627 fprintf(file,
" outline \"#000000\"\n");
5628 fprintf(file,
" ]\n");
5629 fprintf(file,
" LabelGraphics\n");
5630 fprintf(file,
" [\n");
5631 fprintf(file,
" text \"%s\"\n", label);
5632 fprintf(file,
" fontSize 13\n");
5633 fprintf(file,
" fontName \"Dialog\"\n");
5634 fprintf(file,
" anchor \"c\"\n");
5635 fprintf(file,
" ]\n");
5637 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+1);
5639 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+2);
5640 fprintf(file,
" ]\n");
5644 fprintf(file,
" node\n");
5645 fprintf(file,
" [\n");
5646 fprintf(file,
" id %d\n", mcfnetwork->
nnodes);
5647 fprintf(file,
" label \"?\"\n");
5648 fprintf(file,
" graphics\n");
5649 fprintf(file,
" [\n");
5650 fprintf(file,
" w 30.0\n");
5651 fprintf(file,
" h 30.0\n");
5652 fprintf(file,
" type \"ellipse\"\n");
5653 fprintf(file,
" fill \"#FFFFFF\"\n");
5654 fprintf(file,
" outline \"#000000\"\n");
5655 fprintf(file,
" ]\n");
5656 fprintf(file,
" LabelGraphics\n");
5657 fprintf(file,
" [\n");
5658 fprintf(file,
" text \"?\"\n");
5659 fprintf(file,
" fontSize 13\n");
5660 fprintf(file,
" fontName \"Dialog\"\n");
5661 fprintf(file,
" anchor \"c\"\n");
5662 fprintf(file,
" ]\n");
5663 fprintf(file,
" ]\n");
5666 fprintf(file,
" node\n");
5667 fprintf(file,
" [\n");
5668 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+1);
5669 fprintf(file,
" label \"Partition S\"\n");
5670 fprintf(file,
" graphics\n");
5671 fprintf(file,
" [\n");
5672 fprintf(file,
" type \"roundrectangle\"\n");
5673 fprintf(file,
" fill \"#CAECFF84\"\n");
5674 fprintf(file,
" outline \"#666699\"\n");
5675 fprintf(file,
" outlineStyle \"dotted\"\n");
5676 fprintf(file,
" topBorderInset 0\n");
5677 fprintf(file,
" bottomBorderInset 0\n");
5678 fprintf(file,
" leftBorderInset 0\n");
5679 fprintf(file,
" rightBorderInset 0\n");
5680 fprintf(file,
" ]\n");
5681 fprintf(file,
" LabelGraphics\n");
5682 fprintf(file,
" [\n");
5683 fprintf(file,
" text \"Partition S\"\n");
5684 fprintf(file,
" fill \"#99CCFF\"\n");
5685 fprintf(file,
" fontSize 15\n");
5686 fprintf(file,
" fontName \"Dialog\"\n");
5687 fprintf(file,
" alignment \"right\"\n");
5688 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5689 fprintf(file,
" anchor \"t\"\n");
5690 fprintf(file,
" borderDistance 0.0\n");
5691 fprintf(file,
" ]\n");
5692 fprintf(file,
" isGroup 1\n");
5693 fprintf(file,
" ]\n");
5696 fprintf(file,
" node\n");
5697 fprintf(file,
" [\n");
5698 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+2);
5699 fprintf(file,
" label \"Partition T\"\n");
5700 fprintf(file,
" graphics\n");
5701 fprintf(file,
" [\n");
5702 fprintf(file,
" type \"roundrectangle\"\n");
5703 fprintf(file,
" fill \"#CAECFF84\"\n");
5704 fprintf(file,
" outline \"#666699\"\n");
5705 fprintf(file,
" outlineStyle \"dotted\"\n");
5706 fprintf(file,
" topBorderInset 0\n");
5707 fprintf(file,
" bottomBorderInset 0\n");
5708 fprintf(file,
" leftBorderInset 0\n");
5709 fprintf(file,
" rightBorderInset 0\n");
5710 fprintf(file,
" ]\n");
5711 fprintf(file,
" LabelGraphics\n");
5712 fprintf(file,
" [\n");
5713 fprintf(file,
" text \"Partition T\"\n");
5714 fprintf(file,
" fill \"#99CCFF\"\n");
5715 fprintf(file,
" fontSize 15\n");
5716 fprintf(file,
" fontName \"Dialog\"\n");
5717 fprintf(file,
" alignment \"right\"\n");
5718 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5719 fprintf(file,
" anchor \"t\"\n");
5720 fprintf(file,
" borderDistance 0.0\n");
5721 fprintf(file,
" ]\n");
5722 fprintf(file,
" isGroup 1\n");
5723 fprintf(file,
" ]\n");
5726 for(
a = 0;
a < mcfnetwork->
narcs;
a++ )
5738 hasfractional =
FALSE;
5749 for(
i = 0;
i < rowlen;
i++ )
5756 hasfractional =
TRUE;
5764 fprintf(file,
" edge\n");
5765 fprintf(file,
" [\n");
5768 fprintf(file,
" label \"%s\"\n", label);
5769 fprintf(file,
" graphics\n");
5770 fprintf(file,
" [\n");
5772 fprintf(file,
" fill \"#000000\"\n");
5774 fprintf(file,
" fill \"#FF0000\"\n");
5776 fprintf(file,
" style \"dashed\"\n");
5777 fprintf(file,
" width 1\n");
5778 fprintf(file,
" targetArrow \"standard\"\n");
5779 fprintf(file,
" ]\n");
5780 fprintf(file,
" LabelGraphics\n");
5781 fprintf(file,
" [\n");
5782 fprintf(file,
" text \"%s\"\n", label);
5783 fprintf(file,
" ]\n");
5784 fprintf(file,
" ]\n");
5788 fprintf(file,
"]\n");
5837 for(
i = 0;
i < cutnnz; ++
i )
5839 cutvars[
i] =
vars[cutinds[
i]];
5855 SCIPdebugMsg(
scip,
" -> found MCF cut <%s>: rhs=%f, act=%f eff=%f rank=%d\n",
5875 SCIP_CALL(
SCIPseparateRelaxedKnapsack(
scip,
NULL, sepa, cutnnz, cutvars, cutcoefs, +1.0, cutrhs,
sol,
cutoff, ncuts) );
5926 unsigned int partition;
5927 unsigned int allpartitions;
5928 unsigned int startpartition;
5942 maxsepacuts =
sepadata->maxsepacutsroot;
5944 maxsepacuts =
sepadata->maxsepacuts;
5945 if( maxsepacuts < 0 )
5946 maxsepacuts = INT_MAX;
5951 maxtestdelta =
sepadata->maxtestdelta;
5952 if( maxtestdelta <= 0 )
5953 maxtestdelta = INT_MAX;
5989 if( nodepartition ==
NULL )
5993 allpartitions = (
unsigned int)
nnodes;
5994 SCIPdebugMsg(
scip,
"maxtestdelta: %d, maxsepacuts: %d, nnodes: %d \n", maxtestdelta, maxsepacuts,
nnodes);
6001 int nclusters = nodepartition->nclusters;
6003 assert((
unsigned int)nclusters <= 8*
sizeof(
unsigned int));
6004 SCIPdebugMsg(
scip,
"maxtestdelta: %d, maxsepacuts: %d, nclusters: %d \n", maxtestdelta, maxsepacuts, nclusters);
6011 allpartitions = (1 << (nclusters-1));
6015 for( partition = startpartition; partition <= allpartitions-1 && !
SCIPisStopped(
scip) && *ncuts < maxsepacuts && !*
cutoff; partition++ )
6029 if(
sepadata->checkcutshoreconnectivity )
6036 SCIPdebugMsg(
scip,
"generating cluster cuts for partition 0x%x \n", partition );
6037 SCIPdebugMsg(
scip,
" -> either shore S or shore T is not connected - skip partition.\n");
6042 for( inverted =
FALSE; inverted <= useinverted && !*
cutoff; inverted++ )
6044 if( nodepartition ==
NULL )
6046 SCIPdebugMsg(
scip,
"generating single-node cuts for node %u (inverted: %u)\n", partition, inverted);
6050 SCIPdebugMsg(
scip,
"generating cluster cuts for partition 0x%x (inverted: %u)\n", partition, inverted);
6054 SCIP_CALL( outputGraph(
scip, mcfnetwork, nodepartition, inverted, partition) );
6072 for( v = 0; v <
nnodes; v++ )
6082 for( k = 0; k < ncommodities; k++ )
6086 if( nodeflowrows[v][k] ==
NULL )
6089 if( nodeflowscales[v][k] > 0.0 )
6093 if( nodeflowinverted[v][k] )
6096 comcutdemands[k] += rhs * nodeflowscales[v][k];
6104 if(
sepadata->separatesinglenodecuts && nodepartition !=
NULL && (nnodesinS == 1 || nnodesinS ==
nnodes-1) )
6106 SCIPdebugMsg(
scip,
" -> shore S or T has only one node - skip partition.\n");
6113 for( k = 0; k < ncommodities; k++ )
6116 SCIPdebugMsg(
scip,
" -> commodity %d: directed cutdemand=%g\n", k, comcutdemands[k]);
6123 for( k = 0; k < ncommodities; k++ )
6126 SCIPdebugMsg(
scip,
" -> commodity %d: undirected cutdemand=%g\n", k, comcutdemands[k]);
6131 if( k == ncommodities )
6176 if( arccapacityrows[
a] ==
NULL )
6190 if( arcsources[
a] == -1 || arctargets[
a] == -1 )
6205 rowweights[
r] = arccapacityscales[
a];
6212 if( rowweights[
r] > 0.0 )
6222 for( j = 0; j < rowlen; j++ )
6227 coef = rowvals[j] * arccapacityscales[
a];
6233 k = colcommodity[
c];
6235 comdemands[k] = coef;
6249 while( left <= right )
6251 int mid = (left+right)/2;
6253 if(
REALABS( deltas[mid] / coef - 1.0 ) < 1e-03 )
6258 else if( coef < deltas[mid] )
6268 assert(ndeltas <= deltassize);
6269 if( ndeltas == deltassize )
6274 if( left < ndeltas )
6276 for( d = ndeltas; d > left; d-- )
6277 deltas[d] = deltas[d-1];
6279 deltas[left] = coef;
6288 for( v = 0; v <
nnodes; v++ )
6291 for( k = 0; k < ncommodities; k++ )
6297 if( comdemands[k] == 0.0 )
6300 scale = comdemands[k];
6323 if( comcutdemands[k] > 0.0 )
6342 if( nodeflowrows[v][k] ==
NULL )
6357 rowweights[
r] = scale * nodeflowscales[v][k];
6358 if( nodeflowinverted[v][k] )
6359 rowweights[
r] *= -1.0;
6360 SCIPdebugMsg(
scip,
" -> node %d, commodity %d, r=%d, flow row <%s>: scale=%g weight=%g slack=%g dual=%g\n",
6366 if( nodeflowscales[v][k] > 0.0 )
6385 bestdelta = deltas[ndeltas-1];
6396 for( d = ndeltas-1; d >= 0 && d >= ndeltas-maxtestdelta; d-- )
6411 SCIP_CALL(
SCIPcalcMIR(
scip,
sol,
POSTPROCESS,
BOUNDSWITCH,
VARTYPEUSEVBDS, allowlocal,
sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
6412 1.0/deltas[d], aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6413 assert(allowlocal || !cutislocal);
6423 if( cutefficacy > bestefficacy )
6425 bestdelta = deltas[d];
6426 bestefficacy = cutefficacy;
6432 SCIPdebugMsg(
scip,
"success -> delta = %g -> rhs: %g, efficacy: %g\n", deltas[d], cutrhs, cutefficacy);
6433 SCIP_CALL(
addCut(
scip, sepa,
sepadata,
sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts,
cutoff) );
6440 if( arccapacityrows[
a] !=
NULL )
6446 if(
r >= 0 && rowweights[
r] != 0.0 )
6448 MCFdebugMessage(
" -> arc %d, capacity row <%s>: weight=%g slack=%g prod=%g dual=%g\n",
a,
6461 if(
sepadata->separateflowcutset && oldncuts == *ncuts && !*
cutoff )
6469 totalviolationdelta = 0.0;
6470 onedivoneminsf0 = 1.0/(1.0 - f0);
6485 if( arccapacityrows[
a] ==
NULL )
6496 if( rowweights[
r] == 0.0 )
6511 rowweight = rowweights[
r]/bestdelta;
6516 violationdelta = rowweight * (rowlhs - rowconstant);
6518 violationdelta = rowweight * (rowrhs - rowconstant);
6520 for( j = 0; j < rowlen; j++ )
6528 coef = rowvals[j] * rowweight;
6539 if( colcommodity[
c] >= 0 )
6550 mircoef =
SCIPfloor(
scip, coef) + (fj - f0)*onedivoneminsf0;
6557 mircoef = coef * onedivoneminsf0;
6562 if( colcommodity[
c] >= 0 )
6563 violationdelta += mircoef * solval;
6565 violationdelta -= mircoef * solval;
6570 SCIPdebugMsg(
scip,
" -> discarding capacity row <%s> of weight %g and slack %g: increases MIR violation by %g\n",
6573 rowweights[
r] = 0.0;
6574 totalviolationdelta += violationdelta;
6579 if( totalviolationdelta > 0.0 )
6592 SCIPdebugMsg(
scip,
"applying MIR with delta = %g to flowcut inequality (violation improvement: %g)\n", bestdelta, totalviolationdelta);
6599 SCIP_CALL(
SCIPcalcMIR(
scip,
sol,
POSTPROCESS,
BOUNDSWITCH,
VARTYPEUSEVBDS, allowlocal,
sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
6600 1.0/bestdelta, aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6602 assert(allowlocal || !cutislocal);
6606 SCIPdebugMsg(
scip,
" -> delta = %g -> rhs: %g, efficacy: %g\n", bestdelta, cutrhs, cutefficacy);
6607 SCIP_CALL(
addCut(
scip, sepa,
sepadata,
sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts,
cutoff) );
6664 if( ncols !=
nvars )
6679 colrowratio = (
SCIP_Real)ncols/(nrows+1e-9);
6692 if( colrowratio < MINCOLROWRATIO || colrowratio >
MAXCOLROWRATIO )
6711 MCFdebugMessage(
" -> extracted network %d has %d nodes, %d (%d) arcs (uncapacitated), and %d commodities (modeltype: %s)\n",
6718#ifdef COUNTNETWORKVARIABLETYPES
6724 mcfnetworks =
sepadata->mcfnetworks;
6725 nmcfnetworks =
sepadata->nmcfnetworks;
6734 for(
i = 0;
i < nmcfnetworks && !
cutoff;
i++ )
6740 mcfnetwork = mcfnetworks[
i];
6751 MCFdebugMessage(
"MCF network has %d nodes and %d arcs. arc node ratio %.2f exceed --> exit\n",
6757 if(
sepadata->separatesinglenodecuts )
6768 nodepartitionPrint(nodepartition);
6778 MCFdebugMessage(
"MCF network has %d nodes, %d arcs, %d commodities. Found %d MCF network cuts, cutoff = %u.\n",
6787 else if( ncuts > 0 )
6944 sepaExeclpMcf, sepaExecsolMcf,
6958 "separating/mcf/nclusters",
6959 "number of clusters to generate in the shrunken network -- default separation",
6962 "separating/mcf/maxweightrange",
6963 "maximal valid range max(|weights|)/min(|weights|) of row weights",
6966 "separating/mcf/maxtestdelta",
6967 "maximal number of different deltas to try (-1: unlimited) -- default separation",
6970 "separating/mcf/trynegscaling",
6971 "should negative values also be tested in scaling?",
6974 "separating/mcf/fixintegralrhs",
6975 "should an additional variable be complemented if f0 = 0?",
6978 "separating/mcf/dynamiccuts",
6979 "should generated cuts be removed from the LP if they are no longer tight?",
6982 "separating/mcf/modeltype",
6983 "model type of network (0: auto, 1:directed, 2:undirected)",
6986 "separating/mcf/maxsepacuts",
6987 "maximal number of mcf cuts separated per separation round",
6990 "separating/mcf/maxsepacutsroot",
6991 "maximal number of mcf cuts separated per separation round in the root node -- default separation",
6994 "separating/mcf/maxinconsistencyratio",
6995 "maximum inconsistency ratio for separation at all",
6998 "separating/mcf/maxarcinconsistencyratio",
6999 "maximum inconsistency ratio of arcs not to be deleted",
7002 "separating/mcf/checkcutshoreconnectivity",
7003 "should we separate only if the cuts shores are connected?",
7006 "separating/mcf/separatesinglenodecuts",
7007 "should we separate inequalities based on single-node cuts?",
7010 "separating/mcf/separateflowcutset",
7011 "should we separate flowcutset inequalities on the network cuts?",
7014 "separating/mcf/separateknapsack",
7015 "should we separate knapsack cover inequalities on the network cuts?",
#define DEFAULT_MAXSEPACUTSROOT
#define DEFAULT_MAXSEPACUTS
Constraint handler for knapsack constraints of the form , x binary and .
methods for the aggregation rows
#define SCIP_LONGINT_FORMAT
SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
int SCIPgetNVars(SCIP *scip)
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
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)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
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)
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)),)
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
int SCIPgetNLPBranchCands(SCIP *scip)
int SCIPcolGetLPPos(SCIP_COL *col)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
SCIP_Bool SCIPcolIsImpliedIntegral(SCIP_COL *col)
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
int SCIPcolGetNLPNonz(SCIP_COL *col)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_RETCODE SCIPcalcMIR(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, int vartypeusevbds, SCIP_Bool allowlocal, SCIP_Bool fixintegralrhs, int *boundsfortrans, SCIP_BOUNDTYPE *boundtypesfortrans, SCIP_Real minfrac, SCIP_Real maxfrac, SCIP_Real scale, SCIP_AGGRROW *aggrrow, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, SCIP_Real *cutefficacy, int *cutrank, SCIP_Bool *cutislocal, SCIP_Bool *success)
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPaggrRowSumRows(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Real *weights, int *rowinds, int nrowinds, SCIP_Bool sidetypebasis, SCIP_Bool allowlocal, int negslack, int maxaggrlen, SCIP_Bool *valid)
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
SCIP_ROW ** SCIPgetLPRows(SCIP *scip)
int SCIPgetNLPRows(SCIP *scip)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
SCIP_COL ** SCIPgetLPCols(SCIP *scip)
int SCIPgetNLPCols(SCIP *scip)
#define SCIPfreeBuffer(scip, ptr)
#define SCIPfreeMemoryArrayNull(scip, ptr)
#define SCIPreallocMemoryArray(scip, ptr, newnum)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
#define SCIPallocMemoryArray(scip, ptr, num)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPreallocBufferArray(scip, ptr, num)
#define SCIPallocMemory(scip, ptr)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPfreeMemory(scip, ptr)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPallocBuffer(scip, ptr)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
SCIP_Real SCIPgetRowFeasibility(SCIP *scip, SCIP_ROW *row)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
int SCIProwGetNLPNonz(SCIP_ROW *row)
int SCIProwGetLPPos(SCIP_ROW *row)
const char * SCIProwGetName(SCIP_ROW *row)
SCIP_RETCODE SCIPcaptureRow(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
int SCIProwGetRank(SCIP_ROW *row)
void SCIProwChgRank(SCIP_ROW *row, int rank)
SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa,)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa,)
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa,)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa,)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
SCIP_RETCODE SCIPincludeSepaMcf(SCIP *scip)
void SCIPsortInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
assert(minobj< SCIPgetCutoffbound(scip))
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
public methods for LP management
public methods for message output
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for separators
public methods for problem variables
public methods for branching rule plugins and branching
public methods for cuts and aggregation rows
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for separator plugins
public methods for solutions
public methods for querying solving statistics
public methods for the branch-and-bound tree
#define DEFAULT_DYNAMICCUTS
#define DEFAULT_TRYNEGSCALING
#define DEFAULT_FIXINTEGRALRHS
#define DEFAULT_MAXTESTDELTA
#define SEPA_MAXBOUNDDIST
#define DEFAULT_MAXWEIGHTRANGE
static void addFlowrowToCommodity(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, unsigned char rowsign, int *comcolids, int *ncomcolids)
static SCIP_RETCODE extractFlow(SCIP *scip, MCFDATA *mcfdata, SCIP_Real maxflowvarflowrowratio, SCIP_Bool *failed)
static SCIP_RETCODE nodepartitionCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION **nodepartition, int nclusters)
static SCIP_RETCODE mcfnetworkFree(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
struct SCIP_McfNetwork SCIP_MCFNETWORK
static SCIP_RETCODE mcfnetworkFill(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, MCFDATA *mcfdata, int *compnodeid, int *compnodes, int ncompnodes, int *comparcs, int ncomparcs)
struct nodepair NODEPAIRENTRY
#define DEFAULT_MODELTYPE
#define DEFAULT_MAXARCINCONSISTENCYRATIO
struct nodepartition NODEPARTITION
enum McfEffortLevel MCFEFFORTLEVEL
static void getNextFlowrow(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW **nextrow, unsigned char *nextrowsign, SCIP_Bool *nextinvertcommodity)
static SCIP_RETCODE findUncapacitatedArcs(SCIP *scip, MCFDATA *mcfdata)
static SCIP_RETCODE getNodeSimilarityScore(SCIP *scip, MCFDATA *mcfdata, int baserowlen, int *basearcpattern, int basenposuncap, int basenneguncap, SCIP_ROW *row, SCIP_Real *score, SCIP_Bool *invertcommodity)
static void nodepartitionJoin(NODEPARTITION *nodepartition, int rep1, int rep2)
static SCIP_RETCODE identifySourcesTargets(SCIP *scip, MCFDATA *mcfdata, SCIP_SEPADATA *sepadata, MCFEFFORTLEVEL *effortlevel)
#define DEFAULT_SEPARATEFLOWCUTSET
#define HASHSIZE_NODEPAIRS
static SCIP_RETCODE mcfnetworkCreate(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
static void nodepairqueueFree(SCIP *scip, NODEPAIRQUEUE **nodepairqueue)
static SCIP_RETCODE mcfnetworkExtract(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_MCFNETWORK ***mcfnetworks, int *nmcfnetworks, MCFEFFORTLEVEL *effortlevel)
#define UNCAPACITATEDARCSTRESHOLD
static SCIP_RETCODE extractNodes(SCIP *scip, MCFDATA *mcfdata)
static void unionfindJoinSets(int *representatives, int rep1, int rep2)
static void deleteCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int nrows, int *ndelflowrows, int *ndelflowvars)
@ MCFEFFORTLEVEL_AGGRESSIVE
static SCIP_RETCODE nodepairqueueCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPAIRQUEUE **nodepairqueue)
static int nodepartitionIsConnected(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, unsigned int partition)
#define DEFAULT_CHECKCUTSHORECONNECTIVITY
static SCIP_RETCODE extractFlowRows(SCIP *scip, MCFDATA *mcfdata)
enum SCIP_McfModeltype SCIP_MCFMODELTYPE
struct nodepairqueue NODEPAIRQUEUE
#define DEFAULT_SEPARATESINGLENODECUTS
static void getFlowrowFit(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, int k, unsigned char *rowsign, SCIP_Bool *invertcommodity)
#define MAXFLOWVARFLOWROWRATIO
static void getIncidentNodes(SCIP *scip, MCFDATA *mcfdata, SCIP_COL *col, int *sourcenode, int *targetnode)
static SCIP_Bool nodeInPartition(NODEPARTITION *nodepartition, unsigned int partition, SCIP_Bool inverted, int v)
static SCIP_RETCODE extractCapacities(SCIP *scip, MCFDATA *mcfdata)
static SCIP_RETCODE createNewArc(SCIP *scip, MCFDATA *mcfdata, int source, int target, int *newarcid)
static SCIP_RETCODE identifyComponent(SCIP *scip, MCFDATA *mcfdata, int *nodevisited, int startv, int *compnodes, int *ncompnodes, int *comparcs, int *ncomparcs)
static SCIP_RETCODE generateClusterCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Bool allowlocal, int depth, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, int *ncuts, SCIP_Bool *cutoff)
static SCIP_RETCODE cleanupNetwork(SCIP *scip, MCFDATA *mcfdata)
#define DEFAULT_NCLUSTERS
static void nodepartitionFree(SCIP *scip, NODEPARTITION **nodepartition)
static SCIP_RETCODE extractCapacityRows(SCIP *scip, MCFDATA *mcfdata)
static SCIP_Bool nodepairqueueIsEmpty(NODEPAIRQUEUE *nodepairqueue)
static int nodepartitionGetRepresentative(NODEPARTITION *nodepartition, int v)
static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Real *cutcoefs, SCIP_Real cutrhs, int *cutinds, int cutnnz, SCIP_Bool cutislocal, int cutrank, int *ncuts, SCIP_Bool *cutoff)
static void unionfindInitSets(int *representatives, int nelems)
#define MAXAGGRLEN(nvars)
static void collectIncidentFlowCols(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *flowrow, int basecommodity)
#define MINCOMNODESFRACTION
static void invertCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int ncomrows, int *comcolids, int ncomcolids)
@ SCIP_MCFMODELTYPE_UNDIRECTED
@ SCIP_MCFMODELTYPE_DIRECTED
static NODEPAIRENTRY * nodepairqueueRemove(NODEPAIRQUEUE *nodepairqueue)
static void fixCommoditySigns(MCFDATA *mcfdata)
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Bool allowlocal, int depth, SCIP_RESULT *result)
static SCIP_RETCODE createNewCommodity(SCIP *scip, MCFDATA *mcfdata)
#define DEFAULT_SEPARATEKNAPSACK
#define DEFAULT_MAXINCONSISTENCYRATIO
#define MAXFLOWCANDDENSITY
static int unionfindGetRepresentative(int *representatives, int v)
multi-commodity-flow network cut separator
SCIP_ROW *** nodeflowrows
SCIP_MCFMODELTYPE modeltype
SCIP_Real * arccapacityscales
SCIP_Real ** nodeflowscales
SCIP_Bool ** nodeflowinverted
SCIP_ROW ** arccapacityrows
struct SCIP_AggrRow SCIP_AGGRROW
#define SCIP_DECL_SORTPTRCOMP(x)
#define SCIP_DECL_HASHKEYEQ(x)
#define SCIP_DECL_SORTINDCOMP(x)
struct SCIP_PQueue SCIP_PQUEUE
#define SCIP_DECL_HASHGETKEY(x)
#define SCIP_DECL_HASHKEYVAL(x)
struct SCIP_HashTable SCIP_HASHTABLE
enum SCIP_Result SCIP_RESULT
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_SepaData SCIP_SEPADATA
#define SCIP_DECL_SEPAINITSOL(x)
#define SCIP_DECL_SEPAEXECSOL(x)
#define SCIP_DECL_SEPAEXECLP(x)
#define SCIP_DECL_SEPAFREE(x)
#define SCIP_DECL_SEPAEXITSOL(x)
struct SCIP_Sepa SCIP_SEPA
#define SCIP_DECL_SEPACOPY(x)
@ SCIP_VARTYPE_CONTINUOUS