42 #include "scip/scip.h"
43 #include "scip/misc.h"
44 #include "scip/scipdefplugins.h"
47 #define HEUR_NAME "xprins"
48 #define HEUR_DESC "Extreme Point RINS"
49 #define HEUR_DISPCHAR 'Y'
50 #define HEUR_PRIORITY -1100600
52 #define HEUR_FREQOFS 0
53 #define HEUR_MAXDEPTH -1
54 #define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
55 #define HEUR_USESSUBSCIP TRUE
57 #define DEFAULT_EQUALITYRATE 0.5
58 #define DEFAULT_MAXNODES 1000LL
59 #define DEFAULT_MINIMPROVE 0.01
60 #define DEFAULT_MINNODES 200LL
61 #define DEFAULT_MINFIXINGRATE 0.4
62 #define DEFAULT_NODESOFS 200LL
63 #define DEFAULT_NODESQUOT 0.1
64 #define DEFAULT_NUSEDPTS -1
67 #define DEFAULT_RANDOMIZATION FALSE
68 #define DEFAULT_COPYCUTS TRUE
71 #define DEFAULT_RANDSEED 7
101 #ifdef SCIP_STATISTIC
102 SCIP_Longint nfixfails;
103 SCIP_Real avgfixrate;
104 SCIP_Real avgzerorate;
105 SCIP_Longint totalsols;
108 SCIP_Real subsciptime;
109 SCIP_Real bestprimalbd;
125 SCIP_HEURDATA* heurdata,
134 SCIP_VAR** mastervars;
135 SCIP_Real* mastervals;
145 SCIP_Real* blockvalue;
153 assert(scip != NULL);
154 assert(heurdata != NULL);
155 assert(selection != NULL);
156 assert(success != NULL);
158 assert(heurdata->nusedpts >= 0);
162 assert(masterprob != NULL);
168 SCIP_CALL( SCIPgetVarsData(masterprob, &mastervars, &nmastervars, NULL, NULL, NULL, NULL) );
169 assert(mastervars != NULL);
170 assert(nmastervars >= 0);
173 SCIP_CALL( SCIPallocBufferArray(scip, &mastervals, nmastervars) );
174 SCIP_CALL( SCIPgetSolVals(masterprob, NULL, nmastervars, mastervars, mastervals) );
177 nusedpts = heurdata->nusedpts;
180 SCIP_CALL( SCIPallocBufferArray(scip, &selvalue, nblocks * nusedpts) );
181 SCIP_CALL( SCIPallocBufferArray(scip, &blocknrs, nblocks) );
182 SCIP_CALL( SCIPallocBufferArray(scip, &blockvalue, nblocks) );
183 SCIP_CALL( SCIPallocBufferArray(scip, &identblock, nblocks) );
186 for( i = 0; i < nblocks; i++ )
200 for( i = 0; i < nmastervars; i++ )
204 mastervar = mastervars[i];
209 value = SCIPgetSolVal(masterprob, NULL, mastervar);
212 assert(!SCIPisInfinity(scip, value));
215 if( SCIPisFeasZero(scip, value) )
233 while( SCIPisFeasGE(scip, mastervals[i], 1.0) )
236 j = identblock[block] * nusedpts;
237 assert(selection[j] == -1);
238 assert(nactualpts[identblock[block]] == 0);
240 nactualpts[identblock[block]] = 1;
244 mastervals[i] = mastervals[i] - 1.0;
248 for( j = identblock[block] + 1; j < nblocks; ++j )
251 identblock[block] = j;
256 assert(blocknrs[block] >= nidentblocks || j < nblocks);
262 for( i = 0; i < nmastervars; i++ )
266 mastervar = mastervars[i];
271 value = SCIPgetSolVal(masterprob, NULL, mastervar);
274 assert(!SCIPisInfinity(scip, value));
277 if( SCIPisFeasZero(scip, value) )
294 assert(SCIPisFeasGE(scip, mastervals[i], 0.0) && SCIPisFeasLT(scip, mastervals[i], 1.0));
296 while( SCIPisFeasPositive(scip, mastervals[i]) )
298 value = MIN(mastervals[i], 1.0 - blockvalue[block]);
303 for( j = (identblock[block] * nusedpts) + nactualpts[identblock[block]];
304 j > identblock[block] * nusedpts && SCIPisGT(scip, value, selvalue[j]); --j )
306 if( j < (identblock[block] + 1) * nusedpts )
308 selection[j] = selection[j-1];
309 selvalue[j] = selvalue[j-1];
312 if( j < (identblock[block] * nusedpts) + nusedpts )
317 if( nactualpts[identblock[block]] < nusedpts )
318 ++nactualpts[identblock[block]];
321 mastervals[i] = mastervals[i] - value;
322 if( SCIPisFeasZero(scip, mastervals[i]) )
324 blockvalue[block] += value;
327 if( SCIPisFeasGE(scip, blockvalue[block], 1.0) )
329 blockvalue[block] = 0.0;
333 for( j = identblock[block] + 1; j < nblocks; ++j )
336 identblock[block] = j;
341 assert(blocknrs[block] >= nidentblocks || j < nblocks);
350 SCIPfreeBufferArray(scip, &identblock);
351 SCIPfreeBufferArray(scip, &blockvalue);
352 SCIPfreeBufferArray(scip, &blocknrs);
353 SCIPfreeBufferArray(scip, &selvalue);
354 SCIPfreeBufferArray(scip, &mastervals);
364 SCIP_HEURDATA* heurdata,
373 SCIP_VAR** mastervars;
385 assert(scip != NULL);
386 assert(heurdata != NULL);
387 assert(selection != NULL);
388 assert(success != NULL);
392 assert(masterprob != NULL);
398 SCIP_CALL( SCIPgetVarsData(masterprob, &mastervars, &nmastervars, NULL, NULL, NULL, NULL) );
399 assert(mastervars != NULL);
400 assert(nmastervars >= 0);
403 nusedpts = heurdata->nusedpts;
406 SCIP_CALL( SCIPallocBufferArray(scip, &npts, nblocks) );
411 for( i = 0; i < nblocks; ++i )
413 for( i = 0; i < nmastervars; ++i )
419 mastervar = mastervars[i];
420 solval = SCIPgetSolVal(masterprob, NULL, mastervar);
423 if( block >= 0 && !SCIPisFeasZero(scip, solval) )
426 for( i = 0; i < nblocks; ++i )
433 SCIPdebugMessage(
" -> not enough extreme points available for randomization.\n");
436 SCIPfreeBufferArray(scip, &npts);
444 for( i = 0; i < nblocks; ++i )
452 SCIP_CALL( SCIPallocBufferArray(scip, &blockpts, npts[i]) );
453 SCIP_CALL( SCIPallocBufferArray(scip, &ptvals, npts[i]) );
457 assert(blockrep >= 0 && blockrep <= i);
461 for( j = 0; j < nmastervars; ++j )
467 mastervar = mastervars[j];
468 solval = SCIPgetSolVal(masterprob, NULL, mastervar);
471 if( block == blockrep && !SCIPisFeasZero(scip, solval) )
473 assert(k < npts[blockrep]);
478 assert(k == npts[blockrep]);
481 SCIPsortRealInt(ptvals, blockpts, npts[blockrep]);
482 lastpt = npts[blockrep];
485 for( k = 0; k < nusedpts; ++k )
490 idx = SCIPrandomGetInt(heurdata->randnumgen, nusedpts-k-1, lastpt-1);
491 selidx = i * nusedpts + k;
492 selection[selidx] = blockpts[idx];
496 nactualpts[i] = nusedpts;
498 SCIPfreeBufferArray(scip, &ptvals);
499 SCIPfreeBufferArray(scip, &blockpts);
505 SCIPfreeBufferArray(scip, &npts);
523 SCIP_VAR** mastervars;
529 assert(nusedpts == 0 || nusedpts == -1);
530 assert(selection == NULL);
534 assert(masterprob != NULL);
535 SCIP_CALL( SCIPgetVarsData(masterprob, &mastervars, &nmastervars, NULL, NULL, NULL, NULL) );
536 assert(mastervars != NULL);
537 assert(nmastervars >= 0);
541 for( i = 0; i < nblocks; ++i )
543 for( i = 0; i < nmastervars; ++i )
548 mastervar = mastervars[i];
549 assert(mastervar != NULL);
551 if( block >= 0 && (nusedpts == -1 || !SCIPisZero(scip, SCIPgetSolVal(masterprob, NULL, mastervar))) )
557 for( i = 0; i < nblocks; ++i )
560 assert(blockrep >= 0 && blockrep <= i);
562 nactualpts[i] = nactualpts[blockrep];
576 SCIP_HEURDATA* heurdata,
577 SCIP_Longint nstallnodes,
579 SCIP_Real memorylimit
587 char probname[SCIP_MAXSTRLEN];
588 SCIP_HASHMAP* varmapfw;
591 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
592 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
597 SCIP_CALL( SCIPincludeDefaultPlugins(subscip) );
600 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN,
"%s_extremeptsub", SCIPgetProbName(scip));
603 SCIP_CALL( SCIPcreateProb(subscip, probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
606 SCIP_CALL( SCIPcopyVars(scip, subscip, varmapfw, NULL, NULL, NULL, 0, TRUE) );
610 SCIP_CALL( SCIPcopyConss(scip, subscip, varmapfw, NULL, TRUE, FALSE, &valid) );
611 if( heurdata->copycuts )
614 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmapfw, NULL, TRUE, NULL) );
616 SCIPdebugMessage(
"Copying the SCIP constraints was %s complete.\n", valid ?
"" :
"not ");
619 for( i = 0; i < nvars; i++ )
620 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
623 SCIPhashmapFree(&varmapfw);
627 SCIP_CALL( SCIPsetBoolParam(subscip,
"misc/catchctrlc", FALSE) );
631 SCIP_CALL( SCIPsetIntParam(subscip,
"display/verblevel", 5) );
632 SCIP_CALL( SCIPsetIntParam(subscip,
"display/freq", 100000000) );
635 SCIP_CALL( SCIPsetIntParam(subscip,
"display/verblevel", 0) );
639 SCIP_CALL( SCIPsetLongintParam(subscip,
"limits/nodes", nstallnodes) );
640 SCIP_CALL( SCIPsetLongintParam(subscip,
"limits/stallnodes", MAX(10, nstallnodes/10)) );
641 SCIP_CALL( SCIPsetRealParam(subscip,
"limits/time", timelimit) );
642 SCIP_CALL( SCIPsetRealParam(subscip,
"limits/memory", memorylimit) );
645 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
648 SCIP_CALL( SCIPsetSeparating(subscip, SCIP_PARAMSETTING_OFF, TRUE) );
651 SCIP_CALL( SCIPsetPresolving(subscip, SCIP_PARAMSETTING_FAST, TRUE) );
654 if( SCIPfindNodesel(subscip,
"estimate") != NULL && !SCIPisParamFixed(subscip,
"nodeselection/estimate/stdpriority") )
656 SCIP_CALL( SCIPsetIntParam(subscip,
"nodeselection/estimate/stdpriority", INT_MAX/4) );
660 if( SCIPfindBranchrule(subscip,
"inference") != NULL && !SCIPisParamFixed(subscip,
"branching/inference/priority") )
662 SCIP_CALL( SCIPsetIntParam(subscip,
"branching/inference/priority", INT_MAX/4) );
666 if( !SCIPisParamFixed(subscip,
"conflict/enable") )
668 SCIP_CALL( SCIPsetBoolParam(subscip,
"conflict/enable", FALSE) );
672 if( SCIPgetNSols(scip) > 0 )
675 SCIP_Real upperbound;
677 assert( !SCIPisInfinity(scip,SCIPgetUpperbound(scip)) );
679 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
680 if( !SCIPisInfinity(scip,-1.0*SCIPgetLowerbound(scip)) )
682 cutoff = (1-heurdata->minimprove)*SCIPgetUpperbound(scip) + heurdata->minimprove*SCIPgetLowerbound(scip);
686 if( SCIPgetUpperbound ( scip ) >= 0 )
687 cutoff = ( 1 - heurdata->minimprove ) * SCIPgetUpperbound ( scip );
689 cutoff = ( 1 + heurdata->minimprove ) * SCIPgetUpperbound ( scip );
691 cutoff = MIN(upperbound, cutoff );
692 SCIP_CALL( SCIPsetObjlimit(subscip, cutoff) );
708 SCIP_Bool* zeroblocks
734 for( i = 0; i < norigvars; ++i )
736 SCIP_VAR* pricingvar;
737 SCIP_VAR** pricingorigvars;
738 int npricingorigvars;
740 if( SCIPvarGetType(origvars[i]) > SCIP_VARTYPE_INTEGER )
750 pricingvar = linkingpricingvars[block];
755 assert(pricingvar != NULL);
764 assert(pricingorigvars != NULL);
765 assert(npricingorigvars >= 0);
767 for( j = 0; j < npricingorigvars; ++j )
774 assert(origblock != -1);
776 if( solblock != -1 &&
777 ((origblock != -2 && origblock != solblock) || (origblock == -2 && !
GCGisLinkingVarInBlock(pricingorigvars[j], solblock))) )
780 idx = SCIPvarGetProbindex(pricingorigvars[j]);
781 assert(SCIPvarGetType(pricingorigvars[j]) <= SCIP_VARTYPE_INTEGER);
782 solval = SCIPgetRelaxSolVal(scip, pricingorigvars[j]);
787 if( SCIPisZero(scip, solval) )
789 if( !SCIPisZero(scip, origvals[i]) )
794 if( SCIPisEQ(scip, solval, origvals[i]) )
798 if( origblock != -2 )
799 zeroblocks[origblock] = FALSE;
804 for( k = 0; k < nblocks; ++k )
805 if( linkingpricingvars[k] != NULL )
806 zeroblocks[k] = FALSE;
822 SCIP_Bool* zeroblocks
826 SCIP_VAR** mastervars;
835 assert(masterprob != NULL);
836 SCIP_CALL( SCIPgetVarsData(masterprob, &mastervars, &nmastervars, NULL, NULL, NULL, NULL) );
837 assert(mastervars != NULL);
838 assert(nmastervars >= 0);
844 assert(nusedpts == 0 || nusedpts == -1);
846 for( i = 0; i < nmastervars; ++i )
851 mastervar = mastervars[i];
858 if( nusedpts == 0 && SCIPisZero(scip, SCIPgetSolVal(masterprob, NULL, mastervar)) )
866 assert(selection != NULL);
868 for( i = 0; i < nblocks; ++i )
871 for( j = 0; j < nusedpts; ++j )
873 int selidx = i * nusedpts + j;
874 if( selection[selidx] != -1 )
879 mastervar = mastervars[selection[selidx]];
880 assert(mastervar != NULL);
902 SCIP_HEURDATA* heurdata,
903 SCIP_Real* intfixingrate,
904 SCIP_Real* zerofixingrate,
916 SCIP_Bool* zeroblocks;
924 assert(scip != NULL);
925 assert(subscip != NULL);
926 assert(subvars != NULL);
927 assert(heurdata != NULL);
928 assert(selection != NULL || heurdata->nusedpts < 0);
929 assert(nactualpts != NULL);
930 assert(intfixingrate != NULL);
931 assert(zerofixingrate != NULL);
932 assert(success != NULL);
935 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
944 SCIP_CALL( SCIPallocBufferArray(scip, &neqpts, nbinvars + nintvars) );
945 SCIP_CALL( SCIPallocBufferArray(scip, &zeroblocks, nblocks) );
947 for( i = 0; i < nblocks; ++i )
948 zeroblocks[i] = TRUE;
957 for( i = 0; i < nbinvars + nintvars; ++i )
967 solval = SCIPgetRelaxSolVal(scip, var);
969 if( !SCIPisZero(scip, solval) || block == -1 )
971 else if( block == -2 )
975 for( j = 0; j < nblocks; ++j )
976 if( linkingpricingvars[j] != NULL )
977 neqpts[i] += nactualpts[j];
982 neqpts[i] = nactualpts[block];
989 for( i = 0; i < nbinvars + nintvars; ++i )
998 solval = SCIPgetRelaxSolVal(scip, var);
1005 if( SCIPisFeasIntegral(scip, solval) )
1010 solval = SCIPfloor(scip, solval + 0.5);
1011 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], solval) );
1012 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], solval) );
1015 if( SCIPisZero(scip, solval) )
1025 SCIP_Real quoteqpts;
1027 assert(block == -2 || block >= 0);
1033 ntotalpts = nactualpts[block];
1036 SCIP_VAR** linkingpricingvars;
1042 for( j = 0; j < nblocks; ++j )
1043 if( linkingpricingvars[j] != NULL )
1044 ntotalpts += nactualpts[j];
1047 assert(neqpts[i] <= ntotalpts);
1048 quoteqpts = (SCIP_Real) neqpts[i] / (SCIP_Real) MAX(ntotalpts,1);
1050 SCIPdebugMessage(
"Variable %s: %d/%d (%.2f percent) extreme points identical to relaxation solution (value=%g).\n",
1051 SCIPvarGetName(var), neqpts[i], ntotalpts, quoteqpts * 100, solval);
1056 if( quoteqpts >= heurdata->equalityrate && (block < 0 || !zeroblocks[block]) )
1058 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], solval) );
1059 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], solval) );
1062 if( SCIPisZero(scip, solval) )
1068 *intfixingrate = (SCIP_Real) fixingcounter / (SCIP_Real) (MAX(nbinvars + nintvars, 1));
1069 *zerofixingrate = (SCIP_Real)zerocounter / MAX((SCIP_Real)fixingcounter, 1.0);
1074 while( *intfixingrate < heurdata->minfixingrate )
1076 SCIPdebugMessage(
" fixing rate only %5.2f --> trying to fix a zero block\n", *intfixingrate);
1079 for( i = 0; i < nblocks; ++i )
1083 for( j = 0; j < nbinvars + nintvars; ++j )
1086 SCIP_Real quoteqpts;
1089 assert(SCIPisZero(scip, SCIPgetRelaxSolVal(scip, vars[j])));
1090 assert(neqpts[j] <= nactualpts[i]);
1091 quoteqpts = (SCIP_Real) neqpts[j] / (SCIP_Real) MAX(nactualpts[i],1);
1093 if( quoteqpts >= heurdata->equalityrate )
1095 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[j], 0.0) );
1096 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[j], 0.0) );
1103 zeroblocks[i] = FALSE;
1107 *intfixingrate = (SCIP_Real)fixingcounter / (SCIP_Real)(MAX(nbinvars + nintvars, 1));
1108 *zerofixingrate = (SCIP_Real)zerocounter / MAX((SCIP_Real)fixingcounter, 1.0);
1115 if( *intfixingrate < heurdata->minfixingrate )
1117 SCIPstatisticPrintf(
"xprins statistic: fixed only %5.2f ( %5.2f zero) integer variables --> abort \n", *intfixingrate, *zerofixingrate);
1119 if( fixingcounter == nbinvars + nintvars )
1121 SCIPstatisticPrintf(
"xprins statistic: fixed all ( %5.2f zero) integer variables --> abort \n", *zerofixingrate);
1127 SCIPfreeBufferArray(scip, &zeroblocks);
1128 SCIPfreeBufferArray(scip, &neqpts);
1145 #ifdef SCIP_STATISTIC
1146 SCIP_HEURDATA* heurdata;
1151 SCIP_Real* subsolvals;
1153 assert(scip != NULL);
1154 assert(subscip != NULL);
1155 assert(subvars != NULL);
1156 assert(subsol != NULL);
1158 #ifdef SCIP_STATISTIC
1160 heurdata = SCIPheurGetData(heur);
1161 assert( heurdata != NULL );
1165 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
1166 assert(nvars <= SCIPgetNOrigVars(subscip));
1168 SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );
1171 SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) );
1174 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
1175 SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
1177 SCIPstatisticPrintf(
"xprins statistic: Solution %13.6e found at node %"SCIP_LONGINT_FORMAT
"\n",
1178 SCIPgetSolTransObj(scip, newsol), SCIPsolGetNodenum(subsol));
1181 #ifdef SCIP_STATISTIC
1184 SCIP_CALL( SCIPtrySol(scip, newsol, FALSE, FALSE, TRUE, TRUE, TRUE, success) );
1186 #ifdef SCIP_STATISTIC
1187 if( SCIPgetSolTransObj(scip, newsol) < heurdata->bestprimalbd )
1188 heurdata->bestprimalbd = SCIPgetSolTransObj(scip, newsol);
1190 SCIPstatisticPrintf(
"xprins statistic: Solution %13.6e found at node %"SCIP_LONGINT_FORMAT
"\n",
1191 SCIPgetSolTransObj(scip, newsol), SCIPsolGetNodenum(subsol));
1194 SCIP_CALL( SCIPfreeSol(scip, &newsol) );
1196 SCIPfreeBufferArray(scip, &subsolvals);
1205 SCIP_HEURDATA* heurdata
1209 heurdata->nfailures++;
1210 heurdata->nextnodenumber = (heurdata->nfailures <= 25
1211 ? SCIPgetNNodes(scip) + 100*(2LL << heurdata->nfailures)
1212 : SCIP_LONGINT_MAX);
1225 SCIP_HEURDATA* heurdata;
1227 assert(heur != NULL);
1228 assert(scip != NULL);
1231 heurdata = SCIPheurGetData(heur);
1232 assert(heurdata != NULL);
1235 SCIPfreeMemory(scip, &heurdata);
1236 SCIPheurSetData(heur, NULL);
1245 SCIP_HEURDATA* heurdata;
1247 assert(heur != NULL);
1248 assert(scip != NULL);
1251 heurdata = SCIPheurGetData(heur);
1252 assert(heurdata != NULL);
1255 heurdata->usednodes = 0;
1256 heurdata->nfailures = 0;
1257 heurdata->nextnodenumber = 0;
1260 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
1270 SCIP_HEURDATA* heurdata;
1272 assert(heur != NULL);
1273 assert(scip != NULL);
1276 heurdata = SCIPheurGetData(heur);
1277 assert(heurdata != NULL);
1280 SCIPfreeRandom(scip, &heurdata->randnumgen);
1285 #ifdef SCIP_STATISTIC
1290 SCIP_HEURDATA* heurdata;
1292 assert(heur != NULL);
1293 assert(scip != NULL);
1296 heurdata = SCIPheurGetData(heur);
1297 assert(heurdata != NULL);
1300 heurdata->avgfixrate = 0.0;
1301 heurdata->avgzerorate = 0.0;
1302 heurdata->totalsols = 0;
1303 heurdata->subsciptime = 0.0;
1304 heurdata->bestprimalbd = SCIPinfinity(scip);
1313 SCIP_HEURDATA* heurdata;
1314 SCIP_Longint ncalls;
1316 assert(heur != NULL);
1317 assert(scip != NULL);
1320 heurdata = SCIPheurGetData(heur);
1321 assert(heurdata != NULL);
1323 ncalls = SCIPheurGetNCalls(heur);
1324 heurdata->avgfixrate /= MAX((SCIP_Real)ncalls, 1.0);
1325 heurdata->avgzerorate /= MAX((SCIP_Real)ncalls, 1.0);
1328 SCIPstatisticPrintf(
"LNS Statistics -- %s:\n", SCIPheurGetName(heur));
1329 SCIPstatisticPrintf(
"Calls : %13"SCIP_LONGINT_FORMAT
"\n", ncalls);
1330 SCIPstatisticPrintf(
"Failed Fixings : %13"SCIP_LONGINT_FORMAT
"\n", heurdata->nfixfails);
1331 SCIPstatisticPrintf(
"Sols : %13"SCIP_LONGINT_FORMAT
"\n", SCIPheurGetNSolsFound(heur));
1332 SCIPstatisticPrintf(
"Improving Sols : %13"SCIP_LONGINT_FORMAT
"\n", SCIPheurGetNBestSolsFound(heur));
1333 SCIPstatisticPrintf(
"Total Sols : %13"SCIP_LONGINT_FORMAT
"\n", heurdata->totalsols);
1334 SCIPstatisticPrintf(
"subSCIP time : %13.2f\n", heurdata->subsciptime);
1335 SCIPstatisticPrintf(
"subSCIP nodes : %13"SCIP_LONGINT_FORMAT
"\n", heurdata->usednodes);
1336 SCIPstatisticPrintf(
"Avg. fixing rate : %13.2f\n", 100.0 * heurdata->avgfixrate);
1337 SCIPstatisticPrintf(
"Avg. zero rate : %13.2f\n", 100.0 * heurdata->avgzerorate);
1338 SCIPstatisticPrintf(
"Best primal bd. :");
1339 if( SCIPisInfinity(scip, heurdata->bestprimalbd) )
1340 SCIPstatisticPrintf(
" infinity\n");
1342 SCIPstatisticPrintf(
" %13.6e\n", heurdata->bestprimalbd);
1343 SCIPstatisticPrintf(
"\n");
1356 SCIP_HEURDATA* heurdata;
1361 SCIP_Real memorylimit;
1362 SCIP_Real timelimit;
1363 SCIP_Longint nstallnodes;
1364 SCIP_Real allfixingrate;
1365 SCIP_Real intfixingrate;
1366 SCIP_Real zerofixingrate;
1373 SCIP_RETCODE retcode;
1377 assert(heur != NULL);
1378 assert(strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0);
1379 assert(scip != NULL);
1380 assert(result != NULL);
1384 assert(masterprob != NULL);
1389 heurdata = SCIPheurGetData(heur);
1390 assert(heurdata != NULL);
1392 *result = SCIP_DELAYED;
1397 if( !SCIPisRelaxSolValid(scip) )
1399 SCIPdebugMessage(
"skipping Extreme Point RINS: invalid relaxation solution\n");
1404 if( SCIPgetStage(masterprob) > SCIP_STAGE_SOLVING || SCIPgetLPSolstat(masterprob) != SCIP_LPSOLSTAT_OPTIMAL )
1406 SCIPdebugMessage(
"skipping Extreme Point RINS: master LP not solved to optimality.\n");
1410 assert(SCIPhasCurrentNodeLP(masterprob));
1413 if( SCIPgetNNodes(scip) < heurdata->nextnodenumber )
1416 *result = SCIP_DIDNOTRUN;
1419 if( SCIPgetNExternBranchCands(scip) == 0 )
1425 SCIP_CALL( SCIPgetRealParam(scip,
"limits/time", &timelimit) );
1426 if( !SCIPisInfinity(scip, timelimit) )
1427 timelimit -= SCIPgetSolvingTime(scip);
1428 SCIP_CALL( SCIPgetRealParam(scip,
"limits/memory", &memorylimit) );
1431 if( !SCIPisInfinity(scip, memorylimit) )
1433 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
1434 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
1438 if( timelimit <= 0.0 || memorylimit <= 2.0*SCIPgetMemExternEstim(scip)/1048576.0 )
1442 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
1445 nstallnodes = (SCIP_Longint)
1446 (nstallnodes * (1.0 + 2.0*(SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur)+1.0)));
1449 nstallnodes -= 100 * SCIPheurGetNCalls(heur);
1450 nstallnodes += heurdata->nodesofs;
1453 nstallnodes -= heurdata->usednodes;
1454 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
1457 if( nstallnodes < heurdata->minnodes )
1459 SCIPdebugMessage(
"skipping Extreme Point RINS: nstallnodes=%"SCIP_LONGINT_FORMAT
", minnodes=%"SCIP_LONGINT_FORMAT
"\n", nstallnodes, heurdata->minnodes);
1463 if( SCIPisStopped(scip) )
1466 SCIPdebugMessage(
"Executing Extreme Point RINS heuristic ...\n");
1469 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, SCIPgetNVars(scip)) );
1470 SCIP_CALL( SCIPallocBufferArray(scip, &nactualpts, nblocks) );
1473 if( heurdata->nusedpts > 0 )
1476 SCIP_CALL( SCIPallocBufferArray(scip, &selection, nblocks * heurdata->nusedpts) );
1479 for( i = 0; i < nblocks * heurdata->nusedpts; ++i )
1484 if( heurdata->randomization )
1486 SCIPdebugMessage(
"selecting extreme points randomly...\n");
1490 SCIPdebugMessage(
" --> unsuccessful!\n");
1493 if( !heurdata->randomization || !success )
1495 SCIPdebugMessage(
"selecting extreme points deterministically...\n");
1502 SCIPdebugMessage(
"no proper selection could be created - aborting heuristic.\n");
1507 SCIPfreeBufferArray(scip, &selection);
1508 SCIPfreeBufferArray(scip, &nactualpts);
1509 SCIPfreeBufferArray(scip, &subvars);
1516 if( heurdata->randomization )
1518 SCIPwarningMessage(scip,
"Randomization not supported when number of selected extreme points is not constant -- ignoring parameter\n");
1525 SCIP_CALL( SCIPcreate(&subscip) );
1526 SCIP_CALL(
setupSubproblem(scip, subscip, subvars, heurdata, nstallnodes, timelimit, memorylimit) );
1527 SCIPdebugMessage(
"XP RINS subproblem: %d vars, %d conss\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
1529 SCIPstatisticPrintf(
"xprins statistic: called at node %"SCIP_LONGINT_FORMAT
"\n", SCIPgetNNodes(scip));
1532 SCIP_CALL(
fixVariables(scip, subscip, subvars, selection, nactualpts, heurdata, &intfixingrate, &zerofixingrate, &success) );
1534 #ifdef SCIP_STATISTIC
1536 heurdata->avgfixrate += intfixingrate;
1537 heurdata->avgzerorate += zerofixingrate;
1547 #ifdef SCIP_STATISTIC
1548 ++heurdata->nfixfails;
1553 *result = SCIP_DIDNOTFIND;
1556 retcode = SCIPpresolve(subscip);
1561 if( retcode != SCIP_OKAY )
1564 SCIP_CALL( retcode );
1566 SCIPwarningMessage(scip,
"Error while presolving subproblem in XP RINS heuristic; sub-SCIP terminated with code <%d>\n",retcode);
1570 SCIPdebugMessage(
"XP RINS presolved subproblem: %d vars, %d conss, success=%u\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip), success);
1572 allfixingrate = (SCIPgetNOrigVars(subscip) - SCIPgetNVars(subscip)) / (SCIP_Real)SCIPgetNOrigVars(subscip);
1575 allfixingrate = MAX(allfixingrate, 0.0);
1580 if( allfixingrate >= heurdata->minfixingrate / 2.0 )
1586 SCIPdebugMessage(
"subSCIP: Solving... (node limit = %lld, time limit = %.2g)\n", nstallnodes, timelimit);
1592 retcode = SCIPsolve(subscip);
1593 if( retcode != SCIP_OKAY )
1595 SCIPwarningMessage(scip,
"Error while solving subproblem in XP RINS heuristic; sub-SCIP terminated with code <%d>\n",
1599 SCIP_CALL( SCIPsolve(subscip) );
1602 #ifdef SCIP_STATISTIC
1603 heurdata->usednodes += SCIPgetNNodes(subscip);
1604 heurdata->subsciptime += SCIPgetTotalTime(subscip);
1610 nsubsols = SCIPgetNSols(subscip);
1611 subsols = SCIPgetSols(subscip);
1613 #ifdef SCIP_STATISTIC
1614 heurdata->totalsols += nsubsols;
1615 for( i = 0; i < nsubsols; ++i )
1617 for( i = 0; i < nsubsols && !success; ++i )
1620 SCIP_CALL(
createNewSol(scip, subscip, subvars, heur, subsols[i], &success) );
1622 *result = SCIP_FOUNDSOL;
1625 SCIPstatisticPrintf(
"xprins statistic: fixed %6.3f integer variables ( %6.3f zero), %6.3f all variables, needed %6.1f sec (SCIP time: %6.1f sec), %"SCIP_LONGINT_FORMAT
" nodes, found %d solutions, solution %10.4f found at node %"SCIP_LONGINT_FORMAT
"\n",
1626 intfixingrate, zerofixingrate, allfixingrate, SCIPgetSolvingTime(subscip), SCIPgetSolvingTime(scip), SCIPgetNNodes(subscip), nsubsols,
1627 success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip), nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
1633 SCIPdebugMessage(
" -> no subMIP solution found - subSCIP status is %d\n", SCIPgetStatus(subscip));
1638 SCIPstatisticPrintf(
"xprins statistic: fixed only %6.3f integer variables ( %6.3f zero), %6.3f all variables --> abort \n", intfixingrate, zerofixingrate, allfixingrate);
1643 SCIP_CALL( SCIPfree(&subscip) );
1644 SCIPfreeBufferArrayNull(scip, &selection);
1645 SCIPfreeBufferArray(scip, &nactualpts);
1646 SCIPfreeBufferArray(scip, &subvars);
1662 SCIP_HEURDATA* heurdata;
1666 SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
1669 SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
1673 assert(heur != NULL);
1676 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeXprins) );
1677 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitXprins) );
1678 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitXprins) );
1679 #ifdef SCIP_STATISTIC
1680 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolXprins) );
1681 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolXprins) );
1686 SCIP_CALL( SCIPaddRealParam(scip,
"heuristics/"HEUR_NAME"/equalityrate",
1687 "minimum percentage of coincidence of relaxation and extreme pts",
1690 SCIP_CALL( SCIPaddLongintParam(scip,
"heuristics/"HEUR_NAME"/nodesofs",
1691 "number of nodes added to the contingent of the total nodes",
1692 &heurdata->nodesofs, FALSE,
DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1694 SCIP_CALL( SCIPaddLongintParam(scip,
"heuristics/"HEUR_NAME"/maxnodes",
1695 "maximum number of nodes to regard in the subproblem",
1696 &heurdata->maxnodes, TRUE,
DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1698 SCIP_CALL( SCIPaddLongintParam(scip,
"heuristics/"HEUR_NAME"/minnodes",
1699 "minimum number of nodes required to start the subproblem",
1700 &heurdata->minnodes, TRUE,
DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1702 SCIP_CALL( SCIPaddIntParam(scip,
"heuristics/"HEUR_NAME"/nusedpts",
1703 "number of extreme pts per block that will be taken into account (-1: all; 0: all which contribute to current relaxation solution)",
1706 SCIP_CALL( SCIPaddRealParam(scip,
"heuristics/"HEUR_NAME"/nodesquot",
1707 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1710 SCIP_CALL( SCIPaddRealParam(scip,
"heuristics/"HEUR_NAME"/minfixingrate",
1711 "minimum percentage of integer variables that have to be fixed",
1714 SCIP_CALL( SCIPaddRealParam(scip,
"heuristics/"HEUR_NAME"/minimprove",
1715 "factor by which crossover should at least improve the incumbent",
1718 SCIP_CALL( SCIPaddBoolParam(scip,
"heuristics/"HEUR_NAME"/randomization",
1719 "should the choice which sols to take be randomized?",
1722 SCIP_CALL( SCIPaddBoolParam(scip,
"heuristics/"HEUR_NAME"/copycuts",
1723 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",