46 #define BETTERWEIGHTFORDEMANDNODES 74 #define SEPA_NAME "mcf" 75 #define SEPA_DESC "multi-commodity-flow network cut separator" 76 #define SEPA_PRIORITY -10000 78 #define SEPA_MAXBOUNDDIST 0.0 79 #define SEPA_USESSUBSCIP FALSE 80 #define SEPA_DELAY FALSE 83 #define DEFAULT_NCLUSTERS 5 84 #define DEFAULT_MAXWEIGHTRANGE 1e+06 85 #define DEFAULT_MAXTESTDELTA 20 86 #define DEFAULT_TRYNEGSCALING FALSE 87 #define DEFAULT_FIXINTEGRALRHS TRUE 88 #define DEFAULT_DYNAMICCUTS TRUE 89 #define DEFAULT_MODELTYPE 0 90 #define DEFAULT_MAXSEPACUTS 100 91 #define DEFAULT_MAXSEPACUTSROOT 200 92 #define DEFAULT_MAXINCONSISTENCYRATIO 0.02 93 #define DEFAULT_MAXARCINCONSISTENCYRATIO 0.5 94 #define DEFAULT_CHECKCUTSHORECONNECTIVITY TRUE 95 #define DEFAULT_SEPARATESINGLENODECUTS TRUE 96 #define DEFAULT_SEPARATEFLOWCUTSET TRUE 97 #define DEFAULT_SEPARATEKNAPSACK TRUE 100 #define BOUNDSWITCH 0.5 101 #define POSTPROCESS TRUE 104 #define MAXFRAC 0.999 106 #define MAXCOLS 2000000 107 #define MAXAGGRLEN(nvars) (0.1*(nvars)+1000) 108 #define MINCOLROWRATIO 0.01 109 #define MAXCOLROWRATIO 100.0 110 #define MAXFLOWVARFLOWROWRATIO 100.0 111 #define MAXARCNODERATIO 100.0 112 #define MAXNETWORKS 4 113 #define MAXFLOWCANDDENSITY 0.1 114 #define MINCOMNODESFRACTION 0.5 117 #define MAXCAPACITYSLACK 0.1 118 #define UNCAPACITATEDARCSTRESHOLD 0.8 119 #define HASHSIZE_NODEPAIRS 500 131 #define MCFdebugMessage printf 135 #define MCFdebugMessage while(FALSE) printf 209 unsigned char* flowrowsigns;
212 unsigned char* capacityrowsigns;
221 int nemptycommodities;
223 int commoditysignssize;
244 int capacityrowssize;
271 int* representatives;
283 #define LHSPOSSIBLE 1u 284 #define RHSPOSSIBLE 2u 285 #define LHSASSIGNED 4u 286 #define RHSASSIGNED 8u 288 #define DISCARDED 32u 289 #define UNDIRECTED 64u 299 assert(mcfnetwork !=
NULL);
302 (*mcfnetwork)->nodeflowrows =
NULL;
303 (*mcfnetwork)->nodeflowscales =
NULL;
304 (*mcfnetwork)->nodeflowinverted =
NULL;
305 (*mcfnetwork)->arccapacityrows =
NULL;
306 (*mcfnetwork)->arccapacityscales =
NULL;
307 (*mcfnetwork)->arcsources =
NULL;
308 (*mcfnetwork)->arctargets =
NULL;
309 (*mcfnetwork)->colcommodity =
NULL;
310 (*mcfnetwork)->nnodes = 0;
311 (*mcfnetwork)->nuncapacitatedarcs = 0;
312 (*mcfnetwork)->narcs = 0;
313 (*mcfnetwork)->ncommodities = 0;
325 assert(mcfnetwork !=
NULL);
327 if( *mcfnetwork !=
NULL )
332 for( v = 0; v < (*mcfnetwork)->nnodes; v++ )
336 for( k = 0; k < (*mcfnetwork)->ncommodities; k++ )
338 if( (*mcfnetwork)->nodeflowrows[v][k] !=
NULL )
347 for( a = 0; a < (*mcfnetwork)->narcs; a++ )
349 if( (*mcfnetwork)->arccapacityrows[a] !=
NULL )
382 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
383 SCIP_Real* flowrowscalars = mcfdata->flowrowscalars;
384 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
385 int* flowcands = mcfdata->flowcands;
386 int nflowcands = mcfdata->nflowcands;
388 int* commoditysigns = mcfdata->commoditysigns;
390 int* rowcommodity = mcfdata->rowcommodity;
391 int* rownodeid = mcfdata->rownodeid;
392 SCIP_ROW** capacityrows = mcfdata->capacityrows;
401 int ncompcommodities;
408 assert(mcfnetwork !=
NULL);
410 assert(2 <= ncompnodes && ncompnodes <= mcfdata->
nnodes);
411 assert(1 <= ncomparcs && ncomparcs <= mcfdata->
narcs);
412 assert(ncommodities > 0);
416 for( v = 0; v < mcfdata->nnodes; v++ )
417 assert(compnodeid[v] == -1);
429 compcommodity[k] = -1;
436 for( i = 0; i < ncompnodes; i++ )
439 assert(0 <= v && v < mcfdata->nnodes);
444 ncompcommodities = 0;
445 for( i = 0; i < nflowcands; i++ )
451 assert(0 <= r && r < nrows);
454 if( rv >= 0 && compnodeid[rv] >= 0 )
457 assert(0 <= k && k < ncommodities);
458 if( compcommodity[k] == -1 )
460 compcommodity[k] = ncompcommodities;
471 mcfnetwork->
nnodes = ncompnodes;
472 mcfnetwork->
narcs = ncomparcs;
480 for( v = 0; v < mcfnetwork->
nnodes; v++ )
498 for( a = 0; a < mcfnetwork->
narcs; a++ )
508 for( i = 0; i < nflowcands; i++ )
514 assert(0 <= r && r < nrows);
517 if( rv >= 0 && compnodeid[rv] >= 0 )
523 rk = rowcommodity[
r];
524 assert(v < mcfnetwork->nnodes);
525 assert(0 <= rk && rk < ncommodities);
528 k = compcommodity[rk];
529 assert(0 <= k && k < mcfnetwork->ncommodities);
534 scale = flowrowscalars[
r];
537 if( commoditysigns[rk] == -1 )
545 for( a = 0; a < mcfnetwork->
narcs; a++ )
555 globala = comparcs[
a];
556 capacityrow = capacityrows[globala];
561 if( capacityrow !=
NULL)
564 assert(0 <= r && r < nrows);
566 assert((capacityrowsigns[r] &
INVERTED) == 0);
567 assert(mcfdata->rowarcid[r] == globala);
585 for( j = 0; j < rowlen; j++ )
592 if( comdemands[k] != 0.0 )
607 for( j = 0; j < rowlen; j++ )
612 if( k >= 0 && comdemands[k] == 0.0 )
624 if( mcfdata->arcsources[globala] >= 0 )
626 assert(mcfdata->arcsources[globala] < mcfdata->nnodes);
627 assert(0 <= compnodeid[mcfdata->arcsources[globala]] && compnodeid[mcfdata->arcsources[globala]] < mcfnetwork->
nnodes);
628 mcfnetwork->
arcsources[
a] = compnodeid[mcfdata->arcsources[globala]];
630 if( mcfdata->arctargets[globala] >= 0 )
632 assert(mcfdata->arctargets[globala] < mcfdata->nnodes);
633 assert(0 <= compnodeid[mcfdata->arctargets[globala]] && compnodeid[mcfdata->arctargets[globala]] < mcfnetwork->
nnodes);
634 mcfnetwork->
arctargets[
a] = compnodeid[mcfdata->arctargets[globala]];
639 for( c = 0; c < ncols; c++ )
649 for( i = 0; i < ncompnodes; i++ )
651 assert(0 <= compnodes[i] && compnodes[i] < mcfdata->nnodes);
652 assert(compnodeid[compnodes[i]] == i);
653 compnodeid[compnodes[i]] = -1;
666 void mcfnetworkPrint(
670 if( mcfnetwork ==
NULL )
677 for( v = 0; v < mcfnetwork->
nnodes; v++ )
696 for( a = 0; a < mcfnetwork->
narcs; a++ )
712 void printCommodities(
717 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
718 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
720 int* commoditysigns = mcfdata->commoditysigns;
722 int* rowcommodity = mcfdata->rowcommodity;
723 int* colarcid = mcfdata->colarcid;
724 int* rownodeid = mcfdata->rownodeid;
725 int nnodes = mcfdata->nnodes;
726 SCIP_ROW** capacityrows = mcfdata->capacityrows;
746 for( c = 0; c < ncols; c++ )
748 if( colcommodity[c] == k )
751 for( r = 0; r < nrows; r++ )
753 if( rowcommodity[r] == k )
756 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
761 if( rownodeid !=
NULL )
765 for( v = 0; v <
nnodes; v++ )
768 for( r = 0; r < nrows; r++ )
770 if( rownodeid[r] == v )
773 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
779 assert(capacityrows !=
NULL || mcfdata->narcs == 0);
782 for( a = 0; a < mcfdata->narcs; a++ )
785 if( capacityrows[a] !=
NULL )
788 assert(0 <= r && r < nrows);
791 else if( (capacityrowsigns[r] &
RHSASSIGNED) != 0 )
799 assert(colcommodity !=
NULL || ncols == 0);
802 for( c = 0; c < ncols; c++ )
804 if( colcommodity[c] == -1 )
813 for( r = 0; r < nrows; r++ )
815 assert(rowcommodity !=
NULL);
833 if( rowscores[ind2] < rowscores[ind1] )
835 else if( rowscores[ind2] > rowscores[ind1] )
848 unsigned char* flowrowsigns;
868 flowrowsigns = mcfdata->flowrowsigns;
869 flowrowscalars = mcfdata->flowrowscalars;
870 flowrowscores = mcfdata->flowrowscores;
871 flowcands = mcfdata->flowcands;
873 assert(mcfdata->nflowcands == 0);
876 for( r = 0; r < nrows; r++ )
901 absdualsol =
ABS(absdualsol);
904 flowrowscalars[
r] = 0.0;
905 flowrowscores[
r] = 0.0;
926 coef =
ABS(rowvals[0]);
933 for( i = 0; i < rowlen; i++ )
939 hasposcoef = hasposcoef || (rowvals[i] > 0.0);
940 hasnegcoef = hasnegcoef || (rowvals[i] < 0.0);
970 flowrowscalars[
r] = 1.0/coef;
971 flowcands[mcfdata->nflowcands] =
r;
972 mcfdata->nflowcands++;
979 if(
SCIPisEQ(scip, flowrowscalars[r], 1.0) )
980 flowrowscores[
r] += 1000.0;
983 if( hasposcoef && hasnegcoef )
984 flowrowscores[
r] += 500.0;
991 if( ncontvars == rowlen )
992 flowrowscores[
r] += 1000.0;
993 else if( nintvars + nimplintvars == rowlen )
994 flowrowscores[
r] += 500.0;
995 else if( nbinvars == rowlen )
996 flowrowscores[
r] += 100.0;
1000 flowrowscores[
r] += 10.0*rowlen/(rowlen+10.0);
1004 flowrowscores[
r] += 50.0;
1006 assert(flowrowscores[r] > 0.0);
1009 maxdualflow =
MAX(maxdualflow, absdualsol);
1022 for( i = 0; i < mcfdata->nflowcands; i++ )
1027 assert(0 <= r && r < nrows);
1032 dualsol =
ABS(dualsol);
1035 assert(maxdualflow > 0.0);
1036 flowrowscores[
r] += dualsol/maxdualflow + 1.0;
1037 assert(flowrowscores[r] > 0.0);
1042 SCIPsortInd(mcfdata->flowcands, compCands, (
void*)flowrowscores, mcfdata->nflowcands);
1044 MCFdebugMessage(
"flow conservation candidates [%d]\n", mcfdata->nflowcands);
1046 for( r = 0; r < mcfdata->nflowcands; r++ )
1049 SCIPdebugMsg(scip,
"%4d [score: %2g]: %s\n", mcfdata->flowcands[r], flowrowscores[mcfdata->flowcands[r]],
1064 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1067 int nactivecommodities = mcfdata->ncommodities - mcfdata->nemptycommodities;
1070 unsigned char* capacityrowsigns;
1079 int maxcolspercommoditylimit;
1080 int *ncolspercommodity;
1081 int *maxcolspercommodity;
1091 capacityrowsigns = mcfdata->capacityrowsigns;
1092 capacityrowscores = mcfdata->capacityrowscores;
1093 capacitycands = mcfdata->capacitycands;
1095 assert(mcfdata->ncapacitycands == 0);
1105 maxcolspercommoditylimit = 2;
1108 maxcolspercommoditylimit = 1;
1111 maxcolspercommoditylimit = 2;
1114 SCIPerrorMessage(
"invalid parameter value %d for model type\n", modeltype);
1118 maxdualcapacity = 0.0;
1119 directedcandsscore = 0.0;
1120 undirectedcandsscore = 0.0;
1121 for( r = 0; r < nrows; r++ )
1131 int nposcapacitycoefs;
1132 int nnegcapacitycoefs;
1134 int ncoveredcommodities;
1139 unsigned char rowsign;
1145 capacityrowsigns[
r] = 0;
1146 capacityrowscores[
r] = 0.0;
1165 absdualsol =
ABS(absdualsol);
1174 maxcolspercommodity[
r] = 0;
1179 nposcapacitycoefs = 0;
1180 nnegcapacitycoefs = 0;
1182 ncoveredcommodities = 0;
1184 sameabsflowcoef = 0.0;
1185 maxabscapacitycoef = 0.0;
1192 for( i = 0; i < rowlen; i++ )
1201 k = colcommodity[c];
1202 assert(-1 <= k && k < ncommodities);
1207 abscoef =
ABS(rowvals[i]);
1208 if( sameflowcoef == 0.0 )
1209 sameflowcoef = rowvals[i];
1210 else if( !
SCIPisEQ(scip, sameflowcoef, rowvals[i]) )
1212 if( sameabsflowcoef == 0.0 )
1213 sameabsflowcoef = abscoef;
1214 else if( !
SCIPisEQ(scip, sameabsflowcoef, abscoef) )
1217 if( rowvals[i] > 0.0 )
1223 if( ncolspercommodity[k] == 0 )
1224 ncoveredcommodities++;
1225 ncolspercommodity[k]++;
1226 maxcolspercommodity[
r] =
MAX(maxcolspercommodity[r], ncolspercommodity[k]);
1228 if( ncolspercommodity[k] >= 2 )
1237 abscoef =
ABS(rowvals[i]);
1238 if( abscoef > maxabscapacitycoef )
1239 maxabscapacitycoef = abscoef;
1242 if( rowvals[i] > 0.0 )
1243 nposcapacitycoefs++;
1245 nnegcapacitycoefs++;
1255 if( rowsign != 0 && nposflowcoefs + nnegflowcoefs > 0 )
1259 capacityrowsigns[
r] |= rowsign;
1260 capacitycands[mcfdata->ncapacitycands] =
r;
1261 mcfdata->ncapacitycands++;
1264 capacityrowscores[
r] = 1.0;
1268 assert(ncoveredcommodities > 0);
1269 commodityexcessratio =
1270 ABS((nposflowcoefs + nnegflowcoefs)/(
SCIP_Real)ncoveredcommodities - maxcolspercommoditylimit);
1272 capacityrowscores[
r] += 1000.0 *
MAX(0.0, 2.0 - commodityexcessratio);
1279 if( (capacityrowsigns[r] &
RHSPOSSIBLE) != 0 && nnegflowcoefs == 0 && nposcapacitycoefs == 0 && nnegcapacitycoefs > 0 )
1280 capacityrowscores[
r] += 1000.0;
1281 if( (capacityrowsigns[r] &
LHSPOSSIBLE) != 0 && nposflowcoefs == 0 && nposcapacitycoefs > 0 && nnegcapacitycoefs == 0 )
1282 capacityrowscores[
r] += 1000.0;
1291 assert(nactivecommodities + 3 > 0);
1292 capacityrowscores[
r] += 2000.0 * ncoveredcommodities/(
SCIP_Real)(nactivecommodities + 3);
1296 capacityrowscores[r] += 500.0;
1300 capacityrowscores[
r] += 250.0;
1303 if(
SCIPisEQ(scip, sameabsflowcoef, 1.0) )
1304 capacityrowscores[r] += 100.0;
1307 if( maxabscapacitycoef > 0.0 && !
SCIPisEQ(scip, maxabscapacitycoef, 1.0) )
1308 capacityrowscores[r] += 100.0;
1311 capacityrowscores[
r] += 20.0 *
MAX(nposflowcoefs, nnegflowcoefs)/
MAX(1.0,(
SCIP_Real)(nposflowcoefs + nnegflowcoefs));
1314 capacityrowscores[
r] += 10.0 *
MAX(nposcapacitycoefs, nnegcapacitycoefs)/(
SCIP_Real)(nposcapacitycoefs+nnegcapacitycoefs+1.0);
1317 if( (capacityrowsigns[r] & RHSPOSSIBLE) != 0 && !
SCIPisNegative(scip, rowrhs) )
1318 capacityrowscores[r] += 10.0;
1322 capacityrowscores[r] += 10.0;
1324 assert(capacityrowscores[r] > 0.0);
1325 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",
1326 SCIProwGetName(row), maxcolspercommodity[r], capacityrowsigns[r], nposflowcoefs, nnegflowcoefs, nposcapacitycoefs, nnegcapacitycoefs, nbadcoefs, nactivecommodities, sameflowcoef, capacityrowscores[r]);
1329 maxdualcapacity =
MAX(maxdualcapacity, absdualsol);
1334 assert(maxcolspercommoditylimit == 2);
1335 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1336 undirectedcandsscore += capacityrowscores[
r];
1338 directedcandsscore += capacityrowscores[
r];
1343 SCIPdebugMsg(scip,
"row <%s>: rowsign = %d nposflowcoefs = %d nnegflowcoefs = %d -> discard\n",
1351 if( directedcandsscore > undirectedcandsscore )
1356 MCFdebugMessage(
"detected model type: %s (%g directed score, %g undirected score)\n",
1364 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1366 r = capacitycands[i];
1367 assert(0 <= r && r < nrows);
1368 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1371 if( maxcolspercommodity[r] <= maxcolspercommoditylimit )
1372 capacityrowscores[
r] -= 1000.0;
1386 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1390 r = capacitycands[i];
1391 assert(0 <= r && r < nrows);
1396 dualsol =
ABS(dualsol);
1399 assert(maxdualcapacity > 0.0);
1400 capacityrowscores[
r] +=
MAX(dualsol, 0.0)/maxdualcapacity;
1401 assert(capacityrowscores[r] > 0.0);
1406 SCIPsortInd(mcfdata->capacitycands, compCands, (
void*)capacityrowscores, mcfdata->ncapacitycands);
1408 MCFdebugMessage(
"capacity candidates [%d]\n", mcfdata->ncapacitycands);
1410 for( r = 0; r < mcfdata->ncapacitycands; r++ )
1412 SCIPdebugMsg(scip,
"row %4d [score: %2g]: %s\n", mcfdata->capacitycands[r],
1413 capacityrowscores[mcfdata->capacitycands[r]],
SCIProwGetName(rows[mcfdata->capacitycands[r]]));
1433 assert(mcfdata->ncommodities <= mcfdata->commoditysignssize);
1434 if( mcfdata->ncommodities == mcfdata->commoditysignssize )
1436 mcfdata->commoditysignssize =
MAX(2*mcfdata->commoditysignssize, mcfdata->ncommodities+1);
1439 assert(mcfdata->ncommodities < mcfdata->commoditysignssize);
1442 SCIPdebugMsg(scip,
"**** creating new commodity %d ****\n", mcfdata->ncommodities);
1443 mcfdata->commoditysigns[mcfdata->ncommodities] = 0;
1444 mcfdata->ncommodities++;
1459 assert(source != target );
1460 assert(0 <= source && source < mcfdata->
nnodes);
1461 assert(0 <= target && target < mcfdata->nnodes);
1462 assert(newarcid !=
NULL);
1464 *newarcid = mcfdata->narcs;
1467 assert(mcfdata->narcs <= mcfdata->arcarraysize);
1468 if( mcfdata->narcs == mcfdata->arcarraysize )
1470 mcfdata->arcarraysize =
MAX(2*mcfdata->arcarraysize, mcfdata->narcs+1);
1476 assert(mcfdata->narcs < mcfdata->arcarraysize);
1479 if( mcfdata->capacityrowssize < mcfdata->arcarraysize )
1481 mcfdata->capacityrowssize = mcfdata->arcarraysize;
1484 assert(mcfdata->narcs < mcfdata->capacityrowssize);
1487 SCIPdebugMsg(scip,
"**** creating new arc %d: %d -> %d ****\n", mcfdata->narcs, source, target);
1489 mcfdata->arcsources[*newarcid] = source;
1490 mcfdata->arctargets[*newarcid] = target;
1491 mcfdata->nextoutarcs[*newarcid] = mcfdata->firstoutarcs[source];
1492 mcfdata->firstoutarcs[source] = *newarcid;
1493 mcfdata->nextinarcs[*newarcid] = mcfdata->firstinarcs[target];
1494 mcfdata->firstinarcs[target] = *newarcid;
1495 mcfdata->capacityrows[*newarcid] =
NULL;
1508 unsigned char rowsign,
1513 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1514 SCIP_Bool* plusflow = mcfdata->plusflow;
1515 SCIP_Bool* minusflow = mcfdata->minusflow;
1517 int* commoditysigns = mcfdata->commoditysigns;
1519 int* rowcommodity = mcfdata->rowcommodity;
1520 int* newcols = mcfdata->newcols;
1531 assert(comcolids !=
NULL);
1532 assert(ncomcolids !=
NULL);
1541 invertrow = ((rowsign &
INVERTED) != 0);
1544 assert(rowcommodity[r] == -1);
1545 assert((flowrowsigns[r] | rowsign) == flowrowsigns[r]);
1547 assert(rowsign != 0);
1553 commoditysigns[k] = +1;
1582 else if( rowlhs > 0.0 )
1599 flowrowsigns[
r] |= rowsign;
1601 SCIPdebugMsg(scip,
"adding flow row %d <%s> with sign %+d%s to commodity %d [score:%g]\n",
1603 k, mcfdata->flowrowscores[r]);
1607 rowcommodity[
r] = k;
1611 for( i = 0; i < rowlen; i++ )
1620 if( colcommodity[c] == -1 )
1622 assert(!plusflow[c]);
1623 assert(!minusflow[c]);
1625 colcommodity[c] = k;
1626 newcols[mcfdata->nnewcols] = c;
1627 mcfdata->nnewcols++;
1628 comcolids[*ncomcolids] = c;
1631 assert(colcommodity[c] == k);
1634 val = rowscale * rowvals[i];
1637 assert(!plusflow[c]);
1642 assert(!minusflow[c]);
1643 minusflow[c] =
TRUE;
1660 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1661 SCIP_Bool* plusflow = mcfdata->plusflow;
1662 SCIP_Bool* minusflow = mcfdata->minusflow;
1666 assert(mcfdata->commoditysigns[k] == 0);
1667 assert(comrows !=
NULL || ncomrows == 0);
1668 assert(comcolids !=
NULL);
1671 for( i = 0; i < ncomrows; i++ )
1675 unsigned char rowsign;
1677 assert(comrows !=
NULL);
1679 assert( row !=
NULL );
1682 assert(mcfdata->rowcommodity[r] == k);
1686 rowsign = flowrowsigns[
r];
1698 for( i = 0; i < ncomcolids; i++ )
1705 assert(mcfdata->colcommodity[c] == k);
1708 plusflow[c] = minusflow[c];
1725 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1726 SCIP_Bool* plusflow = mcfdata->plusflow;
1727 SCIP_Bool* minusflow = mcfdata->minusflow;
1730 int* rowcommodity = mcfdata->rowcommodity;
1734 assert(0 <= k && k < ncommodities);
1736 assert( ndelflowrows !=
NULL );
1737 assert( ndelflowvars !=
NULL );
1739 SCIPdebugMsg(scip,
"deleting commodity %d (%d total commodities) with %d flow rows\n", k, ncommodities, nrows);
1744 for( n = 0; n < nrows; n++ )
1755 assert(rowcommodity[r] == k);
1764 rowcommodity[
r] = -1;
1767 for( i = 0; i < rowlen; i++ )
1775 assert(colcommodity[c] == k || colcommodity[c] == -1);
1776 if(colcommodity[c] == k)
1778 colcommodity[c] = -1;
1781 plusflow[c] =
FALSE;
1782 minusflow[c] =
FALSE;
1791 if( k == ncommodities-1 )
1792 mcfdata->ncommodities--;
1794 mcfdata->nemptycommodities++;
1804 unsigned char* rowsign,
1808 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1809 SCIP_Bool* plusflow = mcfdata->plusflow;
1810 SCIP_Bool* minusflow = mcfdata->minusflow;
1812 int* rowcommodity = mcfdata->rowcommodity;
1813 int* commoditysigns = mcfdata->commoditysigns;
1818 unsigned char flowrowsign;
1819 unsigned char invflowrowsign;
1823 assert(invertcommodity !=
NULL);
1826 *invertcommodity =
FALSE;
1832 if( rowcommodity[r] != -1 )
1836 flowrowsign = flowrowsigns[
r];
1842 invflowrowsign = flowrowsign;
1848 for( j = 0; j < rowlen && (flowrowsign != 0 || invflowrowsign != 0); j++ )
1856 if( colcommodity[rowc] == k )
1859 if( plusflow[rowc] )
1862 if( rowvals[j] > 0.0 )
1873 if( minusflow[rowc] )
1876 if( rowvals[j] > 0.0 )
1888 else if( colcommodity[rowc] != -1 )
1896 if( flowrowsign != 0 )
1899 *rowsign = flowrowsign;
1900 *invertcommodity =
FALSE;
1902 else if( invflowrowsign != 0 )
1908 if( commoditysigns ==
NULL || commoditysigns[k] == 0 )
1911 *rowsign = invflowrowsign;
1912 *invertcommodity =
TRUE;
1917 *rowsign = (invflowrowsign |
INVERTED);
1918 *invertcommodity =
FALSE;
1935 unsigned char* nextrowsign,
1939 SCIP_Real* flowrowscores = mcfdata->flowrowscores;
1940 SCIP_Bool* plusflow = mcfdata->plusflow;
1941 SCIP_Bool* minusflow = mcfdata->minusflow;
1942 int* newcols = mcfdata->newcols;
1948 assert(nextrow !=
NULL);
1949 assert(nextrowsign !=
NULL);
1953 *nextinvertcommodity =
FALSE;
1958 assert(cols !=
NULL);
1961 while( mcfdata->nnewcols > 0 )
1967 unsigned char bestrowsign;
1974 c = newcols[mcfdata->nnewcols-1];
1975 mcfdata->nnewcols--;
1979 assert(plusflow[c] || minusflow[c]);
1980 if( plusflow[c] && minusflow[c] )
1986 bestinvertcommodity =
FALSE;
1991 for( i = 0; i < collen; i++ )
1994 unsigned char flowrowsign;
2000 getFlowrowFit(scip, mcfdata, row, k, &flowrowsign, &invertcommodity);
2003 if( flowrowsign != 0 )
2010 score = flowrowscores[
r];
2011 assert(score > 0.0);
2017 if( (flowrowsign &
INVERTED) != 0 )
2020 if( score > bestscore )
2023 bestrowsign = flowrowsign;
2024 bestinvertcommodity = invertcommodity;
2034 if( bestrow !=
NULL )
2036 assert(bestscore > 0.0);
2037 assert(bestrowsign != 0);
2039 *nextrowsign = bestrowsign;
2040 *nextinvertcommodity = bestinvertcommodity;
2055 int* flowcands = mcfdata->flowcands;
2082 assert(failed !=
NULL);
2091 plusflow = mcfdata->plusflow;
2092 minusflow = mcfdata->minusflow;
2093 colcommodity = mcfdata->colcommodity;
2094 rowcommodity = mcfdata->rowcommodity;
2106 for( c = 0; c < ncols; c++ )
2107 colcommodity[c] = -1;
2108 for( r = 0; r < nrows; r++ )
2109 rowcommodity[r] = -1;
2111 assert(flowcands !=
NULL || mcfdata->nflowcands == 0);
2122 for( i = 0; i < mcfdata->nflowcands; i++ )
2125 unsigned char newrowsign;
2129 assert(flowcands !=
NULL);
2131 assert(0 <= r && r < nrows);
2135 getFlowrowFit(scip, mcfdata, newrow, mcfdata->ncommodities, &newrowsign, &newinvertcommodity);
2136 if( newrowsign == 0 )
2138 assert(!newinvertcommodity);
2139 assert((newrowsign &
INVERTED) == 0);
2142 SCIPdebugMsg(scip,
" -------------------start new commodity %d--------------------- \n", mcfdata->ncommodities );
2151 if( newinvertcommodity )
2152 invertCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, comcolids, ncomcolids);
2157 comrows[
nnodes] = newrow;
2162 getNextFlowrow(scip, mcfdata, &newrow, &newrowsign, &newinvertcommodity);
2164 while( newrow !=
NULL );
2166 ncomnodes[mcfdata->ncommodities-1] =
nnodes;
2167 maxnnodes =
MAX(maxnnodes, nnodes);
2168 nflowvars += ncomcolids;
2169 SCIPdebugMsg(scip,
" -> finished commodity %d: identified %d nodes, maxnnodes=%d\n", mcfdata->ncommodities-1, nnodes, maxnnodes);
2177 deleteCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2178 nflowrows -= ndelflowrows;
2179 nflowvars -= ndelflowvars;
2180 assert(nflowvars >= 0);
2181 assert(nflowrows >= 0);
2185 for( k = 0; k < mcfdata->ncommodities; k++ )
2197 for( i = 0; i < mcfdata->nflowcands; i++ )
2199 assert(flowcands !=
NULL);
2201 if( rowcommodity[r] == k )
2206 if( nnodes == ncomnodes[k] )
2211 assert(nnodes == ncomnodes[k]);
2212 deleteCommodity(scip, mcfdata, k, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2213 nflowrows -= ndelflowrows;
2214 nflowvars -= ndelflowvars;
2215 assert(nflowvars >= 0);
2216 assert(nflowrows >= 0);
2225 MCFdebugMessage(
"identified %d commodities (%d empty) with a maximum of %d nodes and %d flowrows, %d flowvars \n",
2226 mcfdata->ncommodities, mcfdata->nemptycommodities, maxnnodes, nflowrows, nflowvars);
2228 assert(nflowvars >= 0);
2229 assert(nflowrows >= 0);
2247 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
2250 unsigned char* flowrowsigns = mcfdata->capacityrowsigns;
2251 int* rowcommodity = mcfdata->rowcommodity;
2267 SCIP_Real* capacityrowscores = mcfdata->capacityrowscores;
2269 int *capacitycands = mcfdata->capacitycands;
2270 int ncapacitycands = mcfdata->ncapacitycands;
2272 assert(mcfdata->narcs == 0);
2273 assert(capacitycands !=
NULL || ncapacitycands == 0);
2282 colarcid = mcfdata->colarcid;
2283 rowarcid = mcfdata->rowarcid;
2286 for( c = 0; c < ncols; c++ )
2288 for( r = 0; r < nrows; r++ )
2292 for( i = 0; i < ncapacitycands; i++ )
2297 int nassignedflowvars;
2298 int nunassignedflowvars;
2301 assert(capacitycands !=
NULL);
2302 r = capacitycands[i];
2303 assert(0 <= r && r < nrows );
2304 capacityrow = rows[
r];
2308 assert((capacityrowsigns[r] &
DISCARDED) == 0);
2309 assert(capacityrowscores[r] > 0.0);
2313 assert(rowarcid[r] == -1);
2316 assert( rowcommodity[r] == -1 );
2322 nassignedflowvars = 0;
2323 nunassignedflowvars = 0;
2324 for( k = 0; k < rowlen; k++ )
2327 assert(0 <= c && c < ncols);
2329 assert(-1 <= colcommodity[c] && colcommodity[c] < mcfdata->ncommodities);
2330 assert(-1 <= colarcid[c] && colarcid[c] < mcfdata->narcs);
2333 if( colcommodity[c] == -1 )
2337 if( colarcid[c] >= 0 )
2338 nassignedflowvars++;
2340 nunassignedflowvars++;
2347 if( nunassignedflowvars == 0 || nassignedflowvars >= nunassignedflowvars * 2 )
2349 SCIPdebugMsg(scip,
"discarding capacity candidate row %d <%s> [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2350 r,
SCIProwGetName(capacityrow), mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2356 assert(mcfdata->narcs <= mcfdata->capacityrowssize);
2357 if( mcfdata->narcs == mcfdata->capacityrowssize )
2359 mcfdata->capacityrowssize =
MAX(2*mcfdata->capacityrowssize, mcfdata->narcs+1);
2362 assert(mcfdata->narcs < mcfdata->capacityrowssize);
2363 assert(mcfdata->narcs < nrows);
2365 mcfdata->capacityrows[mcfdata->narcs] = capacityrow;
2368 assert(0 <= r && r < nrows);
2369 rowarcid[
r] = mcfdata->narcs;
2380 SCIPdebugMsg(scip,
"assigning capacity row %d <%s> with sign %+d to arc %d [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2382 mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2385 for( k = 0; k < rowlen; k++ )
2388 assert(0 <= rowc && rowc < ncols);
2393 if( colcommodity[rowc] >= 0 && colarcid[rowc] == -1 )
2394 colarcid[rowc] = mcfdata->narcs;
2414 int* colarcid = mcfdata->colarcid;
2415 int* newcols = mcfdata->newcols;
2416 SCIP_ROW** capacityrows = mcfdata->capacityrows;
2417 SCIP_Bool* colisincident = mcfdata->colisincident;
2426 assert(!colisincident[i]);
2432 mcfdata->nnewcols = 0;
2434 for( i = 0; i < rowlen; i++ )
2446 arcid = colarcid[c];
2449 assert(arcid < mcfdata->
narcs);
2452 assert(capacityrows[arcid] !=
NULL);
2456 for( j = 0; j < capacityrowlen; j++ )
2464 if( colcommodity[caprowc] == -1 )
2466 assert(colarcid[caprowc] == -1);
2469 assert(colarcid[caprowc] <= arcid);
2472 if( colcommodity[caprowc] == basecommodity )
2476 if( !colisincident[caprowc] )
2478 assert(mcfdata->nnewcols < SCIPgetNLPCols(scip));
2479 colisincident[caprowc] =
TRUE;
2480 newcols[mcfdata->nnewcols] = caprowc;
2481 mcfdata->nnewcols++;
2495 int* basearcpattern,
2504 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2505 int* commoditysigns = mcfdata->commoditysigns;
2506 int narcs = mcfdata->narcs;
2507 int* rowcommodity = mcfdata->rowcommodity;
2508 int* colarcid = mcfdata->colarcid;
2509 int* arcpattern = mcfdata->zeroarcarray;
2522 int* overlappingarcs;
2523 int noverlappingarcs;
2528 *invertcommodity =
FALSE;
2531 for( i = 0; i <
narcs; i++ )
2532 assert(arcpattern[i] == 0);
2541 rowcom = rowcommodity[
r];
2543 rowcomsign = commoditysigns[rowcom];
2544 assert(-1 <= rowcomsign && rowcomsign <= +1);
2549 incompatible =
FALSE;
2550 noverlappingarcs = 0;
2554 for( i = 0; i < rowlen; i++ )
2564 valsign = (rowvals[i] > 0.0 ? +1 : -1);
2567 if( (flowrowsigns[r] &
INVERTED) != 0 )
2570 arcid = colarcid[c];
2579 assert(arcid < narcs);
2582 if( basearcpattern[arcid] != 0 )
2589 if( ( valsign * basearcpattern[arcid] ) > 0 )
2594 if( rowcomsign == 0 )
2597 rowcomsign = validcomsign;
2599 else if( rowcomsign != validcomsign )
2602 incompatible =
TRUE;
2613 if( arcpattern[arcid] == 0 )
2615 overlappingarcs[noverlappingarcs] = arcid;
2618 arcpattern[arcid] += valsign;
2624 for( i = 0; i < noverlappingarcs; i++ )
2630 arcid = overlappingarcs[i];
2631 assert(0 <= arcid && arcid < narcs);
2634 basenum =
ABS(basearcpattern[arcid]);
2635 arcnum =
ABS(arcpattern[arcid]);
2636 assert(basenum != 0.0);
2637 assert(arcnum != 0.0);
2639 if( basenum > arcnum )
2640 overlap += arcnum/basenum;
2642 overlap += basenum/arcnum;
2644 arcpattern[arcid] = 0;
2648 if( !incompatible && overlap > 0.0 )
2651 int rowarcs = rowlen - nposuncap - nneguncap;
2652 int baserowarcs = baserowlen - basenposuncap - basenneguncap;
2655 assert(overlap <= (
SCIP_Real) baserowlen);
2656 assert(noverlappingarcs >= 1);
2658 *invertcommodity = (rowcomsign == -1);
2662 if( noverlappingarcs >= 2 )
2665 assert(rowarcs >= 0 && baserowarcs >= 0 );
2668 *score = overlap - (rowarcs + baserowarcs - 2.0 * overlap)/(2.0 * ncols + 1.0);
2670 *score = overlap - (rowarcs + baserowarcs - 4.0 * overlap)/(2.0 * ncols + 1.0);
2673 if(*invertcommodity)
2674 *score += 1.0 - (
ABS(nneguncap - basenposuncap) +
ABS(nposuncap - basenneguncap))/(2.0 * ncols + 1.0);
2676 *score += 1.0 - (
ABS(nposuncap - basenposuncap) +
ABS(nneguncap - basenneguncap))/(2.0 * ncols + 1.0);
2678 *score =
MAX(*score, 1e-6);
2681 SCIPdebugMsg(scip,
" -> node similarity: row <%s>: incompatible=%u overlap=%g rowlen=%d baserowlen=%d score=%g\n",
2682 SCIProwGetName(row), incompatible, overlap, rowlen, baserowlen, *score);
2697 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2699 int* commoditysigns = mcfdata->commoditysigns;
2700 int narcs = mcfdata->narcs;
2701 int* flowcands = mcfdata->flowcands;
2702 int nflowcands = mcfdata->nflowcands;
2703 int* rowcommodity = mcfdata->rowcommodity;
2704 int* colarcid = mcfdata->colarcid;
2705 int* newcols = mcfdata->newcols;
2726 assert(mcfdata->nnodes == 0);
2738 rownodeid = mcfdata->rownodeid;
2739 colisincident = mcfdata->colisincident;
2749 for( r = 0; r < nrows; r++ )
2751 for( c = 0; c < ncols; c++ )
2752 colisincident[c] =
FALSE;
2754 assert(flowcands !=
NULL || nflowcands == 0);
2757 for( n = 0; n < nflowcands; n++ )
2766 assert(flowcands !=
NULL);
2768 assert(0 <= r && r < nrows);
2771 basecommodity = rowcommodity[
r];
2772 if( basecommodity == -1 )
2775 assert(mcfdata->rowarcid[r] == -1);
2778 if( rownodeid[r] >= 0 )
2782 SCIPdebugMsg(scip,
"assigning row %d <%s> of commodity %d to node %d [score: %g]\n",
2783 r,
SCIProwGetName(rows[r]), basecommodity, mcfdata->nnodes, mcfdata->flowrowscores[r]);
2784 rownodeid[
r] = mcfdata->nnodes;
2792 if(ncommodities == 1)
2807 if( (flowrowsigns[r] &
INVERTED) != 0 )
2809 if( commoditysigns[basecommodity] == -1 )
2812 for( i = 0; i < rowlen; i++ )
2817 assert(0 <= c && c < ncols);
2818 arcid = colarcid[c];
2823 arcpattern[arcid]++;
2825 arcpattern[arcid]--;
2840 bestflowrows[i] =
NULL;
2841 bestscores[i] = 0.0;
2842 bestinverted[i] =
FALSE;
2854 for( i = 0; i < mcfdata->nnewcols; i++ )
2861 assert(0 <= c && c < ncols);
2862 assert(mcfdata->colcommodity[c] >= 0);
2863 assert(mcfdata->colcommodity[c] != basecommodity);
2866 assert(colisincident[c]);
2867 colisincident[c] =
FALSE;
2873 for( j = 0; j < collen; j++ )
2881 assert(0 <= colr && colr < nrows);
2884 if( rowprocessed[colr] )
2886 rowprocessed[colr] =
TRUE;
2889 rowcom = rowcommodity[colr];
2890 assert(rowcom != basecommodity);
2894 assert(rowcom == mcfdata->colcommodity[c]);
2895 assert((flowrowsigns[colr] & (
LHSASSIGNED | RHSASSIGNED)) != 0);
2896 assert(mcfdata->rowarcid[colr] == -1);
2899 if( rownodeid[colr] >= 0 )
2904 nposuncap, nneguncap, colrows[j], &score, &invertcommodity) );
2907 if( score > bestscores[rowcom] )
2909 bestflowrows[rowcom] = colrows[j];
2910 bestscores[rowcom] = score;
2911 bestinverted[rowcom] = invertcommodity;
2915 assert(bestflowrows[basecommodity] ==
NULL);
2922 if( bestflowrows[i] ==
NULL )
2926 assert(0 <= comr && comr < nrows);
2927 assert(rowcommodity[comr] == i);
2928 assert((flowrowsigns[comr] & (
LHSASSIGNED | RHSASSIGNED)) != 0);
2929 assert(rownodeid[comr] == -1);
2930 assert(mcfdata->nnodes >= 1);
2932 SCIPdebugMsg(scip,
" -> assigning row %d <%s> of commodity %d to node %d [invert:%u]\n",
2933 comr,
SCIProwGetName(rows[comr]), i, mcfdata->nnodes-1, bestinverted[i]);
2934 rownodeid[comr] = mcfdata->nnodes-1;
2937 if( bestinverted[i] )
2939 assert(commoditysigns[i] != +1);
2940 commoditysigns[i] = -1;
2944 assert(commoditysigns[i] != -1);
2945 commoditysigns[i] = +1;
2968 int* commoditysigns = mcfdata->commoditysigns;
2971 for( k = 0; k < mcfdata->ncommodities; k++ )
2973 if( commoditysigns[k] == 0 )
2974 commoditysigns[k] = +1;
2989 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2990 int* commoditysigns = mcfdata->commoditysigns;
2991 int* rowcommodity = mcfdata->rowcommodity;
2992 int* rownodeid = mcfdata->rownodeid;
2993 int* colsources = mcfdata->colsources;
2994 int* coltargets = mcfdata->coltargets;
3002 assert(sourcenode !=
NULL);
3003 assert(targetnode !=
NULL);
3004 assert(colsources !=
NULL);
3005 assert(coltargets !=
NULL);
3011 if( colsources[c] >= -1 )
3013 assert(coltargets[c] >= -1);
3014 *sourcenode = colsources[c];
3015 *targetnode = coltargets[c];
3026 for( i = 0; i < collen; i++ )
3033 if( rownodeid[r] >= 0 )
3040 k = rowcommodity[
r];
3041 assert(0 <= v && v < mcfdata->
nnodes);
3049 if( (flowrowsigns[r] &
INVERTED) != 0 )
3051 if( commoditysigns[k] == -1 )
3055 if( ( scale * colvals[i] ) > 0.0 )
3057 assert(*sourcenode == -1);
3059 if( *targetnode >= 0 )
3064 assert(*targetnode == -1);
3066 if( *sourcenode >= 0 )
3073 colsources[c] = *sourcenode;
3074 coltargets[c] = *targetnode;
3085 int* flowcands = mcfdata->flowcands;
3086 int nflowcands = mcfdata->nflowcands;
3088 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3090 int* rowcommodity = mcfdata->rowcommodity;
3092 int* rownodeid = mcfdata->rownodeid;
3093 int* colarcid = mcfdata->colarcid;
3094 int nnodes = mcfdata->nnodes;
3102 int* sortedflowcands;
3103 int* sortedflowcandnodeid;
3116 assert(mcfdata->nemptycommodities == 0);
3117 assert(ncommodities >= 0);
3121 if( ncommodities == 0 || nflowcands == 0 || nnodes == 0 )
3130 assert(rows !=
NULL);
3131 assert(cols !=
NULL || ncols == 0);
3142 for( n = 0; n < nflowcands; n++ )
3144 sortedflowcands[n] = flowcands[n];
3145 sortedflowcandnodeid[n] = rownodeid[flowcands[n]];
3149 SCIPsortIntInt(sortedflowcandnodeid, sortedflowcands, nflowcands);
3150 assert(sortedflowcandnodeid[0] <= 0);
3151 assert(sortedflowcandnodeid[nflowcands-1] == nnodes-1);
3154 for( v = 0; v <
nnodes; v++ )
3170 for( n = 0; n < nflowcands; n++ )
3172 if( sortedflowcandnodeid[n] >= 0 )
3174 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3175 assert(rowcommodity[sortedflowcands[n]] == -1);
3177 assert(n < nflowcands);
3178 assert(sortedflowcandnodeid[n] == 0);
3183 for( v = 0; n < nflowcands; v++ )
3188 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3189 assert(rowcommodity[sortedflowcands[n]] >= 0);
3190 assert(rownodeid[sortedflowcands[n]] == sortedflowcandnodeid[n]);
3191 assert(sortedflowcandnodeid[n] == v);
3192 assert(nadjnodes == 0);
3193 assert(ninccols == 0);
3198 for( ; n < nflowcands && sortedflowcandnodeid[n] == v; n++ )
3205 r = sortedflowcands[n];
3207 assert(mcfdata->rowarcid[r] == -1);
3212 for( i = 0; i < rowlen; i++ )
3223 arcid = colarcid[c];
3224 assert(-2 <= arcid && arcid < mcfdata->
narcs);
3225 assert(rowcommodity[r] == colcommodity[c]);
3235 else if( arcid == -1 )
3245 assert(-1 <= s && s < nnodes);
3246 assert(-1 <= t && t < nnodes);
3247 assert(s == v || t == v);
3258 if( s < 0 || t < 0 )
3266 assert(ninccols < ncols);
3267 inccols[ninccols] = c;
3283 if( sourcecount[u] + targetcount[u] == 1 )
3285 assert(nadjnodes < nnodes);
3286 adjnodes[nadjnodes] = u;
3294 for( l = 0; l < nadjnodes; l++ )
3299 assert(0 <= u && u < nnodes);
3300 assert(sourcecount[u] > 0 || targetcount[u] > 0);
3302 assert(ninccols >= 0);
3305 if( sourcecount[u] >= arcsthreshold )
3312 SCIPdebugMsg(scip,
" -> new arc: <%i> = (%i,%i)\n", arcid, u, v);
3315 for( m = 0; m < ninccols; m++ )
3322 assert(0 <= c && c < ncols);
3324 assert(cols !=
NULL);
3326 assert(s == v || t == v);
3331 colarcid[c] = arcid;
3334 inccols[m] = inccols[ninccols-1];
3342 if( targetcount[u] >= arcsthreshold )
3349 SCIPdebugMsg(scip,
" -> new arc: <%i> = (%i,%i)\n", arcid, v, u);
3352 for( m = 0; m < ninccols; m++ )
3359 assert(0 <= c && c < ncols);
3361 assert(cols !=
NULL);
3363 assert(s == v || t == v);
3368 colarcid[c] = arcid;
3371 inccols[m] = inccols[ninccols-1];
3380 for( l = 0; l < nadjnodes; l++ )
3388 for( l = 0; l < ninccols; l++ )
3390 assert(colarcid[inccols[l]] == -1);
3391 colarcid[inccols[l]] = -2;
3395 assert(n == nflowcands);
3396 assert(v == nnodes);
3400 for( n = 0; n < ncols; n++ )
3401 assert(colarcid[n] >= -1);
3412 MCFdebugMessage(
"network after finding uncapacitated arcs has %d nodes, %d arcs, and %d commodities\n",
3413 mcfdata->nnodes, mcfdata->narcs, mcfdata->ncommodities);
3425 int* flowcands = mcfdata->flowcands;
3426 int nflowcands = mcfdata->nflowcands;
3428 int* rowcommodity = mcfdata->rowcommodity;
3429 int* colarcid = mcfdata->colarcid;
3430 int* rowarcid = mcfdata->rowarcid;
3431 int* rownodeid = mcfdata->rownodeid;
3433 int* commoditysigns = mcfdata->commoditysigns;
3434 int narcs = mcfdata->narcs;
3435 int nnodes = mcfdata->nnodes;
3436 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3448 int nnodesthreshold;
3449 int newncommodities;
3455 MCFdebugMessage(
"network before cleanup has %d nodes, %d arcs, and %d commodities\n", nnodes, narcs, ncommodities);
3463 permsize =
MAX(permsize, narcs);
3464 permsize =
MAX(permsize, nnodes);
3474 assert(flowcands !=
NULL || nflowcands == 0);
3477 for( i = 0; i < nflowcands; i++ )
3481 assert(flowcands !=
NULL);
3483 assert(0 <= r && r < nrows);
3484 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3485 if( rowcommodity[r] >= 0 )
3487 assert(rowcommodity[r] < ncommodities);
3488 nnodespercom[rowcommodity[
r]]++;
3492 assert(capacityrows !=
NULL || narcs == 0);
3495 for( a = 0; a <
narcs; a++ )
3502 assert(capacityrows !=
NULL);
3504 assert(0 <= r && r < nrows);
3505 assert(rowarcid[r] == a);
3511 for( j = 0; j < rowlen; j++ )
3516 assert(0 <= c && c < ncols);
3517 if( colcommodity[c] >= 0 && colarcid[c] == a )
3519 assert(colcommodity[c] < ncommodities);
3520 arcisincom[colcommodity[c]] =
TRUE;
3535 maxnnodes =
MAX(maxnnodes, nnodespercom[k]);
3543 SCIPdebugMsg(scip,
" -> node threshold: %d\n", nnodesthreshold);
3546 newncommodities = 0;
3549 SCIPdebugMsg(scip,
" -> commodity %d: %d nodes, %d arcs\n", k, nnodespercom[k], narcspercom[k]);
3552 if( nnodespercom[k] >= nnodesthreshold && narcspercom[k] >= 1 )
3554 assert(newncommodities <= k);
3555 perm[k] = newncommodities;
3556 commoditysigns[newncommodities] = commoditysigns[k];
3563 if( newncommodities < ncommodities )
3572 SCIPdebugMsg(scip,
" -> discarding %d of %d commodities\n", ncommodities - newncommodities, ncommodities);
3580 for( c = 0; c < ncols; c++ )
3582 if( colcommodity[c] >= 0 )
3584 assert(-1 <= colarcid[c] && colarcid[c] < narcs);
3585 assert(colcommodity[c] < mcfdata->ncommodities);
3586 colcommodity[c] = perm[colcommodity[c]];
3587 assert(colcommodity[c] < newncommodities);
3588 if( colcommodity[c] == -1 )
3593 else if( colarcid[c] >= 0 )
3594 arcisused[colarcid[c]] =
TRUE;
3597 for( i = 0; i < nflowcands; i++ )
3601 assert(flowcands !=
NULL);
3603 assert(0 <= r && r < nrows);
3604 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3605 if( rowcommodity[r] >= 0 )
3607 assert(0 <= rownodeid[r] && rownodeid[r] < nnodes);
3608 assert(rowcommodity[r] < mcfdata->ncommodities);
3609 rowcommodity[
r] = perm[rowcommodity[
r]];
3610 assert(rowcommodity[r] < newncommodities);
3611 if( rowcommodity[r] == -1 )
3617 nodeisused[rownodeid[
r]] =
TRUE;
3621 mcfdata->ncommodities = newncommodities;
3622 ncommodities = newncommodities;
3626 for( a = 0; a <
narcs; a++ )
3630 assert(capacityrows !=
NULL);
3634 assert(newnarcs <= a);
3636 capacityrows[newnarcs] = capacityrows[
a];
3645 assert(0 <= r && r < nrows);
3646 assert(rowarcid[r] == a);
3647 rowarcid[
r] = perm[
a];
3651 if( newnarcs < narcs )
3653 SCIPdebugMsg(scip,
" -> discarding %d of %d arcs\n", narcs - newnarcs, narcs);
3655 for( c = 0; c < ncols; c++ )
3657 if( colarcid[c] >= 0 )
3659 colarcid[c] = perm[colarcid[c]];
3660 assert(colarcid[c] >= 0);
3663 mcfdata->narcs = newnarcs;
3667 for( a = 0; a <
narcs; a++ )
3670 assert(capacityrows !=
NULL);
3672 assert(0 <= r && r < nrows);
3673 assert(rowarcid[r] == a);
3679 for( v = 0; v <
nnodes; v++ )
3683 assert(newnnodes <= v);
3684 perm[v] = newnnodes;
3692 if( newnnodes < nnodes )
3694 SCIPdebugMsg(scip,
" -> discarding %d of %d nodes\n", nnodes - newnnodes, nnodes);
3696 for( i = 0; i < nflowcands; i++ )
3700 assert(flowcands !=
NULL);
3702 assert(0 <= r && r < nrows);
3703 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3704 if( rowcommodity[r] >= 0 )
3706 assert(rowcommodity[r] < ncommodities);
3707 rownodeid[
r] = perm[rownodeid[
r]];
3708 assert(rownodeid[r] >= 0);
3711 mcfdata->nnodes = newnnodes;
3723 mcfdata->nemptycommodities = 0;
3731 MCFdebugMessage(
"network after cleanup has %d nodes, %d arcs, and %d commodities\n", nnodes, narcs, ncommodities);
3745 int* colarcid = mcfdata->colarcid;
3747 int narcs = mcfdata->narcs;
3748 int nnodes = mcfdata->nnodes;
3750 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3752 SCIP_Real maxinconsistencyratio = sepadata->maxinconsistencyratio;
3753 SCIP_Real maxarcinconsistencyratio = sepadata->maxarcinconsistencyratio;
3765 int *flowvarspercom;
3778 assert(effortlevel !=
NULL);
3792 arcsources = mcfdata->arcsources;
3793 arctargets = mcfdata->arctargets;
3794 colsources = mcfdata->colsources;
3795 coltargets = mcfdata->coltargets;
3796 firstoutarcs = mcfdata->firstoutarcs;
3797 firstinarcs = mcfdata->firstinarcs;
3798 nextoutarcs = mcfdata->nextoutarcs;
3799 nextinarcs = mcfdata->nextinarcs;
3801 mcfdata->arcarraysize =
narcs;
3804 for( c = 0; c < ncols; c++ )
3811 for( v = 0; v <
nnodes; v++ )
3813 firstoutarcs[v] = -1;
3814 firstinarcs[v] = -1;
3816 for( a = 0; a <
narcs; a++ )
3818 nextoutarcs[
a] = -1;
3832 mcfdata->ninconsistencies = 0.0;
3833 maxninconsistencies = maxinconsistencyratio * (
SCIP_Real)narcs;
3836 for( a = 0; a <
narcs; a++ )
3858 assert(mcfdata->rowarcid[r] == a);
3861 for( i = 0; i <
nnodes; i++ )
3863 assert(sourcenodecnt[i] == 0);
3864 assert(targetnodecnt[i] == 0);
3875 for( i = 0; i < rowlen; i++ )
3879 if( colarcid[c] >= 0 )
3881 int k = colcommodity[c];
3882 assert (0 <= k && k < ncommodities);
3883 flowvarspercom[k]++;
3884 if( !comtouched[k] )
3887 comtouched[k] =
TRUE;
3893 if( ntouchedcoms == 0 )
3895 capacityrows[
a] =
NULL;
3903 totalsourcecnt = 0.0;
3904 totaltargetcnt = 0.0;
3906 for( i = 0; i < rowlen; i++ )
3910 if( colarcid[c] >= 0 )
3912 int k = colcommodity[c];
3917 assert (0 <= k && k < ncommodities);
3918 assert (comtouched[k]);
3919 assert (flowvarspercom[k] >= 1);
3925 weight = 1.0/flowvarspercom[k];
3928 if( sourcenodecnt[sourcev] == 0.0 && targetnodecnt[sourcev] == 0.0 )
3930 touchednodes[ntouchednodes] = sourcev;
3933 sourcenodecnt[sourcev] += weight;
3934 totalsourcecnt += weight;
3938 if( sourcenodecnt[targetv] == 0.0 && targetnodecnt[targetv] == 0.0 )
3940 touchednodes[ntouchednodes] = targetv;
3943 targetnodecnt[targetv] += weight;
3944 totaltargetcnt += weight;
3946 if( sourcev >= 0 || targetv >= 0 )
3947 totalnodecnt += weight;
3954 bestsourcecnt = 0.0;
3955 besttargetcnt = 0.0;
3956 for( i = 0; i < ntouchednodes; i++ )
3958 v = touchednodes[i];
3959 assert(0 <= v && v < nnodes);
3964 if( sourcenodecnt[v] >= targetnodecnt[v] )
3966 if( sourcenodecnt[v] > bestsourcecnt )
3969 bestsourcecnt = sourcenodecnt[v];
3974 if( targetnodecnt[v] > besttargetcnt )
3977 besttargetcnt = targetnodecnt[v];
3983 SCIP_Real nodecnt = sourcenodecnt[v] + targetnodecnt[v];
3987 if( nodecnt > bestsourcecnt )
3989 besttargetv = bestsourcev;
3990 besttargetcnt = bestsourcecnt;
3992 bestsourcecnt = nodecnt;
3994 else if( nodecnt > besttargetcnt )
3997 besttargetcnt = nodecnt;
4002 sourcenodecnt[v] = 0;
4003 targetnodecnt[v] = 0;
4009 totalsourcecnt = totalnodecnt;
4010 totaltargetcnt = totalnodecnt;
4012 assert(
SCIPisGE(scip,totalsourcecnt,bestsourcecnt));
4013 assert(
SCIPisGE(scip,totaltargetcnt,besttargetcnt));
4014 nsourceinconsistencies = (totalsourcecnt - bestsourcecnt)/ntouchedcoms;
4015 ntargetinconsistencies = (totaltargetcnt - besttargetcnt)/ntouchedcoms;
4018 if( nsourceinconsistencies > maxarcinconsistencyratio )
4024 if( ntargetinconsistencies > maxarcinconsistencyratio )
4031 assert(bestsourcev == -1 || bestsourcev != besttargetv);
4032 arcsources[
a] = bestsourcev;
4033 arctargets[
a] = besttargetv;
4034 SCIPdebugMsg(scip,
"arc %d: %d -> %d (len=%d, sourcecnt=%g/%g, targetcnt=%g/%g, %g/%g inconsistencies)\n",
4035 a, bestsourcev, besttargetv, rowlen,
4036 bestsourcecnt, totalsourcecnt, besttargetcnt, totaltargetcnt,
4037 nsourceinconsistencies, ntargetinconsistencies);
4040 if( bestsourcev != -1 )
4042 nextoutarcs[
a] = firstoutarcs[bestsourcev];
4043 firstoutarcs[bestsourcev] =
a;
4045 if( besttargetv != -1 )
4047 nextinarcs[
a] = firstinarcs[besttargetv];
4048 firstinarcs[besttargetv] =
a;
4052 mcfdata->ninconsistencies += 0.5*(nsourceinconsistencies + ntargetinconsistencies);
4054 if( mcfdata->ninconsistencies > maxninconsistencies )
4056 MCFdebugMessage(
" -> reached maximal number of inconsistencies: %g > %g\n",
4057 mcfdata->ninconsistencies, maxninconsistencies);
4063 if( mcfdata->ninconsistencies <= maxninconsistencies && narcs > 0 && ncommodities > 0 )
4068 MCFdebugMessage(
"extracted network has %g inconsistencies (ratio %g) -> separating with effort %d\n",
4069 mcfdata->ninconsistencies, mcfdata->ninconsistencies/(
SCIP_Real)narcs, *effortlevel);
4100 int* firstoutarcs = mcfdata->firstoutarcs;
4101 int* firstinarcs = mcfdata->firstinarcs;
4102 int* nextoutarcs = mcfdata->nextoutarcs;
4103 int* nextinarcs = mcfdata->nextinarcs;
4104 int nnodes = mcfdata->nnodes;
4109 assert(nodevisited !=
NULL);
4110 assert(0 <= startv && startv < nnodes);
4111 assert(nodevisited[startv] ==
UNKNOWN);
4112 assert(compnodes !=
NULL);
4113 assert(ncompnodes !=
NULL);
4114 assert(comparcs !=
NULL);
4115 assert(ncomparcs !=
NULL);
4124 stacknodes[0] = startv;
4126 nodevisited[startv] =
ONSTACK;
4129 while( nstacknodes > 0 )
4134 assert(firstoutarcs !=
NULL);
4135 assert(firstinarcs !=
NULL);
4136 assert(nextoutarcs !=
NULL);
4137 assert(nextinarcs !=
NULL);
4140 v = stacknodes[nstacknodes-1];
4142 assert(0 <= v && v < nnodes);
4143 assert(nodevisited[v] ==
ONSTACK);
4147 assert(*ncompnodes < nnodes);
4148 compnodes[*ncompnodes] = v;
4152 for( a = firstoutarcs[v]; a != -1; a = nextoutarcs[
a] )
4156 assert(0 <= a && a < mcfdata->
narcs);
4157 assert(arctargets !=
NULL);
4159 targetv = arctargets[
a];
4162 if( targetv != -1 && nodevisited[targetv] ==
VISITED )
4166 assert(*ncomparcs < mcfdata->narcs);
4167 comparcs[*ncomparcs] =
a;
4171 if( targetv != -1 && nodevisited[targetv] ==
UNKNOWN )
4173 assert(nstacknodes < nnodes);
4174 stacknodes[nstacknodes] = targetv;
4176 nodevisited[targetv] =
ONSTACK;
4181 for( a = firstinarcs[v]; a != -1; a = nextinarcs[
a] )
4185 assert(0 <= a && a < mcfdata->
narcs);
4186 assert(arcsources !=
NULL);
4188 sourcev = arcsources[
a];
4191 if( sourcev != -1 && nodevisited[sourcev] ==
VISITED )
4195 assert(*ncomparcs < mcfdata->narcs);
4196 comparcs[*ncomparcs] =
a;
4200 if( sourcev != -1 && nodevisited[sourcev] ==
UNKNOWN )
4202 assert(nstacknodes < nnodes);
4203 stacknodes[nstacknodes] = sourcev;
4205 nodevisited[sourcev] =
ONSTACK;
4236 int mcfnetworkssize;
4238 assert(mcfnetworks !=
NULL);
4239 assert(nmcfnetworks !=
NULL);
4240 assert(effortlevel !=
NULL);
4244 *mcfnetworks =
NULL;
4246 mcfnetworkssize = 0;
4277 mcfdata.flowrowsigns =
NULL;
4278 mcfdata.flowrowscalars =
NULL;
4279 mcfdata.flowrowscores =
NULL;
4280 mcfdata.capacityrowsigns =
NULL;
4281 mcfdata.capacityrowscores =
NULL;
4282 mcfdata.flowcands =
NULL;
4283 mcfdata.nflowcands = 0;
4284 mcfdata.capacitycands =
NULL;
4285 mcfdata.ncapacitycands = 0;
4286 mcfdata.plusflow =
NULL;
4287 mcfdata.minusflow =
NULL;
4288 mcfdata.ncommodities = 0;
4289 mcfdata.nemptycommodities = 0;
4290 mcfdata.commoditysigns =
NULL;
4291 mcfdata.commoditysignssize = 0;
4292 mcfdata.colcommodity =
NULL;
4293 mcfdata.rowcommodity =
NULL;
4294 mcfdata.colarcid =
NULL;
4295 mcfdata.rowarcid =
NULL;
4296 mcfdata.rownodeid =
NULL;
4297 mcfdata.arcarraysize = 0;
4298 mcfdata.arcsources =
NULL;
4299 mcfdata.arctargets =
NULL;
4300 mcfdata.colsources =
NULL;
4301 mcfdata.coltargets =
NULL;
4302 mcfdata.firstoutarcs =
NULL;
4303 mcfdata.firstinarcs =
NULL;
4304 mcfdata.nextoutarcs =
NULL;
4305 mcfdata.nextinarcs =
NULL;
4306 mcfdata.newcols =
NULL;
4307 mcfdata.nnewcols = 0;
4310 mcfdata.ninconsistencies = 0.0;
4311 mcfdata.capacityrows =
NULL;
4312 mcfdata.capacityrowssize = 0;
4313 mcfdata.colisincident =
NULL;
4314 mcfdata.zeroarcarray =
NULL;
4321 assert(mcfdata.flowrowsigns !=
NULL);
4322 assert(mcfdata.flowrowscalars !=
NULL);
4323 assert(mcfdata.flowrowscores !=
NULL);
4324 assert(mcfdata.flowcands !=
NULL);
4326 if( mcfdata.nflowcands == 0 )
4333 assert(mcfdata.plusflow !=
NULL);
4334 assert(mcfdata.minusflow !=
NULL);
4335 assert(mcfdata.colcommodity !=
NULL);
4336 assert(mcfdata.rowcommodity !=
NULL);
4337 assert(mcfdata.newcols !=
NULL);
4343 printCommodities(scip, &mcfdata);
4350 assert(mcfdata.capacityrowsigns !=
NULL);
4351 assert(mcfdata.capacityrowscores !=
NULL);
4352 assert(mcfdata.capacitycands !=
NULL);
4354 if( mcfdata.ncapacitycands == 0 )
4362 assert(mcfdata.colarcid !=
NULL);
4363 assert(mcfdata.rowarcid !=
NULL);
4367 assert(mcfdata.rownodeid !=
NULL);
4368 assert(mcfdata.colisincident !=
NULL);
4369 assert(mcfdata.zeroarcarray !=
NULL);
4380 assert(mcfdata.arcsources !=
NULL);
4381 assert(mcfdata.arctargets !=
NULL);
4382 assert(mcfdata.colsources !=
NULL);
4383 assert(mcfdata.coltargets !=
NULL);
4384 assert(mcfdata.firstoutarcs !=
NULL);
4385 assert(mcfdata.firstinarcs !=
NULL);
4386 assert(mcfdata.nextoutarcs !=
NULL);
4387 assert(mcfdata.nextinarcs !=
NULL);
4403 printCommodities(scip, &mcfdata);
4416 for( v = 0; v < mcfdata.nnodes; v++ )
4420 for( v = 0; v < mcfdata.nnodes; v++ )
4427 if( nodevisited[v] ==
VISITED )
4432 assert(ncompnodes >= 1);
4433 assert(compnodes[0] == v);
4434 assert(nodevisited[v] ==
VISITED);
4437 if( ncompnodes >= minnodes && ncomparcs >=
MINARCS )
4444 assert(*nmcfnetworks <= mcfnetworkssize);
4445 if( *nmcfnetworks == mcfnetworkssize )
4447 mcfnetworkssize =
MAX(2*mcfnetworkssize, *nmcfnetworks+1);
4450 assert(*nmcfnetworks < mcfnetworkssize);
4456 SCIP_CALL(
mcfnetworkFill(scip, mcfnetwork, &mcfdata, compnodeid, compnodes, ncompnodes, comparcs, ncomparcs) );
4459 for( i = *nmcfnetworks; i > 0 && mcfnetwork->
nnodes > (*mcfnetworks)[i-1]->nnodes; i-- )
4460 (*mcfnetworks)[i] = (*mcfnetworks)[i-1];
4461 (*mcfnetworks)[i] = mcfnetwork;
4466 minnodes =
MAX(minnodes, (*mcfnetworks)[*nmcfnetworks-1]->
nnodes);
4471 SCIPdebugMsg(scip,
" -> discarded network with %d nodes and %d arcs due to maxnetworks (minnodes=%d)\n",
4472 (*mcfnetworks)[*nmcfnetworks-1]->
nnodes, (*mcfnetworks)[*nmcfnetworks-1]->
narcs, minnodes);
4480 SCIPdebugMsg(scip,
" -> discarded component with %d nodes and %d arcs\n", ncompnodes, ncomparcs);
4522 #ifdef COUNTNETWORKVARIABLETYPES 4544 int nintflowvars = 0;
4545 int nbinflowvars = 0;
4546 int ncontflowvars = 0;
4548 int nintcapvars = 0;
4549 int nbincapvars = 0;
4550 int ncontcapvars = 0;
4558 for(c=0; c < ncols; c++)
4559 colvisited[c]=
FALSE;
4563 for(m=0; m < nmcfnetworks; m++)
4575 for(c=0; c < ncols; c++)
4579 if(colcommodity[c] >= 0 && ! colvisited[c])
4584 colvisited[c] =
TRUE;
4607 for( a = 0; a <
narcs; a++ )
4610 row = arccapacityrows[
a];
4622 for( i = 0; i < rowlen; i++ )
4627 if(colcommodity[c] == -1 && ! colvisited[c] )
4630 colvisited[c] =
TRUE;
4657 for( v = 0; v <
nnodes; v++ )
4660 row = nodeflowrows[v][k];
4670 MCFdebugMessage(
" nof flowvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4671 nflowvars, ncontflowvars, nintflowvars, nbinflowvars);
4672 MCFdebugMessage(
" nof capvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4673 ncapvars, ncontcapvars, nintcapvars, nbincapvars);
4692 int* representatives,
4699 for( v = 0; v < nelems; v++ )
4700 representatives[v] = v;
4706 int* representatives,
4710 assert(representatives !=
NULL);
4712 while( v != representatives[v] )
4714 representatives[v] = representatives[representatives[v]];
4715 v = representatives[v];
4724 int* representatives,
4729 assert(rep1 != rep2);
4730 assert(representatives[rep1] == rep1);
4731 assert(representatives[rep2] == rep2);
4737 representatives[rep2] = rep1;
4739 representatives[rep1] = rep2;
4755 if( nodepair1->weight > nodepair2->weight )
4757 else if( nodepair1->weight < nodepair2->weight )
4792 assert(mcfnetwork !=
NULL);
4798 assert(nodepair1 !=
NULL);
4799 assert(nodepair2 !=
NULL);
4801 source1 = nodepair1->node1;
4802 source2 = nodepair2->node1;
4803 target1 = nodepair1->node2;
4804 target2 = nodepair2->node2;
4806 assert(source1 >=0 && source1 < mcfnetwork->
nnodes);
4807 assert(source2 >=0 && source2 < mcfnetwork->nnodes);
4808 assert(target1 >=0 && target1 < mcfnetwork->nnodes);
4809 assert(target2 >=0 && target2 < mcfnetwork->nnodes);
4810 assert(source1 <= target1);
4811 assert(source2 <= target2);
4813 return (source1 == source2 && target1 == target2);
4827 unsigned int hashval;
4831 assert(mcfnetwork !=
NULL);
4835 assert( nodepair !=
NULL);
4837 source = nodepair->node1;
4838 target = nodepair->node2;
4840 assert(source >=0 && source < mcfnetwork->
nnodes);
4841 assert(target >=0 && target < mcfnetwork->nnodes);
4842 assert(source <= target);
4844 hashval = (source << 16) + target;
4867 #ifdef BETTERWEIGHTFORDEMANDNODES 4887 assert(mcfnetwork !=
NULL);
4889 #ifdef BETTERWEIGHTFORDEMANDNODES 4899 assert(nodepairqueue !=
NULL);
4906 hashtablesize = mcfnetwork->
narcs;
4909 hashGetKeyNodepairs, hashKeyEqNodepairs, hashKeyValNodepairs, (
void*) mcfnetwork) );
4916 for( a = 0; a < mcfnetwork->narcs; a++ )
4922 capacityrow = mcfnetwork->arccapacityrows[
a];
4924 SCIPdebugMsg(scip,
"arc %i = (%i %i)\n", a, mcfnetwork->arcsources[a], mcfnetwork->arctargets[a]);
4927 if( mcfnetwork->arcsources[a] <= mcfnetwork->arctargets[a] )
4929 nodepair.node1 = mcfnetwork->arcsources[
a];
4930 nodepair.node2 = mcfnetwork->arctargets[
a];
4934 nodepair.node2 = mcfnetwork->arcsources[
a];
4935 nodepair.node1 = mcfnetwork->arctargets[
a];
4938 assert(nodepair.node1 < mcfnetwork->nnodes);
4939 assert(nodepair.node2 < mcfnetwork->nnodes);
4940 if( nodepair.node1 == -1 || nodepair.node2 == -1 )
4944 if( capacityrow !=
NULL )
4960 slack =
MAX(slack, 0.0);
4963 scale =
ABS(mcfnetwork->arccapacityscales[a])/maxval;
4964 assert(scale > 0.0);
4974 for( i = 0; i < rowlen; i++ )
4981 if(colcommodity[c] >= 0)
4993 SCIPdebugMsg(scip,
"cap arc -- slack:%g -- dual:%g -- flow:%g -- cap:%g \n", scale * slack, dualsol/scale, totalflow * scale, totalcap * scale);
4995 SCIPdebugMsg(scip,
"cap arc -- slack:%g -- dual:%g1\n", scale * slack, dualsol/scale);
4999 nodepair.weight = scale * slack -
ABS(dualsol)/scale;
5000 #ifdef USEFLOWFORTIEBREAKING 5003 nodepair.weight += totalflow * scale;
5004 nodepair.weight =
MIN( nodepair.weight, -0.0001);
5007 #ifdef USECAPACITYFORTIEBREAKING 5010 nodepair.weight += totalcap * scale;
5011 nodepair.weight =
MIN( nodepair.weight, -0.0001);
5026 if( nodepairptr !=
NULL )
5029 SCIPdebugMsg(scip,
"nodepair known [%d,%d] -- old weight:%g -- new weight:%g\n", nodepair.node1,nodepair.node2,nodepairptr->weight,
5030 MIN(nodepair.weight, nodepairptr->weight));
5031 nodepairptr->weight =
MIN(nodepair.weight, nodepairptr->weight);
5036 nodepairs = (*nodepairqueue)->nodepairs;
5038 assert(nnodepairs < mcfnetwork->
narcs);
5039 nodepairs[nnodepairs] = nodepair;
5042 SCIPdebugMsg(scip,
"new nodepair [%d,%d]-- weight:%g\n", nodepair.node1, nodepair.node2, nodepair.weight);
5053 #ifdef BETTERWEIGHTFORDEMANDNODES 5061 nodepairs = (*nodepairqueue)->nodepairs;
5062 for( n = 0; n < nnodepairs; n++ )
5066 maxweight =
MAX(maxweight, nodepairs[n].weight);
5068 minweight =
MIN(minweight, nodepairs[n].weight);
5071 SCIPdebugMsg(scip,
"min/max weight:%g / %g\n", minweight, maxweight);
5078 for( n = 0; n < nnodepairs; n++ )
5080 int node1 = nodepairs[n].node1;
5081 int node2 = nodepairs[n].node2;
5083 #ifdef BETTERWEIGHTFORDEMANDNODES 5090 SCIPdebugMsg(scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5098 if( nodeflowrows[node1][k] ==
NULL )
5101 if( nodeflowscales[node1][k] > 0.0 )
5118 if( nodeflowrows[node2][k] ==
NULL )
5121 if( nodeflowscales[node2][k] > 0.0 )
5143 if( !hasdemand1 || !hasdemand2 )
5144 nodepairs[n].weight += maxweight;
5150 if( hasdemand1 && hasdemand2)
5151 nodepairs[n].weight += minweight;
5154 SCIPdebugMsg(scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5171 assert(nodepairqueue !=
NULL);
5172 assert(*nodepairqueue !=
NULL);
5186 assert(nodepairqueue !=
NULL);
5198 assert(nodepairqueue !=
NULL);
5246 assert(mcfnetwork !=
NULL);
5247 assert(nodepartition !=
NULL);
5248 assert(mcfnetwork->
nnodes >= 1);
5256 (*nodepartition)->nclusters = 0;
5265 nclustersleft = mcfnetwork->
nnodes;
5277 assert(nodepair !=
NULL);
5278 node1 = nodepair->node1;
5279 node2 = nodepair->node2;
5282 assert(node1 >= 0 && node1 < mcfnetwork->
nnodes);
5283 assert(node2 >= 0 && node2 < mcfnetwork->nnodes);
5288 assert(0 <= node1rep && node1rep < mcfnetwork->nnodes);
5289 assert(0 <= node2rep && node2rep < mcfnetwork->nnodes);
5292 if( node1rep == node2rep )
5296 SCIPdebugMsg(scip,
"shrinking nodepair (%d,%d) with weight %g: join representatives %d and %d\n",
5297 node1, node2, weight, node1rep, node2rep);
5303 assert((*nodepartition)->representatives[0] == 0);
5308 if( nclustersleft > nclusters )
5310 for( v = 1; v < mcfnetwork->
nnodes && nclustersleft > nclusters; v++ )
5322 assert(nclustersleft <= nclusters);
5327 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5337 c = (*nodepartition)->nclusters;
5338 (*nodepartition)->nclusters++;
5341 c = (*nodepartition)->nodeclusters[rep];
5342 assert(0 <= c && c < nclusters);
5345 (*nodepartition)->nodeclusters[v] = c;
5351 for( c = 0; c < (*nodepartition)->nclusters; c++ )
5353 (*nodepartition)->clusterbegin[c] = pos;
5354 pos += clustersize[c];
5356 assert(pos == mcfnetwork->
nnodes);
5357 (*nodepartition)->clusterbegin[(*nodepartition)->nclusters] = mcfnetwork->
nnodes;
5361 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5363 c = (*nodepartition)->nodeclusters[v];
5364 assert(0 <= c && c < (*nodepartition)->nclusters);
5365 pos = (*nodepartition)->clusterbegin[c] + clustersize[c];
5366 assert(pos < (*nodepartition)->clusterbegin[c+1]);
5367 (*nodepartition)->clusternodes[pos] = v;
5387 assert(nodepartition !=
NULL);
5388 assert(*nodepartition !=
NULL);
5401 unsigned int partition,
5412 if( nodepartition ==
NULL )
5413 return ((v == (
int)partition) == !inverted);
5417 unsigned int clusterbit;
5419 cluster = nodepartition->nodeclusters[v];
5420 assert(0 <= cluster && cluster < nodepartition->nclusters);
5421 clusterbit = (1 << cluster);
5423 return (((partition & clusterbit) != 0) == !inverted);
5433 unsigned int partition
5436 const int* nodeclusters = nodepartition->nodeclusters;
5446 assert(nodepartition->nodeclusters !=
NULL);
5447 nclusters = nodepartition->nclusters;
5454 ncomponents = nclusters;
5455 assert(ncomponents >= 2);
5458 for( a = 0; a <
narcs; a++ )
5460 int s = arcsources[
a];
5461 int t = arctargets[
a];
5464 if( s == -1 || t == -1 )
5475 assert(0 <= s && s < mcfnetwork->
nnodes);
5476 assert(0 <= t && t < mcfnetwork->nnodes);
5479 cs = nodeclusters[s];
5480 ct = nodeclusters[t];
5481 assert(0 <= cs && cs < nclusters);
5482 assert(0 <= ct && ct < nclusters);
5491 if( repcs == repct )
5498 if( ncomponents <= 2 )
5508 assert(ncomponents >= 2);
5510 return (ncomponents == 2);
5515 void nodepartitionPrint(
5521 for( c = 0; c < nodepartition->nclusters; c++ )
5526 for( i = nodepartition->clusterbegin[c]; i < nodepartition->clusterbegin[c+1]; i++ )
5541 unsigned int partition
5550 if( nodepartition ==
NULL )
5555 file = fopen(filename,
"w");
5563 fprintf(file,
"graph\n");
5564 fprintf(file,
"[\n");
5565 fprintf(file,
" hierarchic 1\n");
5566 fprintf(file,
" label \"\"\n");
5567 fprintf(file,
" directed 1\n");
5570 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5581 fprintf(file,
" node\n");
5582 fprintf(file,
" [\n");
5583 fprintf(file,
" id %d\n", v);
5584 fprintf(file,
" label \"%s\"\n", label);
5585 fprintf(file,
" graphics\n");
5586 fprintf(file,
" [\n");
5587 fprintf(file,
" w 30.0\n");
5588 fprintf(file,
" h 30.0\n");
5589 fprintf(file,
" type \"ellipse\"\n");
5591 fprintf(file,
" fill \"#FF0000\"\n");
5593 fprintf(file,
" fill \"#00FF00\"\n");
5594 fprintf(file,
" outline \"#000000\"\n");
5595 fprintf(file,
" ]\n");
5596 fprintf(file,
" LabelGraphics\n");
5597 fprintf(file,
" [\n");
5598 fprintf(file,
" text \"%s\"\n", label);
5599 fprintf(file,
" fontSize 13\n");
5600 fprintf(file,
" fontName \"Dialog\"\n");
5601 fprintf(file,
" anchor \"c\"\n");
5602 fprintf(file,
" ]\n");
5604 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+1);
5606 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+2);
5607 fprintf(file,
" ]\n");
5611 fprintf(file,
" node\n");
5612 fprintf(file,
" [\n");
5613 fprintf(file,
" id %d\n", mcfnetwork->
nnodes);
5614 fprintf(file,
" label \"?\"\n");
5615 fprintf(file,
" graphics\n");
5616 fprintf(file,
" [\n");
5617 fprintf(file,
" w 30.0\n");
5618 fprintf(file,
" h 30.0\n");
5619 fprintf(file,
" type \"ellipse\"\n");
5620 fprintf(file,
" fill \"#FFFFFF\"\n");
5621 fprintf(file,
" outline \"#000000\"\n");
5622 fprintf(file,
" ]\n");
5623 fprintf(file,
" LabelGraphics\n");
5624 fprintf(file,
" [\n");
5625 fprintf(file,
" text \"?\"\n");
5626 fprintf(file,
" fontSize 13\n");
5627 fprintf(file,
" fontName \"Dialog\"\n");
5628 fprintf(file,
" anchor \"c\"\n");
5629 fprintf(file,
" ]\n");
5630 fprintf(file,
" ]\n");
5633 fprintf(file,
" node\n");
5634 fprintf(file,
" [\n");
5635 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+1);
5636 fprintf(file,
" label \"Partition S\"\n");
5637 fprintf(file,
" graphics\n");
5638 fprintf(file,
" [\n");
5639 fprintf(file,
" type \"roundrectangle\"\n");
5640 fprintf(file,
" fill \"#CAECFF84\"\n");
5641 fprintf(file,
" outline \"#666699\"\n");
5642 fprintf(file,
" outlineStyle \"dotted\"\n");
5643 fprintf(file,
" topBorderInset 0\n");
5644 fprintf(file,
" bottomBorderInset 0\n");
5645 fprintf(file,
" leftBorderInset 0\n");
5646 fprintf(file,
" rightBorderInset 0\n");
5647 fprintf(file,
" ]\n");
5648 fprintf(file,
" LabelGraphics\n");
5649 fprintf(file,
" [\n");
5650 fprintf(file,
" text \"Partition S\"\n");
5651 fprintf(file,
" fill \"#99CCFF\"\n");
5652 fprintf(file,
" fontSize 15\n");
5653 fprintf(file,
" fontName \"Dialog\"\n");
5654 fprintf(file,
" alignment \"right\"\n");
5655 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5656 fprintf(file,
" anchor \"t\"\n");
5657 fprintf(file,
" borderDistance 0.0\n");
5658 fprintf(file,
" ]\n");
5659 fprintf(file,
" isGroup 1\n");
5660 fprintf(file,
" ]\n");
5663 fprintf(file,
" node\n");
5664 fprintf(file,
" [\n");
5665 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+2);
5666 fprintf(file,
" label \"Partition T\"\n");
5667 fprintf(file,
" graphics\n");
5668 fprintf(file,
" [\n");
5669 fprintf(file,
" type \"roundrectangle\"\n");
5670 fprintf(file,
" fill \"#CAECFF84\"\n");
5671 fprintf(file,
" outline \"#666699\"\n");
5672 fprintf(file,
" outlineStyle \"dotted\"\n");
5673 fprintf(file,
" topBorderInset 0\n");
5674 fprintf(file,
" bottomBorderInset 0\n");
5675 fprintf(file,
" leftBorderInset 0\n");
5676 fprintf(file,
" rightBorderInset 0\n");
5677 fprintf(file,
" ]\n");
5678 fprintf(file,
" LabelGraphics\n");
5679 fprintf(file,
" [\n");
5680 fprintf(file,
" text \"Partition T\"\n");
5681 fprintf(file,
" fill \"#99CCFF\"\n");
5682 fprintf(file,
" fontSize 15\n");
5683 fprintf(file,
" fontName \"Dialog\"\n");
5684 fprintf(file,
" alignment \"right\"\n");
5685 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5686 fprintf(file,
" anchor \"t\"\n");
5687 fprintf(file,
" borderDistance 0.0\n");
5688 fprintf(file,
" ]\n");
5689 fprintf(file,
" isGroup 1\n");
5690 fprintf(file,
" ]\n");
5693 for( a = 0; a < mcfnetwork->
narcs; a++ )
5705 hasfractional =
FALSE;
5716 for( i = 0; i < rowlen; i++ )
5723 hasfractional =
TRUE;
5731 fprintf(file,
" edge\n");
5732 fprintf(file,
" [\n");
5735 fprintf(file,
" label \"%s\"\n", label);
5736 fprintf(file,
" graphics\n");
5737 fprintf(file,
" [\n");
5739 fprintf(file,
" fill \"#000000\"\n");
5741 fprintf(file,
" fill \"#FF0000\"\n");
5743 fprintf(file,
" style \"dashed\"\n");
5744 fprintf(file,
" width 1\n");
5745 fprintf(file,
" targetArrow \"standard\"\n");
5746 fprintf(file,
" ]\n");
5747 fprintf(file,
" LabelGraphics\n");
5748 fprintf(file,
" [\n");
5749 fprintf(file,
" text \"%s\"\n", label);
5750 fprintf(file,
" ]\n");
5751 fprintf(file,
" ]\n");
5755 fprintf(file,
"]\n");
5790 assert(scip !=
NULL);
5791 assert(sepadata !=
NULL);
5792 assert(cutcoefs !=
NULL);
5793 assert(ncuts !=
NULL);
5794 assert(cutoff !=
NULL);
5798 assert(nvars == 0 || vars !=
NULL);
5804 for( i = 0; i < cutnnz; ++i )
5806 cutvars[i] = vars[cutinds[i]];
5812 sepadata->dynamiccuts) );
5822 SCIPdebugMsg(scip,
" -> found MCF cut <%s>: rhs=%f, act=%f eff=%f rank=%d\n",
5839 if( !(*cutoff) && sepadata->separateknapsack)
5842 SCIP_CALL(
SCIPseparateRelaxedKnapsack(scip,
NULL, sepa, cutnnz, cutvars, cutcoefs, +1.0, cutrhs, sol, cutoff, ncuts) );
5892 unsigned int partition;
5893 unsigned int allpartitions;
5894 unsigned int startpartition;
5908 maxsepacuts = sepadata->maxsepacutsroot;
5910 maxsepacuts = sepadata->maxsepacuts;
5911 if( maxsepacuts < 0 )
5912 maxsepacuts = INT_MAX;
5917 maxtestdelta = sepadata->maxtestdelta;
5918 if( maxtestdelta <= 0 )
5919 maxtestdelta = INT_MAX;
5955 if( nodepartition ==
NULL )
5959 allpartitions = (
unsigned int) nnodes;
5960 SCIPdebugMsg(scip,
"maxtestdelta: %d, maxsepacuts: %d, nnodes: %d \n", maxtestdelta, maxsepacuts, nnodes);
5967 int nclusters = nodepartition->nclusters;
5969 assert((
unsigned int)nclusters <= 8*
sizeof(
unsigned int));
5970 SCIPdebugMsg(scip,
"maxtestdelta: %d, maxsepacuts: %d, nclusters: %d \n", maxtestdelta, maxsepacuts, nclusters);
5977 allpartitions = (1 << (nclusters-1));
5981 for( partition = startpartition; partition <= allpartitions-1 && !
SCIPisStopped(scip) && *ncuts < maxsepacuts && !*cutoff; partition++ )
5995 if( sepadata->checkcutshoreconnectivity )
6002 SCIPdebugMsg(scip,
"generating cluster cuts for partition 0x%x \n", partition );
6003 SCIPdebugMsg(scip,
" -> either shore S or shore T is not connected - skip partition.\n");
6008 for( inverted =
FALSE; inverted <= useinverted && !*cutoff; inverted++ )
6010 if( nodepartition ==
NULL )
6012 SCIPdebugMsg(scip,
"generating single-node cuts for node %u (inverted: %u)\n", partition, inverted);
6016 SCIPdebugMsg(scip,
"generating cluster cuts for partition 0x%x (inverted: %u)\n", partition, inverted);
6020 SCIP_CALL( outputGraph(scip, mcfnetwork, nodepartition, inverted, partition) );
6038 for( v = 0; v <
nnodes; v++ )
6052 if( nodeflowrows[v][k] ==
NULL )
6055 if( nodeflowscales[v][k] > 0.0 )
6059 if( nodeflowinverted[v][k] )
6062 comcutdemands[k] += rhs * nodeflowscales[v][k];
6065 assert (1 <= nnodesinS && nnodesinS <= nnodes-1);
6070 if( sepadata->separatesinglenodecuts && nodepartition !=
NULL && (nnodesinS == 1 || nnodesinS == nnodes-1) )
6072 SCIPdebugMsg(scip,
" -> shore S or T has only one node - skip partition.\n");
6082 SCIPdebugMsg(scip,
" -> commodity %d: directed cutdemand=%g\n", k, comcutdemands[k]);
6092 SCIPdebugMsg(scip,
" -> commodity %d: undirected cutdemand=%g\n", k, comcutdemands[k]);
6097 if( k == ncommodities )
6101 for( a = 0; a <
narcs; a++ )
6110 assert(arcsources[a] < nnodes);
6111 assert(arctargets[a] < nnodes);
6117 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) ||
6127 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6133 if( !
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6142 if( arccapacityrows[a] ==
NULL )
6150 assert(rowweights[r] == 0.0);
6156 if( arcsources[a] == -1 || arctargets[a] == -1 )
6166 assert(maxcoef > 0.0);
6171 rowweights[
r] = arccapacityscales[
a];
6172 SCIPdebugMsg(scip,
" -> arc %d, r=%d, capacity row <%s>: weight=%g slack=%g dual=%g\n", a, r,
SCIProwGetName(arccapacityrows[a]), rowweights[r],
6176 if( sepadata->separateflowcutset )
6178 if( rowweights[r] > 0.0 )
6188 for( j = 0; j < rowlen; j++ )
6193 coef = rowvals[j] * arccapacityscales[
a];
6199 k = colcommodity[c];
6201 comdemands[k] = coef;
6215 while( left <= right )
6217 int mid = (left+right)/2;
6219 if(
REALABS( deltas[mid] / coef - 1.0 ) < 1e-03 )
6224 else if( coef < deltas[mid] )
6233 assert(right == left-1);
6234 assert(ndeltas <= deltassize);
6235 if( ndeltas == deltassize )
6240 if( left < ndeltas )
6242 for( d = ndeltas; d > left; d-- )
6243 deltas[d] = deltas[d-1];
6245 deltas[left] = coef;
6247 SCIPdebugMsg(scip,
" -> new capacity %g considered as delta\n", coef);
6254 for( v = 0; v <
nnodes; v++ )
6263 if( comdemands[k] == 0.0 )
6266 scale = comdemands[k];
6289 if( comcutdemands[k] > 0.0 )
6308 if( nodeflowrows[v][k] ==
NULL )
6317 assert(rowweights[r] == 0.0);
6323 rowweights[
r] = scale * nodeflowscales[v][k];
6324 if( nodeflowinverted[v][k] )
6325 rowweights[
r] *= -1.0;
6326 SCIPdebugMsg(scip,
" -> node %d, commodity %d, r=%d, flow row <%s>: scale=%g weight=%g slack=%g dual=%g\n",
6327 v, k, r,
SCIProwGetName(nodeflowrows[v][k]), scale, rowweights[r],
6330 if( sepadata->separateflowcutset )
6332 if( nodeflowscales[v][k] > 0.0 )
6348 if( sepadata->separateflowcutset )
6351 bestdelta = deltas[ndeltas-1];
6361 SCIPdebugMsg(scip,
" -> found %d different deltas to try\n", ndeltas);
6362 for( d = ndeltas-1; d >= 0 && d >= ndeltas-maxtestdelta; d-- )
6376 SCIPdebugMsg(scip,
"applying MIR with delta = %g\n", deltas[d]);
6377 SCIP_CALL(
SCIPcalcMIR(scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
6378 1.0/deltas[d], aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6379 assert(allowlocal || !cutislocal);
6387 if( sepadata->separateflowcutset )
6389 if( cutefficacy > bestefficacy )
6391 bestdelta = deltas[d];
6392 bestefficacy = cutefficacy;
6398 SCIPdebugMsg(scip,
"success -> delta = %g -> rhs: %g, efficacy: %g\n", deltas[d], cutrhs, cutefficacy);
6399 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6404 for( a = 0; a <
narcs; a++ )
6406 if( arccapacityrows[a] !=
NULL )
6412 if( r >= 0 && rowweights[r] != 0.0 )
6414 MCFdebugMessage(
" -> arc %d, capacity row <%s>: weight=%g slack=%g prod=%g dual=%g\n", a,
6427 if( sepadata->separateflowcutset && oldncuts == *ncuts && !*cutoff )
6430 f0 =
SCIPfrac(scip, baserhs/bestdelta);
6435 totalviolationdelta = 0.0;
6436 onedivoneminsf0 = 1.0/(1.0 - f0);
6437 for( a = 0; a <
narcs; a++ )
6451 if( arccapacityrows[a] ==
NULL )
6462 if( rowweights[r] == 0.0 )
6477 rowweight = rowweights[
r]/bestdelta;
6482 violationdelta = rowweight * (rowlhs - rowconstant);
6484 violationdelta = rowweight * (rowrhs - rowconstant);
6486 for( j = 0; j < rowlen; j++ )
6494 coef = rowvals[j] * rowweight;
6505 if( colcommodity[c] >= 0 )
6516 mircoef =
SCIPfloor(scip, coef) + (fj - f0)*onedivoneminsf0;
6523 mircoef = coef * onedivoneminsf0;
6528 if( colcommodity[c] >= 0 )
6529 violationdelta += mircoef * solval;
6531 violationdelta -= mircoef * solval;
6536 SCIPdebugMsg(scip,
" -> discarding capacity row <%s> of weight %g and slack %g: increases MIR violation by %g\n",
6539 rowweights[
r] = 0.0;
6540 totalviolationdelta += violationdelta;
6545 if( totalviolationdelta > 0.0 )
6558 SCIPdebugMsg(scip,
"applying MIR with delta = %g to flowcut inequality (violation improvement: %g)\n", bestdelta, totalviolationdelta);
6565 SCIP_CALL(
SCIPcalcMIR(scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
6566 1.0/bestdelta, aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6568 assert(allowlocal || !cutislocal);
6572 SCIPdebugMsg(scip,
" -> delta = %g -> rhs: %g, efficacy: %g\n", bestdelta, cutrhs, cutefficacy);
6573 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6616 assert(result !=
NULL);
6629 if( ncols != nvars )
6631 MCFdebugMessage(
"%d variables but %d columns -> exit\n", nvars, ncols );
6644 colrowratio = (
SCIP_Real)ncols/(nrows+1e-9);
6648 assert(sepadata !=
NULL);
6657 if( colrowratio < MINCOLROWRATIO || colrowratio >
MAXCOLROWRATIO )
6666 if( sepadata->nmcfnetworks == -1 )
6674 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6676 MCFdebugMessage(
" -> extracted network %d has %d nodes, %d (%d) arcs (uncapacitated), and %d commodities (modeltype: %s)\n",
6677 i, sepadata->mcfnetworks[i]->nnodes, sepadata->mcfnetworks[i]->narcs, sepadata->mcfnetworks[i]->nuncapacitatedarcs,
6678 sepadata->mcfnetworks[i]->ncommodities,
6680 SCIPdebug( mcfnetworkPrint(sepadata->mcfnetworks[i]) );
6683 #ifdef COUNTNETWORKVARIABLETYPES 6684 SCIP_CALL( printFlowSystemInfo(scip,sepadata->mcfnetworks,sepadata->nmcfnetworks));
6688 assert(sepadata->nmcfnetworks >= 0);
6689 assert(sepadata->mcfnetworks !=
NULL || sepadata->nmcfnetworks == 0);
6690 mcfnetworks = sepadata->mcfnetworks;
6691 nmcfnetworks = sepadata->nmcfnetworks;
6698 sepadata->lastroundsuccess =
FALSE;
6700 for( i = 0; i < nmcfnetworks && !cutoff; i++ )
6706 mcfnetwork = mcfnetworks[i];
6709 assert(mcfnetwork->
nnodes >= 2);
6710 assert(mcfnetwork->
narcs >= 1);
6717 MCFdebugMessage(
"MCF network has %d nodes and %d arcs. arc node ratio %.2f exceed --> exit\n",
6723 if( sepadata->separatesinglenodecuts )
6734 nodepartitionPrint(nodepartition);
6744 MCFdebugMessage(
"MCF network has %d nodes, %d arcs, %d commodities. Found %d MCF network cuts, cutoff = %u.\n",
6751 sepadata->lastroundsuccess =
TRUE;
6753 else if( ncuts > 0 )
6756 sepadata->lastroundsuccess =
TRUE;
6773 assert(scip !=
NULL);
6774 assert(sepa !=
NULL);
6792 assert(sepadata !=
NULL);
6793 assert(sepadata->mcfnetworks ==
NULL);
6794 assert(sepadata->nmcfnetworks == -1);
6812 assert(sepadata !=
NULL);
6814 sepadata->lastroundsuccess =
TRUE;
6831 assert(sepadata !=
NULL);
6834 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6839 sepadata->nmcfnetworks = -1;
6901 sepadata->mcfnetworks =
NULL;
6902 sepadata->nmcfnetworks = -1;
6904 sepadata->lastroundsuccess =
TRUE;
6910 sepaExeclpMcf, sepaExecsolMcf,
6913 assert(sepa !=
NULL);
6924 "separating/mcf/nclusters",
6925 "number of clusters to generate in the shrunken network -- default separation",
6928 "separating/mcf/maxweightrange",
6929 "maximal valid range max(|weights|)/min(|weights|) of row weights",
6932 "separating/mcf/maxtestdelta",
6933 "maximal number of different deltas to try (-1: unlimited) -- default separation",
6936 "separating/mcf/trynegscaling",
6937 "should negative values also be tested in scaling?",
6940 "separating/mcf/fixintegralrhs",
6941 "should an additional variable be complemented if f0 = 0?",
6944 "separating/mcf/dynamiccuts",
6945 "should generated cuts be removed from the LP if they are no longer tight?",
6948 "separating/mcf/modeltype",
6949 "model type of network (0: auto, 1:directed, 2:undirected)",
6952 "separating/mcf/maxsepacuts",
6953 "maximal number of mcf cuts separated per separation round",
6956 "separating/mcf/maxsepacutsroot",
6957 "maximal number of mcf cuts separated per separation round in the root node -- default separation",
6960 "separating/mcf/maxinconsistencyratio",
6961 "maximum inconsistency ratio for separation at all",
6964 "separating/mcf/maxarcinconsistencyratio",
6965 "maximum inconsistency ratio of arcs not to be deleted",
6968 "separating/mcf/checkcutshoreconnectivity",
6969 "should we separate only if the cuts shores are connected?",
6972 "separating/mcf/separatesinglenodecuts",
6973 "should we separate inequalities based on single-node cuts?",
6976 "separating/mcf/separateflowcutset",
6977 "should we separate flowcutset inequalities on the network cuts?",
6980 "separating/mcf/separateknapsack",
6981 "should we separate knapsack cover inequalities on the network cuts?",
enum SCIP_Result SCIP_RESULT
SCIP_ROW ** SCIPgetLPRows(SCIP *scip)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE mcfnetworkCreate(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
#define DEFAULT_TRYNEGSCALING
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
static SCIP_RETCODE extractFlowRows(SCIP *scip, MCFDATA *mcfdata)
static void fixCommoditySigns(SCIP *scip, MCFDATA *mcfdata)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
public methods for SCIP parameter handling
SCIP_Bool ** nodeflowinverted
#define SCIPfreeMemoryArrayNull(scip, ptr)
void SCIPsortInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
public methods for memory management
static SCIP_RETCODE nodepairqueueCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPAIRQUEUE **nodepairqueue)
static SCIP_RETCODE identifySourcesTargets(SCIP *scip, MCFDATA *mcfdata, SCIP_SEPADATA *sepadata, MCFEFFORTLEVEL *effortlevel)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
#define SCIPallocMemoryArray(scip, ptr, num)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE extractFlow(SCIP *scip, MCFDATA *mcfdata, SCIP_Real maxflowvarflowrowratio, SCIP_Bool *failed)
const char * SCIProwGetName(SCIP_ROW *row)
static SCIP_RETCODE extractCapacities(SCIP *scip, MCFDATA *mcfdata)
#define SEPA_MAXBOUNDDIST
static SCIP_RETCODE identifyComponent(SCIP *scip, MCFDATA *mcfdata, int *nodevisited, int startv, int *compnodes, int *ncompnodes, int *comparcs, int *ncomparcs)
#define DEFAULT_MODELTYPE
struct nodepairqueue NODEPAIRQUEUE
int SCIProwGetNLPNonz(SCIP_ROW *row)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
#define DEFAULT_MAXINCONSISTENCYRATIO
static SCIP_RETCODE nodepartitionCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION **nodepartition, int nclusters)
static void nodepairqueueFree(SCIP *scip, NODEPAIRQUEUE **nodepairqueue)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
methods for the aggregation rows
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
enum SCIP_Retcode SCIP_RETCODE
static SCIP_DECL_SORTINDCOMP(compCands)
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
static SCIP_DECL_HASHKEYVAL(hashKeyValNodepairs)
public methods for problem variables
#define DEFAULT_FIXINTEGRALRHS
static SCIP_DECL_SORTPTRCOMP(compNodepairs)
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)
#define SCIPfreeBlockMemory(scip, ptr)
#define DEFAULT_CHECKCUTSHORECONNECTIVITY
static NODEPAIRENTRY * nodepairqueueRemove(NODEPAIRQUEUE *nodepairqueue)
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
SCIP_MCFMODELTYPE modeltype
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Bool allowlocal, SCIP_RESULT *result)
#define SCIPallocBlockMemory(scip, ptr)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
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)
public methods for separator plugins
static SCIP_RETCODE mcfnetworkExtract(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_MCFNETWORK ***mcfnetworks, int *nmcfnetworks, MCFEFFORTLEVEL *effortlevel)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_Real SCIPgetRowFeasibility(SCIP *scip, SCIP_ROW *row)
#define MAXFLOWCANDDENSITY
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
public methods for numerical tolerances
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
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)
public methods for querying solving statistics
static SCIP_RETCODE findUncapacitatedArcs(SCIP *scip, MCFDATA *mcfdata)
public methods for the branch-and-bound tree
#define MAXFLOWVARFLOWROWRATIO
#define DEFAULT_MAXTESTDELTA
#define DEFAULT_SEPARATEFLOWCUTSET
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
static void getIncidentNodes(SCIP *scip, MCFDATA *mcfdata, SCIP_COL *col, int *sourcenode, int *targetnode)
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
static SCIP_DECL_SEPACOPY(sepaCopyMcf)
#define MAXAGGRLEN(nvars)
static void unionfindJoinSets(int *representatives, int rep1, int rep2)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
#define DEFAULT_MAXSEPACUTSROOT
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
static SCIP_Bool nodeInPartition(NODEPARTITION *nodepartition, unsigned int partition, SCIP_Bool inverted, int v)
static void nodepartitionJoin(NODEPARTITION *nodepartition, int rep1, int rep2)
static SCIP_RETCODE createNewArc(SCIP *scip, MCFDATA *mcfdata, int source, int target, int *newarcid)
#define SCIPallocBuffer(scip, ptr)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
static int nodepartitionIsConnected(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, unsigned int partition)
#define SCIPreallocMemoryArray(scip, ptr, newnum)
#define DEFAULT_MAXSEPACUTS
const char * SCIPvarGetName(SCIP_VAR *var)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
int SCIPgetNLPRows(SCIP *scip)
static SCIP_RETCODE cleanupNetwork(SCIP *scip, MCFDATA *mcfdata)
enum McfEffortLevel MCFEFFORTLEVEL
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPincludeSepaMcf(SCIP *scip)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
#define DEFAULT_MAXWEIGHTRANGE
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
static SCIP_RETCODE mcfnetworkFill(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, MCFDATA *mcfdata, int *compnodeid, int *compnodes, int ncompnodes, int *comparcs, int ncomparcs)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
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)
static void collectIncidentFlowCols(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *flowrow, int basecommodity)
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPcalcMIR(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, SCIP_Bool usevbds, 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)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
public data structures and miscellaneous methods
struct nodepair NODEPAIRENTRY
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
multi-commodity-flow network cut separator
#define DEFAULT_NCLUSTERS
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
int SCIPgetDepth(SCIP *scip)
enum SCIP_McfModeltype SCIP_MCFMODELTYPE
SCIP_RETCODE SCIPcaptureRow(SCIP *scip, SCIP_ROW *row)
static SCIP_DECL_HASHKEYEQ(hashKeyEqNodepairs)
static SCIP_DECL_SEPAEXITSOL(sepaExitsolMcf)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
SCIP_ROW ** arccapacityrows
public methods for LP management
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)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
public methods for cuts and aggregation rows
static void deleteCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int nrows, int *ndelflowrows, int *ndelflowvars)
SCIP_COL ** SCIPgetLPCols(SCIP *scip)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define UNCAPACITATEDARCSTRESHOLD
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
public methods for the LP relaxation, rows and columns
int SCIProwGetRank(SCIP_ROW *row)
static void getNextFlowrow(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW **nextrow, unsigned char *nextrowsign, SCIP_Bool *nextinvertcommodity)
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
int SCIPgetNVars(SCIP *scip)
#define HASHSIZE_NODEPAIRS
#define SCIPfreeMemory(scip, ptr)
static SCIP_RETCODE mcfnetworkFree(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
methods for sorting joint arrays of various types
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
public methods for branching rule plugins and branching
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
#define DEFAULT_MAXARCINCONSISTENCYRATIO
#define SCIPfreeBuffer(scip, ptr)
#define DEFAULT_SEPARATEKNAPSACK
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
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_VAR * SCIPcolGetVar(SCIP_COL *col)
public methods for solutions
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
static int nodepartitionGetRepresentative(NODEPARTITION *nodepartition, int v)
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)))
void SCIProwChgRank(SCIP_ROW *row, int rank)
#define DEFAULT_SEPARATESINGLENODECUTS
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)
public methods for message output
SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
int SCIProwGetLPPos(SCIP_ROW *row)
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_Real ** nodeflowscales
static SCIP_RETCODE extractCapacityRows(SCIP *scip, MCFDATA *mcfdata)
#define MINCOMNODESFRACTION
public methods for message handling
static SCIP_DECL_SEPAEXECSOL(sepaExecsolMcf)
static void getFlowrowFit(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, int k, unsigned char *rowsign, SCIP_Bool *invertcommodity)
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
static SCIP_DECL_SEPAINITSOL(sepaInitsolMcf)
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
#define SCIPallocMemory(scip, ptr)
static SCIP_DECL_SEPAEXECLP(sepaExeclpMcf)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_ROW *** nodeflowrows
SCIP_Real * arccapacityscales
int SCIPgetNLPCols(SCIP *scip)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
static SCIP_Bool nodepairqueueIsEmpty(NODEPAIRQUEUE *nodepairqueue)
public methods for separators
#define BMSclearMemoryArray(ptr, num)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
static void unionfindInitSets(int *representatives, int nelems)
static void invertCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int ncomrows, int *comcolids, int ncomcolids)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
#define DEFAULT_DYNAMICCUTS
static SCIP_RETCODE generateClusterCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Bool allowlocal, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, int *ncuts, SCIP_Bool *cutoff)
static int unionfindGetRepresentative(int *representatives, int v)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
static void addFlowrowToCommodity(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, unsigned char rowsign, int *comcolids, int *ncomcolids)
public methods for global and local (sub)problems
int SCIPcolGetNLPNonz(SCIP_COL *col)
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
int SCIPcolGetLPPos(SCIP_COL *col)
static SCIP_DECL_HASHGETKEY(hashGetKeyNodepairs)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
static SCIP_RETCODE extractNodes(SCIP *scip, MCFDATA *mcfdata)
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)
struct nodepartition NODEPARTITION
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_DECL_SEPAFREE(sepaFreeMcf)
struct SCIP_SepaData SCIP_SEPADATA
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_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)
static void nodepartitionFree(SCIP *scip, NODEPARTITION **nodepartition)
static SCIP_RETCODE createNewCommodity(SCIP *scip, MCFDATA *mcfdata)
#define SCIPreallocBufferArray(scip, ptr, num)
memory allocation routines