* flowrowsigns;
222 unsigned char* capacityrowsigns;
231 intnemptycommodities;
232 int* commoditysigns;
233 intcommoditysignssize;
254 intcapacityrowssize;
281 int* representatives;
293#define LHSPOSSIBLE 1u 294#define RHSPOSSIBLE 2u 295#define LHSASSIGNED 4u 296#define RHSASSIGNED 8u 299#define UNDIRECTED 64u 309assert(mcfnetwork !=
NULL);
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;
335assert(mcfnetwork !=
NULL);
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 intnflowcands = mcfdata->nflowcands;
397 intncommodities = 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 intncompcommodities;
418assert(mcfnetwork !=
NULL);
420assert(2 <= ncompnodes && ncompnodes <= mcfdata->
nnodes);
421assert(1 <= ncomparcs && ncomparcs <= mcfdata->
narcs);
422assert(ncommodities > 0);
426 for( v = 0; v < mcfdata->nnodes; v++ )
427assert(compnodeid[v] == -1);
438 for( k = 0; k < ncommodities; k++ )
439compcommodity[k] = -1;
446 for( i = 0; i < ncompnodes; i++ )
449assert(0 <= v && v < mcfdata->
nnodes);
454ncompcommodities = 0;
455 for( i = 0; i < nflowcands; i++ )
461assert(0 <=
r&&
r< nrows);
464 if( rv >= 0 && compnodeid[rv] >= 0 )
466k = rowcommodity[
r];
467assert(0 <= k && k < ncommodities);
468 if( compcommodity[k] == -1 )
470compcommodity[k] = ncompcommodities;
481mcfnetwork->
nnodes= ncompnodes;
482mcfnetwork->
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++ )
524assert(0 <=
r&&
r< nrows);
527 if( rv >= 0 && compnodeid[rv] >= 0 )
533rk = rowcommodity[
r];
534assert(v < mcfnetwork->
nnodes);
535assert(0 <= rk && rk < ncommodities);
538k = compcommodity[rk];
539assert(0 <= k && k < mcfnetwork->ncommodities);
544scale = flowrowscalars[
r];
547 if( commoditysigns[rk] == -1 )
555 for(
a= 0;
a< mcfnetwork->
narcs;
a++ )
565globala = comparcs[
a];
566capacityrow = capacityrows[globala];
571 if( capacityrow !=
NULL)
574assert(0 <=
r&&
r< nrows);
576assert((capacityrowsigns[
r] &
INVERTED) == 0);
577assert(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 )
636assert(mcfdata->arcsources[globala] < mcfdata->nnodes);
637assert(0 <= compnodeid[mcfdata->arcsources[globala]] && compnodeid[mcfdata->arcsources[globala]] < mcfnetwork->
nnodes);
638mcfnetwork->
arcsources[
a] = compnodeid[mcfdata->arcsources[globala]];
640 if( mcfdata->arctargets[globala] >= 0 )
642assert(mcfdata->arctargets[globala] < mcfdata->nnodes);
643assert(0 <= compnodeid[mcfdata->arctargets[globala]] && compnodeid[mcfdata->arctargets[globala]] < mcfnetwork->
nnodes);
644mcfnetwork->
arctargets[
a] = compnodeid[mcfdata->arctargets[globala]];
649 for( c = 0; c < ncols; c++ )
659 for( i = 0; i < ncompnodes; i++ )
661assert(0 <= compnodes[i] && compnodes[i] < mcfdata->nnodes);
662assert(compnodeid[compnodes[i]] == i);
663compnodeid[compnodes[i]] = -1;
680 if( mcfnetwork ==
NULL)
687 for( v = 0; v < mcfnetwork->
nnodes; v++ )
706 for(
a= 0;
a< mcfnetwork->
narcs;
a++ )
722voidprintCommodities(
727 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
728 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
729 intncommodities = 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++ )
754 MCFdebugMessage(
"commodity %d (sign: %+d):\n", k, commoditysigns[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);
789assert(capacityrows !=
NULL|| mcfdata->narcs == 0);
792 for(
a= 0;
a< mcfdata->narcs;
a++ )
795 if( capacityrows[
a] !=
NULL)
798assert(0 <=
r&&
r< nrows);
809assert(colcommodity !=
NULL|| ncols == 0);
812 for( c = 0; c < ncols; c++ )
814 if( colcommodity[c] == -1 )
823 for(
r= 0;
r< nrows;
r++ )
825assert(rowcommodity !=
NULL);
843 if( rowscores[ind2] < rowscores[ind1] )
845 else if( rowscores[ind2] > rowscores[ind1] )
858 unsigned char* flowrowsigns;
878flowrowsigns = mcfdata->flowrowsigns;
879flowrowscalars = mcfdata->flowrowscalars;
880flowrowscores = mcfdata->flowrowscores;
881flowcands = mcfdata->flowcands;
883assert(mcfdata->nflowcands == 0);
886 for(
r= 0;
r< nrows;
r++ )
911absdualsol =
ABS(absdualsol);
913flowrowsigns[
r] = 0;
914flowrowscalars[
r] = 0.0;
915flowrowscores[
r] = 0.0;
936coef =
ABS(rowvals[0]);
943 for( i = 0; i < rowlen; i++ )
949hasposcoef = hasposcoef || (rowvals[i] > 0.0);
950hasnegcoef = hasnegcoef || (rowvals[i] < 0.0);
980flowrowscalars[
r] = 1.0/coef;
981flowcands[mcfdata->nflowcands] =
r;
982mcfdata->nflowcands++;
990flowrowscores[
r] += 1000.0;
993 if( hasposcoef && hasnegcoef )
994flowrowscores[
r] += 500.0;
1001 if( ncontvars == rowlen )
1002flowrowscores[
r] += 1000.0;
1003 else if( nintvars + nimplintvars == rowlen )
1004flowrowscores[
r] += 500.0;
1005 else if( nbinvars == rowlen )
1006flowrowscores[
r] += 100.0;
1010flowrowscores[
r] += 10.0*rowlen/(rowlen+10.0);
1014flowrowscores[
r] += 50.0;
1016assert(flowrowscores[
r] > 0.0);
1019maxdualflow =
MAX(maxdualflow, absdualsol);
1032 for( i = 0; i < mcfdata->nflowcands; i++ )
1037assert(0 <=
r&&
r< nrows);
1042dualsol =
ABS(dualsol);
1045assert(maxdualflow > 0.0);
1046flowrowscores[
r] += dualsol/maxdualflow + 1.0;
1047assert(flowrowscores[
r] > 0.0);
1052 SCIPsortInd(mcfdata->flowcands, compCands, (
void*)flowrowscores, mcfdata->nflowcands);
1054 MCFdebugMessage(
"flow conservation candidates [%d]\n", mcfdata->nflowcands);
1056 for(
r= 0;
r< mcfdata->nflowcands;
r++ )
1059 SCIPdebugMsg(
scip,
"%4d [score: %2g]: %s\n", mcfdata->flowcands[
r], flowrowscores[mcfdata->flowcands[
r]],
1074 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1075 int* colcommodity = mcfdata->colcommodity;
1076 intncommodities = mcfdata->ncommodities;
1077 intnactivecommodities = mcfdata->ncommodities - mcfdata->nemptycommodities;
1080 unsigned char* capacityrowsigns;
1082 int* capacitycands;
1089 intmaxcolspercommoditylimit;
1090 int*ncolspercommodity;
1091 int*maxcolspercommodity;
1101capacityrowsigns = mcfdata->capacityrowsigns;
1102capacityrowscores = mcfdata->capacityrowscores;
1103capacitycands = mcfdata->capacitycands;
1105assert(mcfdata->ncapacitycands == 0);
1112 switch( modeltype )
1115maxcolspercommoditylimit = 2;
1118maxcolspercommoditylimit = 1;
1121maxcolspercommoditylimit = 2;
1124 SCIPerrorMessage(
"invalid parameter value %d for model type\n", modeltype);
1128maxdualcapacity = 0.0;
1129directedcandsscore = 0.0;
1130undirectedcandsscore = 0.0;
1131 for(
r= 0;
r< nrows;
r++ )
1141 intnposcapacitycoefs;
1142 intnnegcapacitycoefs;
1144 intncoveredcommodities;
1149 unsigned charrowsign;
1155capacityrowsigns[
r] = 0;
1156capacityrowscores[
r] = 0.0;
1175absdualsol =
ABS(absdualsol);
1184maxcolspercommodity[
r] = 0;
1189nposcapacitycoefs = 0;
1190nnegcapacitycoefs = 0;
1192ncoveredcommodities = 0;
1194sameabsflowcoef = 0.0;
1195maxabscapacitycoef = 0.0;
1202 for( i = 0; i < rowlen; i++ )
1209assert(colcommodity !=
NULL);
1212k = colcommodity[c];
1213assert(-1 <= k && k < ncommodities);
1218abscoef =
ABS(rowvals[i]);
1219 if( sameflowcoef == 0.0 )
1220sameflowcoef = rowvals[i];
1221 else if( !
SCIPisEQ(
scip, sameflowcoef, rowvals[i]) )
1223 if( sameabsflowcoef == 0.0 )
1224sameabsflowcoef = abscoef;
1225 else if( !
SCIPisEQ(
scip, sameabsflowcoef, abscoef) )
1228 if( rowvals[i] > 0.0 )
1234 if( ncolspercommodity[k] == 0 )
1235ncoveredcommodities++;
1236ncolspercommodity[k]++;
1237maxcolspercommodity[
r] =
MAX(maxcolspercommodity[
r], ncolspercommodity[k]);
1239 if( ncolspercommodity[k] >= 2 )
1248abscoef =
ABS(rowvals[i]);
1249 if( abscoef > maxabscapacitycoef )
1250maxabscapacitycoef = abscoef;
1253 if( rowvals[i] > 0.0 )
1254nposcapacitycoefs++;
1256nnegcapacitycoefs++;
1266 if( rowsign != 0 && nposflowcoefs + nnegflowcoefs > 0 )
1270capacityrowsigns[
r] |= rowsign;
1271capacitycands[mcfdata->ncapacitycands] =
r;
1272mcfdata->ncapacitycands++;
1275capacityrowscores[
r] = 1.0;
1279assert(ncoveredcommodities > 0);
1281commodityexcessratio =
1282 ABS((nposflowcoefs + nnegflowcoefs)/(
SCIP_Real)ncoveredcommodities - maxcolspercommoditylimit);
1284capacityrowscores[
r] += 1000.0 *
MAX(0.0, 2.0 - commodityexcessratio);
1291 if( (capacityrowsigns[
r] &
RHSPOSSIBLE) != 0 && nnegflowcoefs == 0 && nposcapacitycoefs == 0 && nnegcapacitycoefs > 0 )
1292capacityrowscores[
r] += 1000.0;
1293 if( (capacityrowsigns[
r] &
LHSPOSSIBLE) != 0 && nposflowcoefs == 0 && nposcapacitycoefs > 0 && nnegcapacitycoefs == 0 )
1294capacityrowscores[
r] += 1000.0;
1303assert(nactivecommodities + 3 > 0);
1304capacityrowscores[
r] += 2000.0 * ncoveredcommodities/(
SCIP_Real)(nactivecommodities + 3);
1308capacityrowscores[
r] += 500.0;
1312capacityrowscores[
r] += 250.0;
1316capacityrowscores[
r] += 100.0;
1319 if( maxabscapacitycoef > 0.0 && !
SCIPisEQ(
scip, maxabscapacitycoef, 1.0) )
1320capacityrowscores[
r] += 100.0;
1323capacityrowscores[
r] += 20.0 *
MAX(nposflowcoefs, nnegflowcoefs)/
MAX(1.0,(
SCIP_Real)(nposflowcoefs + nnegflowcoefs));
1326capacityrowscores[
r] += 10.0 *
MAX(nposcapacitycoefs, nnegcapacitycoefs)/(
SCIP_Real)(nposcapacitycoefs+nnegcapacitycoefs+1.0);
1330capacityrowscores[
r] += 10.0;
1334capacityrowscores[
r] += 10.0;
1336assert(capacityrowscores[
r] > 0.0);
1337 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",
1338 SCIProwGetName(row), maxcolspercommodity[
r], capacityrowsigns[
r], nposflowcoefs, nnegflowcoefs, nposcapacitycoefs, nnegcapacitycoefs, nbadcoefs, nactivecommodities, sameflowcoef, capacityrowscores[
r]);
1341maxdualcapacity =
MAX(maxdualcapacity, absdualsol);
1346assert(maxcolspercommoditylimit == 2);
1348undirectedcandsscore += capacityrowscores[
r];
1350directedcandsscore += capacityrowscores[
r];
1355 SCIPdebugMsg(
scip,
"row <%s>: rowsign = %d nposflowcoefs = %d nnegflowcoefs = %d -> discard\n",
1363 if( directedcandsscore > undirectedcandsscore )
1368 MCFdebugMessage(
"detected model type: %s (%g directed score, %g undirected score)\n",
1376 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1378 r= capacitycands[i];
1379assert(0 <=
r&&
r< nrows);
1383 if( maxcolspercommodity[
r] <= maxcolspercommoditylimit )
1384capacityrowscores[
r] -= 1000.0;
1390mcfdata->modeltype = modeltype;
1398 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1402 r= capacitycands[i];
1403assert(0 <=
r&&
r< nrows);
1408dualsol =
ABS(dualsol);
1411assert(maxdualcapacity > 0.0);
1412capacityrowscores[
r] +=
MAX(dualsol, 0.0)/maxdualcapacity;
1413assert(capacityrowscores[
r] > 0.0);
1418 SCIPsortInd(mcfdata->capacitycands, compCands, (
void*)capacityrowscores, mcfdata->ncapacitycands);
1420 MCFdebugMessage(
"capacity candidates [%d]\n", mcfdata->ncapacitycands);
1422 for(
r= 0;
r< mcfdata->ncapacitycands;
r++ )
1424 SCIPdebugMsg(
scip,
"row %4d [score: %2g]: %s\n", mcfdata->capacitycands[
r],
1425capacityrowscores[mcfdata->capacitycands[
r]],
SCIProwGetName(rows[mcfdata->capacitycands[
r]]));
1445assert(mcfdata->ncommodities <= mcfdata->commoditysignssize);
1446 if( mcfdata->ncommodities == mcfdata->commoditysignssize )
1448mcfdata->commoditysignssize =
MAX(2*mcfdata->commoditysignssize, mcfdata->ncommodities+1);
1451assert(mcfdata->ncommodities < mcfdata->commoditysignssize);
1454 SCIPdebugMsg(
scip,
"**** creating new commodity %d ****\n", mcfdata->ncommodities);
1455mcfdata->commoditysigns[mcfdata->ncommodities] = 0;
1456mcfdata->ncommodities++;
1471assert(source != target );
1472assert(0 <= source && source < mcfdata->
nnodes);
1473assert(0 <= target && target < mcfdata->
nnodes);
1474assert(newarcid !=
NULL);
1476*newarcid = mcfdata->narcs;
1479assert(mcfdata->narcs <= mcfdata->arcarraysize);
1480 if( mcfdata->narcs == mcfdata->arcarraysize )
1482mcfdata->arcarraysize =
MAX(2*mcfdata->arcarraysize, mcfdata->narcs+1);
1488assert(mcfdata->narcs < mcfdata->arcarraysize);
1491 if( mcfdata->capacityrowssize < mcfdata->arcarraysize )
1493mcfdata->capacityrowssize = mcfdata->arcarraysize;
1496assert(mcfdata->narcs < mcfdata->capacityrowssize);
1499 SCIPdebugMsg(
scip,
"**** creating new arc %d: %d -> %d ****\n", mcfdata->narcs, source, target);
1501mcfdata->arcsources[*newarcid] = source;
1502mcfdata->arctargets[*newarcid] = target;
1503mcfdata->nextoutarcs[*newarcid] = mcfdata->firstoutarcs[source];
1504mcfdata->firstoutarcs[source] = *newarcid;
1505mcfdata->nextinarcs[*newarcid] = mcfdata->firstinarcs[target];
1506mcfdata->firstinarcs[target] = *newarcid;
1507mcfdata->capacityrows[*newarcid] =
NULL;
1520 unsigned charrowsign,
1525 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1526 SCIP_Bool* plusflow = mcfdata->plusflow;
1527 SCIP_Bool* minusflow = mcfdata->minusflow;
1528 intncommodities = mcfdata->ncommodities;
1529 int* commoditysigns = mcfdata->commoditysigns;
1530 int* colcommodity = mcfdata->colcommodity;
1531 int* rowcommodity = mcfdata->rowcommodity;
1532 int* newcols = mcfdata->newcols;
1543assert(comcolids !=
NULL);
1544assert(ncomcolids !=
NULL);
1553invertrow = ((rowsign &
INVERTED) != 0);
1554rowsign &= ~INVERTED;
1556assert(rowcommodity[
r] == -1);
1557assert((flowrowsigns[
r] | rowsign) == flowrowsigns[
r]);
1559assert(rowsign != 0);
1565commoditysigns[k] = +1;
1581 if( dualsol > 0.0 )
1594 else if( rowlhs > 0.0 )
1611flowrowsigns[
r] |= rowsign;
1613 SCIPdebugMsg(
scip,
"adding flow row %d <%s> with sign %+d%s to commodity %d [score:%g]\n",
1615k, mcfdata->flowrowscores[
r]);
1619rowcommodity[
r] = k;
1623 for( i = 0; i < rowlen; i++ )
1632 if( colcommodity[c] == -1 )
1634assert(!plusflow[c]);
1635assert(!minusflow[c]);
1637colcommodity[c] = k;
1638newcols[mcfdata->nnewcols] = c;
1639mcfdata->nnewcols++;
1640comcolids[*ncomcolids] = c;
1643assert(colcommodity[c] == k);
1646val = rowscale * rowvals[i];
1649assert(!plusflow[c]);
1650plusflow[c] =
TRUE;
1654assert(!minusflow[c]);
1655minusflow[c] =
TRUE;
1672 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1673 SCIP_Bool* plusflow = mcfdata->plusflow;
1674 SCIP_Bool* minusflow = mcfdata->minusflow;
1678assert(mcfdata->commoditysigns[k] == 0);
1679assert(comrows !=
NULL|| ncomrows == 0);
1680assert(comcolids !=
NULL);
1683 for( i = 0; i < ncomrows; i++ )
1687 unsigned charrowsign;
1689assert(comrows !=
NULL);
1691assert( row !=
NULL);
1694assert(mcfdata->rowcommodity[
r] == k);
1698rowsign = flowrowsigns[
r];
1700assert((rowsign &
INVERTED) == 0);
1710 for( i = 0; i < ncomcolids; i++ )
1717assert(mcfdata->colcommodity[c] == k);
1720plusflow[c] = minusflow[c];
1737 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1738 SCIP_Bool* plusflow = mcfdata->plusflow;
1739 SCIP_Bool* minusflow = mcfdata->minusflow;
1740 intncommodities = mcfdata->ncommodities;
1741 int* colcommodity = mcfdata->colcommodity;
1742 int* rowcommodity = mcfdata->rowcommodity;
1746assert(0 <= k && k < ncommodities);
1748assert( ndelflowrows !=
NULL);
1749assert( ndelflowvars !=
NULL);
1751 SCIPdebugMsg(
scip,
"deleting commodity %d (%d total commodities) with %d flow rows\n", k, ncommodities, nrows);
1756 for( n = 0; n < nrows; n++ )
1767assert(rowcommodity[
r] == k);
1776rowcommodity[
r] = -1;
1779 for( i = 0; i < rowlen; i++ )
1787assert(colcommodity[c] == k || colcommodity[c] == -1);
1788 if(colcommodity[c] == k)
1790colcommodity[c] = -1;
1793plusflow[c] =
FALSE;
1794minusflow[c] =
FALSE;
1803 if( k == ncommodities-1 )
1804mcfdata->ncommodities--;
1806mcfdata->nemptycommodities++;
1816 unsigned char* rowsign,
1820 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1821 SCIP_Bool* plusflow = mcfdata->plusflow;
1822 SCIP_Bool* minusflow = mcfdata->minusflow;
1823 int* colcommodity = mcfdata->colcommodity;
1824 int* rowcommodity = mcfdata->rowcommodity;
1825 int* commoditysigns = mcfdata->commoditysigns;
1830 unsigned charflowrowsign;
1831 unsigned charinvflowrowsign;
1835assert(invertcommodity !=
NULL);
1838*invertcommodity =
FALSE;
1844 if( rowcommodity[
r] != -1 )
1848flowrowsign = flowrowsigns[
r];
1854invflowrowsign = flowrowsign;
1860 for( j = 0; j < rowlen && (flowrowsign != 0 || invflowrowsign != 0); j++ )
1868 if( colcommodity[rowc] == k )
1871 if( plusflow[rowc] )
1874 if( rowvals[j] > 0.0 )
1876flowrowsign &= ~RHSPOSSIBLE;
1877invflowrowsign &= ~LHSPOSSIBLE;
1881flowrowsign &= ~LHSPOSSIBLE;
1882invflowrowsign &= ~RHSPOSSIBLE;
1885 if( minusflow[rowc] )
1888 if( rowvals[j] > 0.0 )
1890flowrowsign &= ~LHSPOSSIBLE;
1891invflowrowsign &= ~RHSPOSSIBLE;
1895flowrowsign &= ~RHSPOSSIBLE;
1896invflowrowsign &= ~LHSPOSSIBLE;
1900 else if( colcommodity[rowc] != -1 )
1908 if( flowrowsign != 0 )
1911*rowsign = flowrowsign;
1912*invertcommodity =
FALSE;
1914 else if( invflowrowsign != 0 )
1920 if( commoditysigns ==
NULL|| commoditysigns[k] == 0 )
1923*rowsign = invflowrowsign;
1924*invertcommodity =
TRUE;
1929*rowsign = (invflowrowsign |
INVERTED);
1930*invertcommodity =
FALSE;
1947 unsigned char* nextrowsign,
1951 SCIP_Real* flowrowscores = mcfdata->flowrowscores;
1952 SCIP_Bool* plusflow = mcfdata->plusflow;
1953 SCIP_Bool* minusflow = mcfdata->minusflow;
1954 int* newcols = mcfdata->newcols;
1955 intncommodities = mcfdata->ncommodities;
1960assert(nextrow !=
NULL);
1961assert(nextrowsign !=
NULL);
1965*nextinvertcommodity =
FALSE;
1970assert(cols !=
NULL);
1973 while( mcfdata->nnewcols > 0 )
1979 unsigned charbestrowsign;
1986c = newcols[mcfdata->nnewcols-1];
1987mcfdata->nnewcols--;
1991assert(plusflow[c] || minusflow[c]);
1992 if( plusflow[c] && minusflow[c] )
1998bestinvertcommodity =
FALSE;
2003 for( i = 0; i < collen; i++ )
2006 unsigned charflowrowsign;
2015 if( flowrowsign != 0 )
2022score = flowrowscores[
r];
2023assert(score > 0.0);
2029 if( (flowrowsign &
INVERTED) != 0 )
2032 if( score > bestscore )
2035bestrowsign = flowrowsign;
2036bestinvertcommodity = invertcommodity;
2046 if( bestrow !=
NULL)
2048assert(bestscore > 0.0);
2049assert(bestrowsign != 0);
2051*nextrowsign = bestrowsign;
2052*nextinvertcommodity = bestinvertcommodity;
2067 int* flowcands = mcfdata->flowcands;
2094assert(failed !=
NULL);
2103plusflow = mcfdata->plusflow;
2104minusflow = mcfdata->minusflow;
2105colcommodity = mcfdata->colcommodity;
2106rowcommodity = mcfdata->rowcommodity;
2118 for( c = 0; c < ncols; c++ )
2119colcommodity[c] = -1;
2120 for(
r= 0;
r< nrows;
r++ )
2121rowcommodity[
r] = -1;
2123assert(flowcands !=
NULL|| mcfdata->nflowcands == 0);
2134 for( i = 0; i < mcfdata->nflowcands; i++ )
2137 unsigned charnewrowsign;
2141assert(flowcands !=
NULL);
2143assert(0 <=
r&&
r< nrows);
2147 getFlowrowFit(
scip, mcfdata, newrow, mcfdata->ncommodities, &newrowsign, &newinvertcommodity);
2148 if( newrowsign == 0 )
2150assert(!newinvertcommodity);
2151assert((newrowsign &
INVERTED) == 0);
2154 SCIPdebugMsg(
scip,
" -------------------start new commodity %d--------------------- \n", mcfdata->ncommodities );
2163 if( newinvertcommodity )
2169comrows[
nnodes] = newrow;
2176 while( newrow !=
NULL);
2178ncomnodes[mcfdata->ncommodities-1] =
nnodes;
2180nflowvars += ncomcolids;
2181 SCIPdebugMsg(
scip,
" -> finished commodity %d: identified %d nodes, maxnnodes=%d\n", mcfdata->ncommodities-1,
nnodes, maxnnodes);
2190nflowrows -= ndelflowrows;
2191nflowvars -= ndelflowvars;
2192assert(nflowvars >= 0);
2193assert(nflowrows >= 0);
2197 for( k = 0; k < mcfdata->ncommodities; k++ )
2209 for( i = 0; i < mcfdata->nflowcands; i++ )
2211assert(flowcands !=
NULL);
2213 if( rowcommodity[
r] == k )
2215comrows[
nnodes] = rows[
r];
2218 if(
nnodes== ncomnodes[k] )
2223assert(
nnodes== ncomnodes[k]);
2225nflowrows -= ndelflowrows;
2226nflowvars -= ndelflowvars;
2227assert(nflowvars >= 0);
2228assert(nflowrows >= 0);
2237 MCFdebugMessage(
"identified %d commodities (%d empty) with a maximum of %d nodes and %d flowrows, %d flowvars \n",
2238mcfdata->ncommodities, mcfdata->nemptycommodities, maxnnodes, nflowrows, nflowvars);
2240assert(nflowvars >= 0);
2241assert(nflowrows >= 0);
2244 if( nflowrows == 0)
2259 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
2260 int* colcommodity = mcfdata->colcommodity;
2262 unsigned char* flowrowsigns = mcfdata->capacityrowsigns;
2263 int* rowcommodity = mcfdata->rowcommodity;
2279 SCIP_Real* capacityrowscores = mcfdata->capacityrowscores;
2281 int*capacitycands = mcfdata->capacitycands;
2282 intncapacitycands = mcfdata->ncapacitycands;
2284assert(mcfdata->narcs == 0);
2285assert(capacitycands !=
NULL|| ncapacitycands == 0);
2294colarcid = mcfdata->colarcid;
2295rowarcid = mcfdata->rowarcid;
2298 for( c = 0; c < ncols; c++ )
2300 for(
r= 0;
r< nrows;
r++ )
2304 for( i = 0; i < ncapacitycands; i++ )
2309 intnassignedflowvars;
2310 intnunassignedflowvars;
2313assert(capacitycands !=
NULL);
2314 r= capacitycands[i];
2315assert(0 <=
r&&
r< nrows );
2316capacityrow = rows[
r];
2318assert(capacityrowsigns !=
NULL);
2319assert(capacityrowscores !=
NULL);
2320assert(rowcommodity !=
NULL);
2321assert(flowrowsigns !=
NULL);
2325assert((capacityrowsigns[
r] &
DISCARDED) == 0);
2326assert(capacityrowscores[
r] > 0.0);
2330assert(rowarcid[
r] == -1);
2333assert( rowcommodity[
r] == -1 );
2339nassignedflowvars = 0;
2340nunassignedflowvars = 0;
2341 for( k = 0; k < rowlen; k++ )
2344assert(0 <= c && c < ncols);
2345assert(colcommodity !=
NULL);
2347assert(-1 <= colcommodity[c] && colcommodity[c] < mcfdata->ncommodities);
2348assert(-1 <= colarcid[c] && colarcid[c] < mcfdata->narcs);
2351 if( colcommodity[c] == -1 )
2355 if( colarcid[c] >= 0 )
2356nassignedflowvars++;
2358nunassignedflowvars++;
2365 if( nunassignedflowvars == 0 || nassignedflowvars >= nunassignedflowvars * 2 )
2367 SCIPdebugMsg(
scip,
"discarding capacity candidate row %d <%s> [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2368 r,
SCIProwGetName(capacityrow), mcfdata->capacityrowscores[
r], nassignedflowvars, nunassignedflowvars);
2374assert(mcfdata->narcs <= mcfdata->capacityrowssize);
2375 if( mcfdata->narcs == mcfdata->capacityrowssize )
2377mcfdata->capacityrowssize =
MAX(2*mcfdata->capacityrowssize, mcfdata->narcs+1);
2380assert(mcfdata->narcs < mcfdata->capacityrowssize);
2381assert(mcfdata->narcs < nrows);
2383mcfdata->capacityrows[mcfdata->narcs] = capacityrow;
2386assert(0 <=
r&&
r< nrows);
2387rowarcid[
r] = mcfdata->narcs;
2398 SCIPdebugMsg(
scip,
"assigning capacity row %d <%s> with sign %+d to arc %d [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2400mcfdata->capacityrowscores[
r], nassignedflowvars, nunassignedflowvars);
2403 for( k = 0; k < rowlen; k++ )
2406assert(0 <= rowc && rowc < ncols);
2407assert(colcommodity !=
NULL);
2412 if( colcommodity[rowc] >= 0 && colarcid[rowc] == -1 )
2413colarcid[rowc] = mcfdata->narcs;
2432 int* colcommodity = mcfdata->colcommodity;
2433 int* colarcid = mcfdata->colarcid;
2434 int* newcols = mcfdata->newcols;
2435 SCIP_ROW** capacityrows = mcfdata->capacityrows;
2436 SCIP_Bool* colisincident = mcfdata->colisincident;
2445assert(!colisincident[i]);
2451mcfdata->nnewcols = 0;
2453 for( i = 0; i < rowlen; i++ )
2465arcid = colarcid[c];
2468assert(arcid < mcfdata->
narcs);
2471assert(capacityrows[arcid] !=
NULL);
2475 for( j = 0; j < capacityrowlen; j++ )
2483 if( colcommodity[caprowc] == -1 )
2485assert(colarcid[caprowc] == -1);
2488assert(colarcid[caprowc] <= arcid);
2491 if( colcommodity[caprowc] == basecommodity )
2495 if( !colisincident[caprowc] )
2498colisincident[caprowc] =
TRUE;
2499newcols[mcfdata->nnewcols] = caprowc;
2500mcfdata->nnewcols++;
2514 int* basearcpattern,
2523 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2524 int* commoditysigns = mcfdata->commoditysigns;
2525 int narcs= mcfdata->narcs;
2526 int* rowcommodity = mcfdata->rowcommodity;
2527 int* colarcid = mcfdata->colarcid;
2528 int* arcpattern = mcfdata->zeroarcarray;
2541 int* overlappingarcs;
2542 intnoverlappingarcs;
2547*invertcommodity =
FALSE;
2550 for( i = 0; i <
narcs; i++ )
2551assert(arcpattern[i] == 0);
2560rowcom = rowcommodity[
r];
2561assert(0 <= rowcom && rowcom < mcfdata->ncommodities);
2562rowcomsign = commoditysigns[rowcom];
2563assert(-1 <= rowcomsign && rowcomsign <= +1);
2568incompatible =
FALSE;
2569noverlappingarcs = 0;
2573 for( i = 0; i < rowlen; i++ )
2583valsign = (rowvals[i] > 0.0 ? +1 : -1);
2586 if( (flowrowsigns[
r] &
INVERTED) != 0 )
2589arcid = colarcid[c];
2598assert(arcid <
narcs);
2601 if( basearcpattern[arcid] != 0 )
2608 if( ( valsign * basearcpattern[arcid] ) > 0 )
2613 if( rowcomsign == 0 )
2616rowcomsign = validcomsign;
2618 else if( rowcomsign != validcomsign )
2621incompatible =
TRUE;
2632 if( arcpattern[arcid] == 0 )
2634overlappingarcs[noverlappingarcs] = arcid;
2637arcpattern[arcid] += valsign;
2643 for( i = 0; i < noverlappingarcs; i++ )
2649arcid = overlappingarcs[i];
2650assert(0 <= arcid && arcid <
narcs);
2653basenum =
ABS(basearcpattern[arcid]);
2654arcnum =
ABS(arcpattern[arcid]);
2655assert(basenum != 0.0);
2656assert(arcnum != 0.0);
2658 if( basenum > arcnum )
2659overlap += arcnum/basenum;
2661overlap += basenum/arcnum;
2663arcpattern[arcid] = 0;
2667 if( !incompatible && overlap > 0.0 )
2670 introwarcs = rowlen - nposuncap - nneguncap;
2671 intbaserowarcs = baserowlen - basenposuncap - basenneguncap;
2673assert(overlap <= (
SCIP_Real) rowlen);
2674assert(overlap <= (
SCIP_Real) baserowlen);
2675assert(noverlappingarcs >= 1);
2677*invertcommodity = (rowcomsign == -1);
2681 if( noverlappingarcs >= 2 )
2684assert(rowarcs >= 0 && baserowarcs >= 0 );
2687*score = overlap - (rowarcs + baserowarcs - 2.0 * overlap)/(2.0 * ncols + 1.0);
2689*score = overlap - (rowarcs + baserowarcs - 4.0 * overlap)/(2.0 * ncols + 1.0);
2692 if(*invertcommodity)
2693*score += 1.0 - (
ABS(nneguncap - basenposuncap) +
ABS(nposuncap - basenneguncap))/(2.0 * ncols + 1.0);
2695*score += 1.0 - (
ABS(nposuncap - basenposuncap) +
ABS(nneguncap - basenneguncap))/(2.0 * ncols + 1.0);
2697*score =
MAX(*score, 1e-6);
2700 SCIPdebugMsg(
scip,
" -> node similarity: row <%s>: incompatible=%u overlap=%g rowlen=%d baserowlen=%d score=%g\n",
2701 SCIProwGetName(row), incompatible, overlap, rowlen, baserowlen, *score);
2716 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2717 intncommodities = mcfdata->ncommodities;
2718 int* commoditysigns = mcfdata->commoditysigns;
2719 int narcs= mcfdata->narcs;
2720 int* flowcands = mcfdata->flowcands;
2721 intnflowcands = mcfdata->nflowcands;
2722 int* rowcommodity = mcfdata->rowcommodity;
2723 int* colarcid = mcfdata->colarcid;
2724 int* newcols = mcfdata->newcols;
2745assert(mcfdata->nnodes == 0);
2757rownodeid = mcfdata->rownodeid;
2758colisincident = mcfdata->colisincident;
2768 for(
r= 0;
r< nrows;
r++ )
2769rownodeid[
r] = -1;
2770 for( c = 0; c < ncols; c++ )
2771colisincident[c] =
FALSE;
2773assert(flowcands !=
NULL|| nflowcands == 0);
2776 for( n = 0; n < nflowcands; n++ )
2785assert(flowcands !=
NULL);
2787assert(0 <=
r&&
r< nrows);
2788assert(rowcommodity !=
NULL);
2791basecommodity = rowcommodity[
r];
2792 if( basecommodity == -1 )
2795assert(mcfdata->rowarcid[
r] == -1);
2798 if( rownodeid[
r] >= 0 )
2802 SCIPdebugMsg(
scip,
"assigning row %d <%s> of commodity %d to node %d [score: %g]\n",
2803 r,
SCIProwGetName(rows[
r]), basecommodity, mcfdata->nnodes, mcfdata->flowrowscores[
r]);
2804rownodeid[
r] = mcfdata->nnodes;
2812 if(ncommodities == 1)
2824assert(commoditysigns !=
NULL);
2830 if( (flowrowsigns[
r] &
INVERTED) != 0 )
2832 if( commoditysigns[basecommodity] == -1 )
2835 for( i = 0; i < rowlen; i++ )
2840assert(0 <= c && c < ncols);
2841arcid = colarcid[c];
2846arcpattern[arcid]++;
2848arcpattern[arcid]--;
2861 for( i = 0; i < ncommodities; i++ )
2863bestflowrows[i] =
NULL;
2864bestscores[i] = 0.0;
2865bestinverted[i] =
FALSE;
2877 for( i = 0; i < mcfdata->nnewcols; i++ )
2883assert(newcols !=
NULL);
2885assert(0 <= c && c < ncols);
2886assert(mcfdata->colcommodity[c] >= 0);
2887assert(mcfdata->colcommodity[c] != basecommodity);
2890assert(colisincident[c]);
2891colisincident[c] =
FALSE;
2897 for( j = 0; j < collen; j++ )
2905assert(0 <= colr && colr < nrows);
2908 if( rowprocessed[colr] )
2910rowprocessed[colr] =
TRUE;
2913rowcom = rowcommodity[colr];
2914assert(rowcom != basecommodity);
2918assert(rowcom == mcfdata->colcommodity[c]);
2920assert(mcfdata->rowarcid[colr] == -1);
2923 if( rownodeid[colr] >= 0 )
2928nposuncap, nneguncap, colrows[j], &score, &invertcommodity) );
2931 if( score > bestscores[rowcom] )
2933bestflowrows[rowcom] = colrows[j];
2934bestscores[rowcom] = score;
2935bestinverted[rowcom] = invertcommodity;
2939assert(bestflowrows[basecommodity] ==
NULL);
2942 for( i = 0; i < ncommodities; i++ )
2946 if( bestflowrows[i] ==
NULL)
2950assert(0 <= comr && comr < nrows);
2951assert(rowcommodity[comr] == i);
2953assert(rownodeid[comr] == -1);
2954assert(mcfdata->nnodes >= 1);
2956 SCIPdebugMsg(
scip,
" -> assigning row %d <%s> of commodity %d to node %d [invert:%u]\n",
2957comr,
SCIProwGetName(rows[comr]), i, mcfdata->nnodes-1, bestinverted[i]);
2958rownodeid[comr] = mcfdata->nnodes-1;
2961 if( bestinverted[i] )
2963assert(commoditysigns[i] != +1);
2964commoditysigns[i] = -1;
2968assert(commoditysigns[i] != -1);
2969commoditysigns[i] = +1;
2991 int* commoditysigns = mcfdata->commoditysigns;
2994 for( k = 0; k < mcfdata->ncommodities; k++ )
2996 if( commoditysigns[k] == 0 )
2997commoditysigns[k] = +1;
3012 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3013 int* commoditysigns = mcfdata->commoditysigns;
3014 int* rowcommodity = mcfdata->rowcommodity;
3015 int* rownodeid = mcfdata->rownodeid;
3016 int* colsources = mcfdata->colsources;
3017 int* coltargets = mcfdata->coltargets;
3025assert(sourcenode !=
NULL);
3026assert(targetnode !=
NULL);
3027assert(colsources !=
NULL);
3028assert(coltargets !=
NULL);
3034 if( colsources[c] >= -1 )
3036assert(coltargets[c] >= -1);
3037*sourcenode = colsources[c];
3038*targetnode = coltargets[c];
3049 for( i = 0; i < collen; i++ )
3056 if( rownodeid[
r] >= 0 )
3063k = rowcommodity[
r];
3064assert(0 <= v && v < mcfdata->
nnodes);
3065assert(0 <= k && k < mcfdata->ncommodities);
3072 if( (flowrowsigns[
r] &
INVERTED) != 0 )
3074 if( commoditysigns[k] == -1 )
3078 if( ( scale * colvals[i] ) > 0.0 )
3080assert(*sourcenode == -1);
3082 if( *targetnode >= 0 )
3087assert(*targetnode == -1);
3089 if( *sourcenode >= 0 )
3096colsources[c] = *sourcenode;
3097coltargets[c] = *targetnode;
3108 int* flowcands = mcfdata->flowcands;
3109 intnflowcands = mcfdata->nflowcands;
3111 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3112 int* colcommodity = mcfdata->colcommodity;
3113 int* rowcommodity = mcfdata->rowcommodity;
3115 int* rownodeid = mcfdata->rownodeid;
3116 int* colarcid = mcfdata->colarcid;
3117 int nnodes= mcfdata->nnodes;
3118 intncommodities = mcfdata->ncommodities;
3125 int* sortedflowcands;
3126 int* sortedflowcandnodeid;
3139assert(mcfdata->nemptycommodities == 0);
3140assert(ncommodities >= 0);
3144 if( ncommodities == 0 || nflowcands == 0 ||
nnodes== 0 )
3153assert(rows !=
NULL);
3154assert(cols !=
NULL|| ncols == 0);
3165 for( n = 0; n < nflowcands; n++ )
3167sortedflowcands[n] = flowcands[n];
3168sortedflowcandnodeid[n] = rownodeid[flowcands[n]];
3172 SCIPsortIntInt(sortedflowcandnodeid, sortedflowcands, nflowcands);
3173assert(sortedflowcandnodeid[0] <= 0);
3174assert(sortedflowcandnodeid[nflowcands-1] ==
nnodes-1);
3177 for( v = 0; v <
nnodes; v++ )
3193 for( n = 0; n < nflowcands; n++ )
3195 if( sortedflowcandnodeid[n] >= 0 )
3198assert(rowcommodity[sortedflowcands[n]] == -1);
3200assert(n < nflowcands);
3201assert(sortedflowcandnodeid[n] == 0);
3206 for( v = 0; n < nflowcands; v++ )
3212assert(rowcommodity[sortedflowcands[n]] >= 0);
3213assert(rownodeid[sortedflowcands[n]] == sortedflowcandnodeid[n]);
3214assert(sortedflowcandnodeid[n] == v);
3215assert(nadjnodes == 0);
3216assert(ninccols == 0);
3221 for( ; n < nflowcands && sortedflowcandnodeid[n] == v; n++ )
3228 r= sortedflowcands[n];
3230assert(mcfdata->rowarcid[
r] == -1);
3235 for( i = 0; i < rowlen; i++ )
3246arcid = colarcid[c];
3247assert(-2 <= arcid && arcid < mcfdata->
narcs);
3248assert(rowcommodity[
r] == colcommodity[c]);
3258 else if( arcid == -1 )
3268assert(-1 <= s && s <
nnodes);
3269assert(-1 <= t && t <
nnodes);
3270assert(s == v || t == v);
3281 if( s < 0 || t < 0 )
3289assert(ninccols < ncols);
3290inccols[ninccols] = c;
3306 if( sourcecount[u] + targetcount[u] == 1 )
3308assert(nadjnodes <
nnodes);
3309adjnodes[nadjnodes] = u;
3317 for( l = 0; l < nadjnodes; l++ )
3322assert(0 <= u && u <
nnodes);
3323assert(sourcecount[u] > 0 || targetcount[u] > 0);
3325assert(ninccols >= 0);
3328 if( sourcecount[u] >= arcsthreshold )
3338 for( m = 0; m < ninccols; m++ )
3345assert(0 <= c && c < ncols);
3347assert(cols !=
NULL);
3349assert(s == v || t == v);
3354colarcid[c] = arcid;
3357inccols[m] = inccols[ninccols-1];
3365 if( targetcount[u] >= arcsthreshold )
3375 for( m = 0; m < ninccols; m++ )
3382assert(0 <= c && c < ncols);
3384assert(cols !=
NULL);
3386assert(s == v || t == v);
3391colarcid[c] = arcid;
3394inccols[m] = inccols[ninccols-1];
3403 for( l = 0; l < nadjnodes; l++ )
3411 for( l = 0; l < ninccols; l++ )
3413assert(colarcid[inccols[l]] == -1);
3414colarcid[inccols[l]] = -2;
3418assert(n == nflowcands);
3423 for( n = 0; n < ncols; n++ )
3424assert(colarcid[n] >= -1);
3435 MCFdebugMessage(
"network after finding uncapacitated arcs has %d nodes, %d arcs, and %d commodities\n",
3436mcfdata->nnodes, mcfdata->narcs, mcfdata->ncommodities);
3448 int* flowcands = mcfdata->flowcands;
3449 intnflowcands = mcfdata->nflowcands;
3450 int* colcommodity = mcfdata->colcommodity;
3451 int* rowcommodity = mcfdata->rowcommodity;
3452 int* colarcid = mcfdata->colarcid;
3453 int* rowarcid = mcfdata->rowarcid;
3454 int* rownodeid = mcfdata->rownodeid;
3455 intncommodities = mcfdata->ncommodities;
3456 int* commoditysigns = mcfdata->commoditysigns;
3457 int narcs= mcfdata->narcs;
3458 int nnodes= mcfdata->nnodes;
3459 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3471 intnnodesthreshold;
3472 intnewncommodities;
3485permsize = ncommodities;
3497assert(flowcands !=
NULL|| nflowcands == 0);
3500 for( i = 0; i < nflowcands; i++ )
3504assert(flowcands !=
NULL);
3506assert(0 <=
r&&
r< nrows);
3507assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3508 if( rowcommodity[
r] >= 0 )
3510assert(rowcommodity[
r] < ncommodities);
3511nnodespercom[rowcommodity[
r]]++;
3515assert(capacityrows !=
NULL||
narcs== 0);
3525assert(capacityrows !=
NULL);
3527assert(0 <=
r&&
r< nrows);
3528assert(rowarcid[
r] ==
a);
3534 for( j = 0; j < rowlen; j++ )
3539assert(0 <= c && c < ncols);
3540 if( colcommodity[c] >= 0 && colarcid[c] ==
a)
3542assert(colcommodity[c] < ncommodities);
3543arcisincom[colcommodity[c]] =
TRUE;
3548 for( k = 0; k < ncommodities; k++ )
3550 if( arcisincom[k] )
3557 for( k = 0; k < ncommodities; k++ )
3558maxnnodes =
MAX(maxnnodes, nnodespercom[k]);
3565nnodesthreshold =
MAX(nnodesthreshold,
MINNODES);
3569newncommodities = 0;
3570 for( k = 0; k < ncommodities; k++ )
3572 SCIPdebugMsg(
scip,
" -> commodity %d: %d nodes, %d arcs\n", k, nnodespercom[k], narcspercom[k]);
3575 if( nnodespercom[k] >= nnodesthreshold && narcspercom[k] >= 1 )
3577assert(newncommodities <= k);
3578perm[k] = newncommodities;
3579commoditysigns[newncommodities] = commoditysigns[k];
3586 if( newncommodities < ncommodities )
3595 SCIPdebugMsg(
scip,
" -> discarding %d of %d commodities\n", ncommodities - newncommodities, ncommodities);
3603 for( c = 0; c < ncols; c++ )
3605 if( colcommodity[c] >= 0 )
3607assert(-1 <= colarcid[c] && colarcid[c] <
narcs);
3608assert(colcommodity[c] < mcfdata->ncommodities);
3609colcommodity[c] = perm[colcommodity[c]];
3610assert(colcommodity[c] < newncommodities);
3611 if( colcommodity[c] == -1 )
3616 else if( colarcid[c] >= 0 )
3617arcisused[colarcid[c]] =
TRUE;
3620 for( i = 0; i < nflowcands; i++ )
3624assert(flowcands !=
NULL);
3626assert(0 <=
r&&
r< nrows);
3627assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3628 if( rowcommodity[
r] >= 0 )
3630assert(0 <= rownodeid[
r] && rownodeid[
r] <
nnodes);
3631assert(rowcommodity[
r] < mcfdata->ncommodities);
3632rowcommodity[
r] = perm[rowcommodity[
r]];
3633assert(rowcommodity[
r] < newncommodities);
3634 if( rowcommodity[
r] == -1 )
3637rownodeid[
r] = -1;
3640nodeisused[rownodeid[
r]] =
TRUE;
3644mcfdata->ncommodities = newncommodities;
3645ncommodities = newncommodities;
3653assert(capacityrows !=
NULL);
3655 if( arcisused[
a] )
3657assert(newnarcs <=
a);
3658perm[
a] = newnarcs;
3659capacityrows[newnarcs] = capacityrows[
a];
3668assert(0 <=
r&&
r< nrows);
3669assert(rowarcid[
r] ==
a);
3670rowarcid[
r] = perm[
a];
3674 if( newnarcs <
narcs)
3678 for( c = 0; c < ncols; c++ )
3680 if( colarcid[c] >= 0 )
3682colarcid[c] = perm[colarcid[c]];
3683assert(colarcid[c] >= 0);
3686mcfdata->narcs = newnarcs;
3693assert(capacityrows !=
NULL);
3695assert(0 <=
r&&
r< nrows);
3696assert(rowarcid[
r] ==
a);
3702 for( v = 0; v <
nnodes; v++ )
3704 if( nodeisused[v] )
3706assert(newnnodes <= v);
3707perm[v] = newnnodes;
3715 if( newnnodes <
nnodes)
3719 for( i = 0; i < nflowcands; i++ )
3723assert(flowcands !=
NULL);
3725assert(0 <=
r&&
r< nrows);
3726assert((rownodeid[
r] >= 0) == (rowcommodity[
r] >= 0));
3727 if( rowcommodity[
r] >= 0 )
3729assert(rowcommodity[
r] < ncommodities);
3730rownodeid[
r] = perm[rownodeid[
r]];
3731assert(rownodeid[
r] >= 0);
3734mcfdata->nnodes = newnnodes;
3746mcfdata->nemptycommodities = 0;
3768 int* colarcid = mcfdata->colarcid;
3769 int* colcommodity = mcfdata->colcommodity;
3770 int narcs= mcfdata->narcs;
3771 int nnodes= mcfdata->nnodes;
3772 intncommodities = mcfdata->ncommodities;
3773 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3775 SCIP_Realmaxinconsistencyratio = sepadata->maxinconsistencyratio;
3776 SCIP_Realmaxarcinconsistencyratio = sepadata->maxarcinconsistencyratio;
3788 int*flowvarspercom;
3801assert(effortlevel !=
NULL);
3815arcsources = mcfdata->arcsources;
3816arctargets = mcfdata->arctargets;
3817colsources = mcfdata->colsources;
3818coltargets = mcfdata->coltargets;
3819firstoutarcs = mcfdata->firstoutarcs;
3820firstinarcs = mcfdata->firstinarcs;
3821nextoutarcs = mcfdata->nextoutarcs;
3822nextinarcs = mcfdata->nextinarcs;
3824mcfdata->arcarraysize =
narcs;
3827 for( c = 0; c < ncols; c++ )
3834 for( v = 0; v <
nnodes; v++ )
3836firstoutarcs[v] = -1;
3837firstinarcs[v] = -1;
3841nextoutarcs[
a] = -1;
3842nextinarcs[
a] = -1;
3855mcfdata->ninconsistencies = 0.0;
3856maxninconsistencies = maxinconsistencyratio * (
SCIP_Real)
narcs;
3881assert(mcfdata->rowarcid[
r] ==
a);
3884 for( i = 0; i <
nnodes; i++ )
3886assert(sourcenodecnt[i] == 0);
3887assert(targetnodecnt[i] == 0);
3898 for( i = 0; i < rowlen; i++ )
3902 if( colarcid[c] >= 0 )
3904 intk = colcommodity[c];
3905assert (0 <= k && k < ncommodities);
3906flowvarspercom[k]++;
3907 if( !comtouched[k] )
3910comtouched[k] =
TRUE;
3916 if( ntouchedcoms == 0 )
3918capacityrows[
a] =
NULL;
3919arcsources[
a] = -1;
3920arctargets[
a] = -1;
3926totalsourcecnt = 0.0;
3927totaltargetcnt = 0.0;
3929 for( i = 0; i < rowlen; i++ )
3933 if( colarcid[c] >= 0 )
3935 intk = colcommodity[c];
3940assert (0 <= k && k < ncommodities);
3941assert (comtouched[k]);
3942assert (flowvarspercom[k] >= 1);
3948weight = 1.0/flowvarspercom[k];
3951 if( sourcenodecnt[sourcev] == 0.0 && targetnodecnt[sourcev] == 0.0 )
3953touchednodes[ntouchednodes] = sourcev;
3956sourcenodecnt[sourcev] += weight;
3957totalsourcecnt += weight;
3961 if( sourcenodecnt[targetv] == 0.0 && targetnodecnt[targetv] == 0.0 )
3963touchednodes[ntouchednodes] = targetv;
3966targetnodecnt[targetv] += weight;
3967totaltargetcnt += weight;
3969 if( sourcev >= 0 || targetv >= 0 )
3970totalnodecnt += weight;
3977bestsourcecnt = 0.0;
3978besttargetcnt = 0.0;
3979 for( i = 0; i < ntouchednodes; i++ )
3981v = touchednodes[i];
3982assert(0 <= v && v <
nnodes);
3987 if( sourcenodecnt[v] >= targetnodecnt[v] )
3989 if( sourcenodecnt[v] > bestsourcecnt )
3992bestsourcecnt = sourcenodecnt[v];
3997 if( targetnodecnt[v] > besttargetcnt )
4000besttargetcnt = targetnodecnt[v];
4006 SCIP_Realnodecnt = sourcenodecnt[v] + targetnodecnt[v];
4010 if( nodecnt > bestsourcecnt )
4012besttargetv = bestsourcev;
4013besttargetcnt = bestsourcecnt;
4015bestsourcecnt = nodecnt;
4017 else if( nodecnt > besttargetcnt )
4020besttargetcnt = nodecnt;
4025sourcenodecnt[v] = 0;
4026targetnodecnt[v] = 0;
4032totalsourcecnt = totalnodecnt;
4033totaltargetcnt = totalnodecnt;
4035assert(
SCIPisGE(
scip,totalsourcecnt,bestsourcecnt));
4036assert(
SCIPisGE(
scip,totaltargetcnt,besttargetcnt));
4037nsourceinconsistencies = (totalsourcecnt - bestsourcecnt)/ntouchedcoms;
4038ntargetinconsistencies = (totaltargetcnt - besttargetcnt)/ntouchedcoms;
4041 if( nsourceinconsistencies > maxarcinconsistencyratio )
4047 if( ntargetinconsistencies > maxarcinconsistencyratio )
4054assert(bestsourcev == -1 || bestsourcev != besttargetv);
4055arcsources[
a] = bestsourcev;
4056arctargets[
a] = besttargetv;
4057 SCIPdebugMsg(
scip,
"arc %d: %d -> %d (len=%d, sourcecnt=%g/%g, targetcnt=%g/%g, %g/%g inconsistencies)\n",
4058 a, bestsourcev, besttargetv, rowlen,
4059bestsourcecnt, totalsourcecnt, besttargetcnt, totaltargetcnt,
4060nsourceinconsistencies, ntargetinconsistencies);
4063 if( bestsourcev != -1 )
4065nextoutarcs[
a] = firstoutarcs[bestsourcev];
4066firstoutarcs[bestsourcev] =
a;
4068 if( besttargetv != -1 )
4070nextinarcs[
a] = firstinarcs[besttargetv];
4071firstinarcs[besttargetv] =
a;
4075mcfdata->ninconsistencies += 0.5*(nsourceinconsistencies + ntargetinconsistencies);
4077 if( mcfdata->ninconsistencies > maxninconsistencies )
4079 MCFdebugMessage(
" -> reached maximal number of inconsistencies: %g > %g\n",
4080mcfdata->ninconsistencies, maxninconsistencies);
4086 if( mcfdata->ninconsistencies <= maxninconsistencies &&
narcs> 0 && ncommodities > 0 )
4091 MCFdebugMessage(
"extracted network has %g inconsistencies (ratio %g) -> separating with effort %d\n",
4092mcfdata->ninconsistencies, mcfdata->ninconsistencies/(
SCIP_Real)
narcs, *effortlevel);
4121 int* arcsources = mcfdata->arcsources;
4122 int* arctargets = mcfdata->arctargets;
4123 int* firstoutarcs = mcfdata->firstoutarcs;
4124 int* firstinarcs = mcfdata->firstinarcs;
4125 int* nextoutarcs = mcfdata->nextoutarcs;
4126 int* nextinarcs = mcfdata->nextinarcs;
4127 int nnodes= mcfdata->nnodes;
4132assert(nodevisited !=
NULL);
4133assert(0 <= startv && startv <
nnodes);
4134assert(nodevisited[startv] ==
UNKNOWN);
4135assert(compnodes !=
NULL);
4136assert(ncompnodes !=
NULL);
4137assert(comparcs !=
NULL);
4138assert(ncomparcs !=
NULL);
4147stacknodes[0] = startv;
4149nodevisited[startv] =
ONSTACK;
4152 while( nstacknodes > 0 )
4157assert(firstoutarcs !=
NULL);
4158assert(firstinarcs !=
NULL);
4159assert(nextoutarcs !=
NULL);
4160assert(nextinarcs !=
NULL);
4163v = stacknodes[nstacknodes-1];
4165assert(0 <= v && v <
nnodes);
4166assert(nodevisited[v] ==
ONSTACK);
4170assert(*ncompnodes <
nnodes);
4171compnodes[*ncompnodes] = v;
4175 for(
a= firstoutarcs[v];
a!= -1;
a= nextoutarcs[
a] )
4179assert(0 <=
a&& a < mcfdata->
narcs);
4180assert(arctargets !=
NULL);
4182targetv = arctargets[
a];
4185 if( targetv != -1 && nodevisited[targetv] ==
VISITED)
4189assert(*ncomparcs < mcfdata->
narcs);
4190comparcs[*ncomparcs] =
a;
4194 if( targetv != -1 && nodevisited[targetv] ==
UNKNOWN)
4196assert(nstacknodes <
nnodes);
4197stacknodes[nstacknodes] = targetv;
4199nodevisited[targetv] =
ONSTACK;
4204 for(
a= firstinarcs[v];
a!= -1;
a= nextinarcs[
a] )
4208assert(0 <=
a&& a < mcfdata->
narcs);
4209assert(arcsources !=
NULL);
4211sourcev = arcsources[
a];
4214 if( sourcev != -1 && nodevisited[sourcev] ==
VISITED)
4218assert(*ncomparcs < mcfdata->
narcs);
4219comparcs[*ncomparcs] =
a;
4223 if( sourcev != -1 && nodevisited[sourcev] ==
UNKNOWN)
4225assert(nstacknodes <
nnodes);
4226stacknodes[nstacknodes] = sourcev;
4228nodevisited[sourcev] =
ONSTACK;
4259 intmcfnetworkssize;
4261assert(mcfnetworks !=
NULL);
4262assert(nmcfnetworks !=
NULL);
4263assert(effortlevel !=
NULL);
4267*mcfnetworks =
NULL;
4269mcfnetworkssize = 0;
4300mcfdata.flowrowsigns =
NULL;
4301mcfdata.flowrowscalars =
NULL;
4302mcfdata.flowrowscores =
NULL;
4303mcfdata.capacityrowsigns =
NULL;
4304mcfdata.capacityrowscores =
NULL;
4305mcfdata.flowcands =
NULL;
4306mcfdata.nflowcands = 0;
4307mcfdata.capacitycands =
NULL;
4308mcfdata.ncapacitycands = 0;
4309mcfdata.plusflow =
NULL;
4310mcfdata.minusflow =
NULL;
4311mcfdata.ncommodities = 0;
4312mcfdata.nemptycommodities = 0;
4313mcfdata.commoditysigns =
NULL;
4314mcfdata.commoditysignssize = 0;
4315mcfdata.colcommodity =
NULL;
4316mcfdata.rowcommodity =
NULL;
4317mcfdata.colarcid =
NULL;
4318mcfdata.rowarcid =
NULL;
4319mcfdata.rownodeid =
NULL;
4320mcfdata.arcarraysize = 0;
4321mcfdata.arcsources =
NULL;
4322mcfdata.arctargets =
NULL;
4323mcfdata.colsources =
NULL;
4324mcfdata.coltargets =
NULL;
4325mcfdata.firstoutarcs =
NULL;
4326mcfdata.firstinarcs =
NULL;
4327mcfdata.nextoutarcs =
NULL;
4328mcfdata.nextinarcs =
NULL;
4329mcfdata.newcols =
NULL;
4330mcfdata.nnewcols = 0;
4333mcfdata.ninconsistencies = 0.0;
4334mcfdata.capacityrows =
NULL;
4335mcfdata.capacityrowssize = 0;
4336mcfdata.colisincident =
NULL;
4337mcfdata.zeroarcarray =
NULL;
4338mcfdata.modeltype = modeltype;
4344assert(mcfdata.flowrowsigns !=
NULL);
4345assert(mcfdata.flowrowscalars !=
NULL);
4346assert(mcfdata.flowrowscores !=
NULL);
4347assert(mcfdata.flowcands !=
NULL);
4349 if( mcfdata.nflowcands == 0 )
4357assert(mcfdata.plusflow !=
NULL);
4358assert(mcfdata.minusflow !=
NULL);
4359assert(mcfdata.colcommodity !=
NULL);
4360assert(mcfdata.rowcommodity !=
NULL);
4361assert(mcfdata.newcols !=
NULL);
4367printCommodities(
scip, &mcfdata);
4374assert(mcfdata.capacityrowsigns !=
NULL);
4375assert(mcfdata.capacityrowscores !=
NULL);
4376assert(mcfdata.capacitycands !=
NULL);
4378 if( mcfdata.ncapacitycands == 0 )
4386assert(mcfdata.colarcid !=
NULL);
4387assert(mcfdata.rowarcid !=
NULL);
4391assert(mcfdata.rownodeid !=
NULL);
4392assert(mcfdata.colisincident !=
NULL);
4393assert(mcfdata.zeroarcarray !=
NULL);
4404assert(mcfdata.arcsources !=
NULL);
4405assert(mcfdata.arctargets !=
NULL);
4406assert(mcfdata.colsources !=
NULL);
4407assert(mcfdata.coltargets !=
NULL);
4408assert(mcfdata.firstoutarcs !=
NULL);
4409assert(mcfdata.firstinarcs !=
NULL);
4410assert(mcfdata.nextoutarcs !=
NULL);
4411assert(mcfdata.nextinarcs !=
NULL);
4427printCommodities(
scip, &mcfdata);
4440 for( v = 0; v < mcfdata.nnodes; v++ )
4444 for( v = 0; v < mcfdata.nnodes; v++ )
4451 if( nodevisited[v] ==
VISITED)
4456assert(ncompnodes >= 1);
4457assert(compnodes[0] == v);
4458assert(nodevisited[v] ==
VISITED);
4461 if( ncompnodes >= minnodes && ncomparcs >=
MINARCS)
4468assert(*nmcfnetworks <= mcfnetworkssize);
4469 if( *nmcfnetworks == mcfnetworkssize )
4471mcfnetworkssize =
MAX(2*mcfnetworkssize, *nmcfnetworks+1);
4474assert(*nmcfnetworks < mcfnetworkssize);
4483assert(*mcfnetworks !=
NULL);
4484 for( i = *nmcfnetworks; i > 0 && mcfnetwork->
nnodes> (*mcfnetworks)[i-1]->nnodes; i-- )
4485(*mcfnetworks)[i] = (*mcfnetworks)[i-1];
4486(*mcfnetworks)[i] = mcfnetwork;
4491minnodes =
MAX(minnodes, (*mcfnetworks)[*nmcfnetworks-1]->
nnodes);
4496 SCIPdebugMsg(
scip,
" -> discarded network with %d nodes and %d arcs due to maxnetworks (minnodes=%d)\n",
4497(*mcfnetworks)[*nmcfnetworks-1]->
nnodes, (*mcfnetworks)[*nmcfnetworks-1]->
narcs, minnodes);
4505 SCIPdebugMsg(
scip,
" -> discarded component with %d nodes and %d arcs\n", ncompnodes, ncomparcs);
4547#ifdef COUNTNETWORKVARIABLETYPES 4569 intnintflowvars = 0;
4570 intnbinflowvars = 0;
4571 intncontflowvars = 0;
4573 intnintcapvars = 0;
4574 intnbincapvars = 0;
4575 intncontcapvars = 0;
4583 for(c=0; c < ncols; c++)
4584colvisited[c]=
FALSE;
4588 for(m=0; m < nmcfnetworks; m++)
4600 for(c=0; c < ncols; c++)
4604 if(colcommodity[c] >= 0 && ! colvisited[c])
4609colvisited[c] =
TRUE;
4635row = arccapacityrows[
a];
4647 for( i = 0; i < rowlen; i++ )
4652 if(colcommodity[c] == -1 && ! colvisited[c] )
4655colvisited[c] =
TRUE;
4680 for( k = 0; k < ncommodities; k++ )
4682 for( v = 0; v <
nnodes; v++ )
4685row = nodeflowrows[v][k];
4695 MCFdebugMessage(
" nof flowvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4696nflowvars, ncontflowvars, nintflowvars, nbinflowvars);
4697 MCFdebugMessage(
" nof capvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4698ncapvars, ncontcapvars, nintcapvars, nbincapvars);
4717 int* representatives,
4724 for( v = 0; v < nelems; v++ )
4725representatives[v] = v;
4731 int* representatives,
4735assert(representatives !=
NULL);
4737 while( v != representatives[v] )
4739representatives[v] = representatives[representatives[v]];
4740v = representatives[v];
4749 int* representatives,
4754assert(rep1 != rep2);
4755assert(representatives[rep1] == rep1);
4756assert(representatives[rep2] == rep2);
4762representatives[rep2] = rep1;
4764representatives[rep1] = rep2;
4780 if( nodepair1->weight > nodepair2->weight )
4782 else if( nodepair1->weight < nodepair2->weight )
4817assert(mcfnetwork !=
NULL);
4823assert(nodepair1 !=
NULL);
4824assert(nodepair2 !=
NULL);
4826source1 = nodepair1->node1;
4827source2 = nodepair2->node1;
4828target1 = nodepair1->node2;
4829target2 = nodepair2->node2;
4831assert(source1 >=0 && source1 < mcfnetwork->
nnodes);
4832assert(source2 >=0 && source2 < mcfnetwork->
nnodes);
4833assert(target1 >=0 && target1 < mcfnetwork->
nnodes);
4834assert(target2 >=0 && target2 < mcfnetwork->
nnodes);
4835assert(source1 <= target1);
4836assert(source2 <= target2);
4838 return(source1 == source2 && target1 == target2);
4852 unsigned inthashval;
4856assert(mcfnetwork !=
NULL);
4860assert( nodepair !=
NULL);
4862source = nodepair->node1;
4863target = nodepair->node2;
4865assert(source >=0 && source < mcfnetwork->
nnodes);
4866assert(target >=0 && target < mcfnetwork->
nnodes);
4867assert(source <= target);
4869hashval = (unsigned)((source << 16) + target);
4892#ifdef BETTERWEIGHTFORDEMANDNODES 4912assert(mcfnetwork !=
NULL);
4914#ifdef BETTERWEIGHTFORDEMANDNODES 4924assert(nodepairqueue !=
NULL);
4931hashtablesize = mcfnetwork->
narcs;
4934hashGetKeyNodepairs, hashKeyEqNodepairs, hashKeyValNodepairs, (
void*) mcfnetwork) );
4941 for(
a= 0;
a< mcfnetwork->
narcs;
a++ )
4963assert(nodepair.node1 < mcfnetwork->
nnodes);
4964assert(nodepair.node2 < mcfnetwork->
nnodes);
4965 if( nodepair.node1 == -1 || nodepair.node2 == -1 )
4969 if( capacityrow !=
NULL)
4985slack =
MAX(slack, 0.0);
4989assert(scale > 0.0);
4999 for( i = 0; i < rowlen; i++ )
5006 if(colcommodity[c] >= 0)
5018 SCIPdebugMsg(
scip,
"cap arc -- slack:%g -- dual:%g -- flow:%g -- cap:%g \n", scale * slack, dualsol/scale, totalflow * scale, totalcap * scale);
5020 SCIPdebugMsg(
scip,
"cap arc -- slack:%g -- dual:%g1\n", scale * slack, dualsol/scale);
5024nodepair.weight = scale * slack -
ABS(dualsol)/scale;
5025#ifdef USEFLOWFORTIEBREAKING 5028nodepair.weight += totalflow * scale;
5029nodepair.weight =
MIN( nodepair.weight, -0.0001);
5032#ifdef USECAPACITYFORTIEBREAKING 5035nodepair.weight += totalcap * scale;
5036nodepair.weight =
MIN( nodepair.weight, -0.0001);
5051 if( nodepairptr !=
NULL)
5054 SCIPdebugMsg(
scip,
"nodepair known [%d,%d] -- old weight:%g -- new weight:%g\n", nodepair.node1,nodepair.node2,nodepairptr->weight,
5055 MIN(nodepair.weight, nodepairptr->weight));
5056nodepairptr->weight =
MIN(nodepair.weight, nodepairptr->weight);
5061nodepairs = (*nodepairqueue)->nodepairs;
5063assert(nnodepairs < mcfnetwork->
narcs);
5064nodepairs[nnodepairs] = nodepair;
5067 SCIPdebugMsg(
scip,
"new nodepair [%d,%d]-- weight:%g\n", nodepair.node1, nodepair.node2, nodepair.weight);
5078#ifdef BETTERWEIGHTFORDEMANDNODES 5086nodepairs = (*nodepairqueue)->nodepairs;
5087 for( n = 0; n < nnodepairs; n++ )
5091maxweight =
MAX(maxweight, nodepairs[n].weight);
5093minweight =
MIN(minweight, nodepairs[n].weight);
5103 for( n = 0; n < nnodepairs; n++ )
5105 intnode1 = nodepairs[n].node1;
5106 intnode2 = nodepairs[n].node2;
5108#ifdef BETTERWEIGHTFORDEMANDNODES 5115 SCIPdebugMsg(
scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5121 for( k = 0; k < ncommodities; k++ )
5123 if( nodeflowrows[node1][k] ==
NULL)
5126 if( nodeflowscales[node1][k] > 0.0 )
5141 for( k = 0; k < ncommodities; k++ )
5143 if( nodeflowrows[node2][k] ==
NULL)
5146 if( nodeflowscales[node2][k] > 0.0 )
5168 if( !hasdemand1 || !hasdemand2 )
5169nodepairs[n].weight += maxweight;
5175 if( hasdemand1 && hasdemand2)
5176nodepairs[n].weight += minweight;
5179 SCIPdebugMsg(
scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5196assert(nodepairqueue !=
NULL);
5197assert(*nodepairqueue !=
NULL);
5211assert(nodepairqueue !=
NULL);
5223assert(nodepairqueue !=
NULL);
5271assert(mcfnetwork !=
NULL);
5272assert(nodepartition !=
NULL);
5273assert(mcfnetwork->
nnodes>= 1);
5281(*nodepartition)->nclusters = 0;
5290nclustersleft = mcfnetwork->
nnodes;
5301assert(nodepair !=
NULL);
5302node1 = nodepair->node1;
5303node2 = nodepair->node2;
5305assert(node1 >= 0 && node1 < mcfnetwork->
nnodes);
5306assert(node2 >= 0 && node2 < mcfnetwork->
nnodes);
5311assert(0 <= node1rep && node1rep < mcfnetwork->
nnodes);
5312assert(0 <= node2rep && node2rep < mcfnetwork->
nnodes);
5315 if( node1rep == node2rep )
5319 SCIPdebugMsg(
scip,
"shrinking nodepair (%d,%d) with weight %g: join representatives %d and %d\n",
5320node1, node2, nodepair->weight, node1rep, node2rep);
5326assert((*nodepartition)->representatives[0] == 0);
5331 if( nclustersleft > nclusters )
5333 for( v = 1; v < mcfnetwork->
nnodes&& nclustersleft > nclusters; v++ )
5345assert(nclustersleft <= nclusters);
5350 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5360c = (*nodepartition)->nclusters;
5361(*nodepartition)->nclusters++;
5364c = (*nodepartition)->nodeclusters[rep];
5365assert(0 <= c && c < nclusters);
5368(*nodepartition)->nodeclusters[v] = c;
5374 for( c = 0; c < (*nodepartition)->nclusters; c++ )
5376(*nodepartition)->clusterbegin[c] = pos;
5377pos += clustersize[c];
5379assert(pos == mcfnetwork->
nnodes);
5380(*nodepartition)->clusterbegin[(*nodepartition)->nclusters] = mcfnetwork->
nnodes;
5384 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5386c = (*nodepartition)->nodeclusters[v];
5387assert(0 <= c && c < (*nodepartition)->nclusters);
5388pos = (*nodepartition)->clusterbegin[c] + clustersize[c];
5389assert(pos < (*nodepartition)->clusterbegin[c+1]);
5390(*nodepartition)->clusternodes[pos] = v;
5410assert(nodepartition !=
NULL);
5411assert(*nodepartition !=
NULL);
5424 unsigned intpartition,
5435 if( nodepartition ==
NULL)
5436 return((v == (
int)partition) == !inverted);
5440 unsigned intclusterbit;
5442cluster = nodepartition->nodeclusters[v];
5443assert(0 <= cluster && cluster < nodepartition->nclusters);
5444clusterbit = (1 << cluster);
5446 return(((partition & clusterbit) != 0) == !inverted);
5456 unsigned intpartition
5459 const int* nodeclusters = nodepartition->nodeclusters;
5460 const int* arcsources = mcfnetwork->
arcsources;
5461 const int* arctargets = mcfnetwork->
arctargets;
5469assert(nodepartition->nodeclusters !=
NULL);
5470nclusters = nodepartition->nclusters;
5477ncomponents = nclusters;
5478assert(ncomponents >= 2);
5483 ints = arcsources[
a];
5484 intt = arctargets[
a];
5487 if( s == -1 || t == -1 )
5498assert(0 <= s && s < mcfnetwork->
nnodes);
5499assert(0 <= t && t < mcfnetwork->
nnodes);
5502cs = nodeclusters[s];
5503ct = nodeclusters[t];
5504assert(0 <= cs && cs < nclusters);
5505assert(0 <= ct && ct < nclusters);
5514 if( repcs == repct )
5521 if( ncomponents <= 2 )
5531assert(ncomponents >= 2);
5533 return(ncomponents == 2);
5538voidnodepartitionPrint(
5544 for( c = 0; c < nodepartition->nclusters; c++ )
5549 for( i = nodepartition->clusterbegin[c]; i < nodepartition->clusterbegin[c+1]; i++ )
5564 unsigned intpartition
5573 if( nodepartition ==
NULL)
5578file = fopen(filename,
"w");
5586fprintf(file,
"graph\n");
5587fprintf(file,
"[\n");
5588fprintf(file,
" hierarchic 1\n");
5589fprintf(file,
" label \"\"\n");
5590fprintf(file,
" directed 1\n");
5593 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5602inpartition =
nodeInPartition(nodepartition, partition, inverted, v);
5604fprintf(file,
" node\n");
5605fprintf(file,
" [\n");
5606fprintf(file,
" id %d\n", v);
5607fprintf(file,
" label \"%s\"\n", label);
5608fprintf(file,
" graphics\n");
5609fprintf(file,
" [\n");
5610fprintf(file,
" w 30.0\n");
5611fprintf(file,
" h 30.0\n");
5612fprintf(file,
" type \"ellipse\"\n");
5614fprintf(file,
" fill \"#FF0000\"\n");
5616fprintf(file,
" fill \"#00FF00\"\n");
5617fprintf(file,
" outline \"#000000\"\n");
5618fprintf(file,
" ]\n");
5619fprintf(file,
" LabelGraphics\n");
5620fprintf(file,
" [\n");
5621fprintf(file,
" text \"%s\"\n", label);
5622fprintf(file,
" fontSize 13\n");
5623fprintf(file,
" fontName \"Dialog\"\n");
5624fprintf(file,
" anchor \"c\"\n");
5625fprintf(file,
" ]\n");
5627fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+1);
5629fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+2);
5630fprintf(file,
" ]\n");
5634fprintf(file,
" node\n");
5635fprintf(file,
" [\n");
5636fprintf(file,
" id %d\n", mcfnetwork->
nnodes);
5637fprintf(file,
" label \"?\"\n");
5638fprintf(file,
" graphics\n");
5639fprintf(file,
" [\n");
5640fprintf(file,
" w 30.0\n");
5641fprintf(file,
" h 30.0\n");
5642fprintf(file,
" type \"ellipse\"\n");
5643fprintf(file,
" fill \"#FFFFFF\"\n");
5644fprintf(file,
" outline \"#000000\"\n");
5645fprintf(file,
" ]\n");
5646fprintf(file,
" LabelGraphics\n");
5647fprintf(file,
" [\n");
5648fprintf(file,
" text \"?\"\n");
5649fprintf(file,
" fontSize 13\n");
5650fprintf(file,
" fontName \"Dialog\"\n");
5651fprintf(file,
" anchor \"c\"\n");
5652fprintf(file,
" ]\n");
5653fprintf(file,
" ]\n");
5656fprintf(file,
" node\n");
5657fprintf(file,
" [\n");
5658fprintf(file,
" id %d\n", mcfnetwork->
nnodes+1);
5659fprintf(file,
" label \"Partition S\"\n");
5660fprintf(file,
" graphics\n");
5661fprintf(file,
" [\n");
5662fprintf(file,
" type \"roundrectangle\"\n");
5663fprintf(file,
" fill \"#CAECFF84\"\n");
5664fprintf(file,
" outline \"#666699\"\n");
5665fprintf(file,
" outlineStyle \"dotted\"\n");
5666fprintf(file,
" topBorderInset 0\n");
5667fprintf(file,
" bottomBorderInset 0\n");
5668fprintf(file,
" leftBorderInset 0\n");
5669fprintf(file,
" rightBorderInset 0\n");
5670fprintf(file,
" ]\n");
5671fprintf(file,
" LabelGraphics\n");
5672fprintf(file,
" [\n");
5673fprintf(file,
" text \"Partition S\"\n");
5674fprintf(file,
" fill \"#99CCFF\"\n");
5675fprintf(file,
" fontSize 15\n");
5676fprintf(file,
" fontName \"Dialog\"\n");
5677fprintf(file,
" alignment \"right\"\n");
5678fprintf(file,
" autoSizePolicy \"node_width\"\n");
5679fprintf(file,
" anchor \"t\"\n");
5680fprintf(file,
" borderDistance 0.0\n");
5681fprintf(file,
" ]\n");
5682fprintf(file,
" isGroup 1\n");
5683fprintf(file,
" ]\n");
5686fprintf(file,
" node\n");
5687fprintf(file,
" [\n");
5688fprintf(file,
" id %d\n", mcfnetwork->
nnodes+2);
5689fprintf(file,
" label \"Partition T\"\n");
5690fprintf(file,
" graphics\n");
5691fprintf(file,
" [\n");
5692fprintf(file,
" type \"roundrectangle\"\n");
5693fprintf(file,
" fill \"#CAECFF84\"\n");
5694fprintf(file,
" outline \"#666699\"\n");
5695fprintf(file,
" outlineStyle \"dotted\"\n");
5696fprintf(file,
" topBorderInset 0\n");
5697fprintf(file,
" bottomBorderInset 0\n");
5698fprintf(file,
" leftBorderInset 0\n");
5699fprintf(file,
" rightBorderInset 0\n");
5700fprintf(file,
" ]\n");
5701fprintf(file,
" LabelGraphics\n");
5702fprintf(file,
" [\n");
5703fprintf(file,
" text \"Partition T\"\n");
5704fprintf(file,
" fill \"#99CCFF\"\n");
5705fprintf(file,
" fontSize 15\n");
5706fprintf(file,
" fontName \"Dialog\"\n");
5707fprintf(file,
" alignment \"right\"\n");
5708fprintf(file,
" autoSizePolicy \"node_width\"\n");
5709fprintf(file,
" anchor \"t\"\n");
5710fprintf(file,
" borderDistance 0.0\n");
5711fprintf(file,
" ]\n");
5712fprintf(file,
" isGroup 1\n");
5713fprintf(file,
" ]\n");
5716 for(
a= 0;
a< mcfnetwork->
narcs;
a++ )
5728hasfractional =
FALSE;
5739 for( i = 0; i < rowlen; i++ )
5746hasfractional =
TRUE;
5754fprintf(file,
" edge\n");
5755fprintf(file,
" [\n");
5758fprintf(file,
" label \"%s\"\n", label);
5759fprintf(file,
" graphics\n");
5760fprintf(file,
" [\n");
5762fprintf(file,
" fill \"#000000\"\n");
5764fprintf(file,
" fill \"#FF0000\"\n");
5765 if( hasfractional )
5766fprintf(file,
" style \"dashed\"\n");
5767fprintf(file,
" width 1\n");
5768fprintf(file,
" targetArrow \"standard\"\n");
5769fprintf(file,
" ]\n");
5770fprintf(file,
" LabelGraphics\n");
5771fprintf(file,
" [\n");
5772fprintf(file,
" text \"%s\"\n", label);
5773fprintf(file,
" ]\n");
5774fprintf(file,
" ]\n");
5778fprintf(file,
"]\n");
5814assert(sepadata !=
NULL);
5815assert(cutcoefs !=
NULL);
5816assert(ncuts !=
NULL);
5817assert(cutoff !=
NULL);
5821assert(nvars == 0 || vars !=
NULL);
5827 for( i = 0; i < cutnnz; ++i )
5829cutvars[i] = vars[cutinds[i]];
5835sepadata->dynamiccuts) );
5845 SCIPdebugMsg(
scip,
" -> found MCF cut <%s>: rhs=%f, act=%f eff=%f rank=%d\n",
5862 if( !(*cutoff) && sepadata->separateknapsack)
5865 SCIP_CALL(
SCIPseparateRelaxedKnapsack(
scip,
NULL, sepa, cutnnz, cutvars, cutcoefs, +1.0, cutrhs, sol, cutoff, ncuts) );
5916 unsigned intpartition;
5917 unsigned intallpartitions;
5918 unsigned intstartpartition;
5932maxsepacuts = sepadata->maxsepacutsroot;
5934maxsepacuts = sepadata->maxsepacuts;
5935 if( maxsepacuts < 0 )
5936maxsepacuts = INT_MAX;
5941maxtestdelta = sepadata->maxtestdelta;
5942 if( maxtestdelta <= 0 )
5943maxtestdelta = INT_MAX;
5979 if( nodepartition ==
NULL)
5983allpartitions = (
unsignedint)
nnodes;
5984 SCIPdebugMsg(
scip,
"maxtestdelta: %d, maxsepacuts: %d, nnodes: %d \n", maxtestdelta, maxsepacuts,
nnodes);
5991 intnclusters = nodepartition->nclusters;
5993assert((
unsigned int)nclusters <= 8*
sizeof(
unsigned int));
5994 SCIPdebugMsg(
scip,
"maxtestdelta: %d, maxsepacuts: %d, nclusters: %d \n", maxtestdelta, maxsepacuts, nclusters);
6001allpartitions = (1 << (nclusters-1));
6005 for( partition = startpartition; partition <= allpartitions-1 && !
SCIPisStopped(
scip) && *ncuts < maxsepacuts && !*cutoff; partition++ )
6019 if( sepadata->checkcutshoreconnectivity )
6026 SCIPdebugMsg(
scip,
"generating cluster cuts for partition 0x%x \n", partition );
6027 SCIPdebugMsg(
scip,
" -> either shore S or shore T is not connected - skip partition.\n");
6032 for( inverted =
FALSE; inverted <= useinverted && !*cutoff; inverted++ )
6034 if( nodepartition ==
NULL)
6036 SCIPdebugMsg(
scip,
"generating single-node cuts for node %u (inverted: %u)\n", partition, inverted);
6040 SCIPdebugMsg(
scip,
"generating cluster cuts for partition 0x%x (inverted: %u)\n", partition, inverted);
6044 SCIP_CALL( outputGraph(
scip, mcfnetwork, nodepartition, inverted, partition) );
6062 for( v = 0; v <
nnodes; v++ )
6072 for( k = 0; k < ncommodities; k++ )
6076 if( nodeflowrows[v][k] ==
NULL)
6079 if( nodeflowscales[v][k] > 0.0 )
6083 if( nodeflowinverted[v][k] )
6086comcutdemands[k] += rhs * nodeflowscales[v][k];
6089assert (1 <= nnodesinS && nnodesinS <=
nnodes-1);
6094 if( sepadata->separatesinglenodecuts && nodepartition !=
NULL&& (nnodesinS == 1 || nnodesinS ==
nnodes-1) )
6096 SCIPdebugMsg(
scip,
" -> shore S or T has only one node - skip partition.\n");
6103 for( k = 0; k < ncommodities; k++ )
6106 SCIPdebugMsg(
scip,
" -> commodity %d: directed cutdemand=%g\n", k, comcutdemands[k]);
6113 for( k = 0; k < ncommodities; k++ )
6116 SCIPdebugMsg(
scip,
" -> commodity %d: undirected cutdemand=%g\n", k, comcutdemands[k]);
6121 if( k == ncommodities )
6134assert(arcsources[
a] <
nnodes);
6135assert(arctargets[
a] <
nnodes);
6141 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[
a]) ||
6151 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[
a]) &&
6157 if( !
nodeInPartition(nodepartition, partition, inverted, arcsources[
a]) &&
6166 if( arccapacityrows[
a] ==
NULL)
6174assert(rowweights[
r] == 0.0);
6180 if( arcsources[
a] == -1 || arctargets[
a] == -1 )
6190assert(maxcoef > 0.0);
6195rowweights[
r] = arccapacityscales[
a];
6200 if( sepadata->separateflowcutset )
6202 if( rowweights[
r] > 0.0 )
6212 for( j = 0; j < rowlen; j++ )
6217coef = rowvals[j] * arccapacityscales[
a];
6223k = colcommodity[c];
6225comdemands[k] = coef;
6239 while( left <= right )
6241 intmid = (left+right)/2;
6243 if(
REALABS( deltas[mid] / coef - 1.0 ) < 1e-03 )
6248 else if( coef < deltas[mid] )
6257assert(right == left-1);
6258assert(ndeltas <= deltassize);
6259 if( ndeltas == deltassize )
6264 if( left < ndeltas )
6266 for( d = ndeltas; d > left; d-- )
6267deltas[d] = deltas[d-1];
6269deltas[left] = coef;
6278 for( v = 0; v <
nnodes; v++ )
6281 for( k = 0; k < ncommodities; k++ )
6287 if( comdemands[k] == 0.0 )
6290scale = comdemands[k];
6313 if( comcutdemands[k] > 0.0 )
6332 if( nodeflowrows[v][k] ==
NULL)
6341assert(rowweights[
r] == 0.0);
6347rowweights[
r] = scale * nodeflowscales[v][k];
6348 if( nodeflowinverted[v][k] )
6349rowweights[
r] *= -1.0;
6350 SCIPdebugMsg(
scip,
" -> node %d, commodity %d, r=%d, flow row <%s>: scale=%g weight=%g slack=%g dual=%g\n",
6354 if( sepadata->separateflowcutset )
6356 if( nodeflowscales[v][k] > 0.0 )
6372 if( sepadata->separateflowcutset )
6375bestdelta = deltas[ndeltas-1];
6386 for( d = ndeltas-1; d >= 0 && d >= ndeltas-maxtestdelta; d-- )
6401 SCIP_CALL(
SCIPcalcMIR(
scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
64021.0/deltas[d], aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6403assert(allowlocal || !cutislocal);
6411 if( sepadata->separateflowcutset )
6413 if( cutefficacy > bestefficacy )
6415bestdelta = deltas[d];
6416bestefficacy = cutefficacy;
6422 SCIPdebugMsg(
scip,
"success -> delta = %g -> rhs: %g, efficacy: %g\n", deltas[d], cutrhs, cutefficacy);
6423 SCIP_CALL(
addCut(
scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6430 if( arccapacityrows[
a] !=
NULL)
6436 if(
r>= 0 && rowweights[
r] != 0.0 )
6438 MCFdebugMessage(
" -> arc %d, capacity row <%s>: weight=%g slack=%g prod=%g dual=%g\n",
a,
6451 if( sepadata->separateflowcutset && oldncuts == *ncuts && !*cutoff )
6459totalviolationdelta = 0.0;
6460onedivoneminsf0 = 1.0/(1.0 - f0);
6475 if( arccapacityrows[
a] ==
NULL)
6486 if( rowweights[
r] == 0.0 )
6501rowweight = rowweights[
r]/bestdelta;
6506violationdelta = rowweight * (rowlhs - rowconstant);
6508violationdelta = rowweight * (rowrhs - rowconstant);
6510 for( j = 0; j < rowlen; j++ )
6518coef = rowvals[j] * rowweight;
6529 if( colcommodity[c] >= 0 )
6540mircoef =
SCIPfloor(
scip, coef) + (fj - f0)*onedivoneminsf0;
6547mircoef = coef * onedivoneminsf0;
6552 if( colcommodity[c] >= 0 )
6553violationdelta += mircoef * solval;
6555violationdelta -= mircoef * solval;
6560 SCIPdebugMsg(
scip,
" -> discarding capacity row <%s> of weight %g and slack %g: increases MIR violation by %g\n",
6563rowweights[
r] = 0.0;
6564totalviolationdelta += violationdelta;
6569 if( totalviolationdelta > 0.0 )
6582 SCIPdebugMsg(
scip,
"applying MIR with delta = %g to flowcut inequality (violation improvement: %g)\n", bestdelta, totalviolationdelta);
6589 SCIP_CALL(
SCIPcalcMIR(
scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs,
NULL,
NULL,
MINFRAC,
MAXFRAC,
65901.0/bestdelta, aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6592assert(allowlocal || !cutislocal);
6596 SCIPdebugMsg(
scip,
" -> delta = %g -> rhs: %g, efficacy: %g\n", bestdelta, cutrhs, cutefficacy);
6597 SCIP_CALL(
addCut(
scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6641assert(result !=
NULL);
6654 if( ncols != nvars )
6656 MCFdebugMessage(
"%d variables but %d columns -> exit\n", nvars, ncols );
6669colrowratio = (
SCIP_Real)ncols/(nrows+1e-9);
6673assert(sepadata !=
NULL);
6682 if( colrowratio < MINCOLROWRATIO || colrowratio >
MAXCOLROWRATIO)
6691 if( sepadata->nmcfnetworks == -1 )
6697 MCFdebugMessage(
"extracted %d networks\n", sepadata->nmcfnetworks);
6699 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6701 MCFdebugMessage(
" -> extracted network %d has %d nodes, %d (%d) arcs (uncapacitated), and %d commodities (modeltype: %s)\n",
6702i, sepadata->mcfnetworks[i]->nnodes, sepadata->mcfnetworks[i]->narcs, sepadata->mcfnetworks[i]->nuncapacitatedarcs,
6703sepadata->mcfnetworks[i]->ncommodities,
6705 SCIPdebug( mcfnetworkPrint(sepadata->mcfnetworks[i]) );
6708#ifdef COUNTNETWORKVARIABLETYPES 6709 SCIP_CALL( printFlowSystemInfo(
scip,sepadata->mcfnetworks,sepadata->nmcfnetworks));
6713assert(sepadata->nmcfnetworks >= 0);
6714assert(sepadata->mcfnetworks !=
NULL|| sepadata->nmcfnetworks == 0);
6715mcfnetworks = sepadata->mcfnetworks;
6716nmcfnetworks = sepadata->nmcfnetworks;
6723sepadata->lastroundsuccess =
FALSE;
6725 for( i = 0; i < nmcfnetworks && !cutoff; i++ )
6731mcfnetwork = mcfnetworks[i];
6734assert(mcfnetwork->
nnodes>= 2);
6735assert(mcfnetwork->
narcs>= 1);
6742 MCFdebugMessage(
"MCF network has %d nodes and %d arcs. arc node ratio %.2f exceed --> exit\n",
6748 if( sepadata->separatesinglenodecuts )
6759nodepartitionPrint(nodepartition);
6769 MCFdebugMessage(
"MCF network has %d nodes, %d arcs, %d commodities. Found %d MCF network cuts, cutoff = %u.\n",
6776sepadata->lastroundsuccess =
TRUE;
6778 else if( ncuts > 0 )
6781sepadata->lastroundsuccess =
TRUE;
6799assert(sepa !=
NULL);
6817assert(sepadata !=
NULL);
6818assert(sepadata->mcfnetworks ==
NULL);
6819assert(sepadata->nmcfnetworks == -1);
6837assert(sepadata !=
NULL);
6839sepadata->lastroundsuccess =
TRUE;
6856assert(sepadata !=
NULL);
6859 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6864sepadata->nmcfnetworks = -1;
6926sepadata->mcfnetworks =
NULL;
6927sepadata->nmcfnetworks = -1;
6929sepadata->lastroundsuccess =
TRUE;
6935sepaExeclpMcf, sepaExecsolMcf,
6938assert(sepa !=
NULL);
6949 "separating/mcf/nclusters",
6950 "number of clusters to generate in the shrunken network -- default separation",
6953 "separating/mcf/maxweightrange",
6954 "maximal valid range max(|weights|)/min(|weights|) of row weights",
6957 "separating/mcf/maxtestdelta",
6958 "maximal number of different deltas to try (-1: unlimited) -- default separation",
6961 "separating/mcf/trynegscaling",
6962 "should negative values also be tested in scaling?",
6965 "separating/mcf/fixintegralrhs",
6966 "should an additional variable be complemented if f0 = 0?",
6969 "separating/mcf/dynamiccuts",
6970 "should generated cuts be removed from the LP if they are no longer tight?",
6973 "separating/mcf/modeltype",
6974 "model type of network (0: auto, 1:directed, 2:undirected)",
6977 "separating/mcf/maxsepacuts",
6978 "maximal number of mcf cuts separated per separation round",
6981 "separating/mcf/maxsepacutsroot",
6982 "maximal number of mcf cuts separated per separation round in the root node -- default separation",
6985 "separating/mcf/maxinconsistencyratio",
6986 "maximum inconsistency ratio for separation at all",
6989 "separating/mcf/maxarcinconsistencyratio",
6990 "maximum inconsistency ratio of arcs not to be deleted",
6993 "separating/mcf/checkcutshoreconnectivity",
6994 "should we separate only if the cuts shores are connected?",
6997 "separating/mcf/separatesinglenodecuts",
6998 "should we separate inequalities based on single-node cuts?",
7001 "separating/mcf/separateflowcutset",
7002 "should we separate flowcutset inequalities on the network cuts?",
7005 "separating/mcf/separateknapsack",
7006 "should we separate knapsack cover inequalities on the network cuts?",
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)
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), SCIP_DECL_PQUEUEELEMCHGPOS((*elemchgpos)))
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_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 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 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)
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)
#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 SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
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)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
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_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,...)
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
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
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_DECL_SORTINDCOMP(compCands)
static SCIP_RETCODE nodepartitionCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION **nodepartition, int nclusters)
static SCIP_RETCODE mcfnetworkFree(SCIP *scip, SCIP_MCFNETWORK **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_MAXWEIGHTRANGE
#define DEFAULT_MAXARCINCONSISTENCYRATIO
struct nodepartition NODEPARTITION
#define DEFAULT_DYNAMICCUTS
static SCIP_DECL_SEPAEXECSOL(sepaExecsolMcf)
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_DECL_SEPAEXITSOL(sepaExitsolMcf)
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 SCIP_DECL_SEPAFREE(sepaFreeMcf)
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
#define DEFAULT_TRYNEGSCALING
static SCIP_RETCODE extractFlowRows(SCIP *scip, MCFDATA *mcfdata)
enum SCIP_McfModeltype SCIP_MCFMODELTYPE
struct nodepairqueue NODEPAIRQUEUE
#define DEFAULT_SEPARATESINGLENODECUTS
#define DEFAULT_MAXSEPACUTSROOT
static void getFlowrowFit(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, int k, unsigned char *rowsign, SCIP_Bool *invertcommodity)
#define MAXFLOWVARFLOWROWRATIO
#define DEFAULT_FIXINTEGRALRHS
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)
#define DEFAULT_MAXTESTDELTA
static SCIP_RETCODE cleanupNetwork(SCIP *scip, MCFDATA *mcfdata)
static SCIP_DECL_SORTPTRCOMP(compNodepairs)
static SCIP_DECL_HASHGETKEY(hashGetKeyNodepairs)
#define DEFAULT_NCLUSTERS
#define SEPA_MAXBOUNDDIST
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)
#define DEFAULT_MAXSEPACUTS
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 SCIP_DECL_HASHKEYVAL(hashKeyValNodepairs)
static void fixCommoditySigns(MCFDATA *mcfdata)
static SCIP_DECL_SEPAEXECLP(sepaExeclpMcf)
static SCIP_DECL_SEPAINITSOL(sepaInitsolMcf)
static SCIP_DECL_HASHKEYEQ(hashKeyEqNodepairs)
static SCIP_DECL_SEPACOPY(sepaCopyMcf)
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
enum SCIP_Result SCIP_RESULT
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_SepaData SCIP_SEPADATA
@ SCIP_VARTYPE_CONTINUOUS
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4