30 #define HEUR_NAME "intshifting" 31 #define HEUR_DESC "LP rounding heuristic with infeasibility recovering and final LP solving" 32 #define HEUR_DISPCHAR 'i' 33 #define HEUR_PRIORITY -10000 35 #define HEUR_FREQOFS 0 36 #define HEUR_MAXDEPTH -1 37 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE 38 #define HEUR_USESSUBSCIP FALSE 40 #define MAXSHIFTINGS 50 41 #define WEIGHTFACTOR 1.1 42 #define DEFAULT_RANDSEED 17 78 assert(violrows != NULL);
79 assert(violrowpos != NULL);
80 assert(nviolrows != NULL);
86 if( oldviol != newviol )
97 violpos = violrowpos[rowpos];
98 assert(0 <= violpos && violpos < *nviolrows);
99 assert(violrows[violpos] == row);
100 violrowpos[rowpos] = -1;
102 if( nfracsinrow[rowpos] > 0 )
104 violrows[violpos] = violrows[*nviolrows-1];
105 assert(violpos < *nviolfracrows);
108 if( violpos != *nviolfracrows - 1 )
110 violrows[violpos] = violrows[*nviolfracrows - 1];
112 violpos = *nviolfracrows - 1;
117 assert(violpos >= *nviolfracrows);
120 if( violpos != *nviolrows - 1 )
122 violrows[violpos] = violrows[*nviolrows - 1];
130 assert(violrowpos[rowpos] == -1);
131 violrows[*nviolrows] = row;
132 violrowpos[rowpos] = *nviolrows;
138 if( nfracsinrow[rowpos] > 0 )
140 if( *nviolfracrows < *nviolrows - 1 )
144 violrows[*nviolrows - 1] = violrows[*nviolfracrows];
145 violrowpos[
SCIProwGetLPPos(violrows[*nviolrows - 1])] = *nviolrows - 1;
147 violrows[*nviolfracrows] = row;
148 violrowpos[rowpos] = *nviolfracrows;
180 assert(minactivities != NULL);
181 assert(maxactivities != NULL);
182 assert(nviolrows != NULL);
183 assert(0 <= *nviolrows && *nviolrows <= nlprows);
186 delta = newsolval - oldsolval;
191 assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
193 for( r = 0; r < ncolrows; ++r )
200 assert(-1 <= rowpos && rowpos < nlprows);
212 oldminactivity = minactivities[rowpos];
213 oldmaxactivity = maxactivities[rowpos];
217 newminactivity = oldminactivity + delta * colvals[r];
218 minactivities[rowpos] = newminactivity;
224 newmaxactivity = oldmaxactivity + delta * colvals[r];
225 maxactivities[rowpos] = newmaxactivity;
231 updateViolations(scip, row, violrows, violrowpos, nviolrows, nviolfracrows, nfracsinrow, oldminactivity, oldmaxactivity,
232 newminactivity, newmaxactivity);
269 assert(direction == +1 || direction == -1);
270 assert(nincreases != NULL);
271 assert(ndecreases != NULL);
272 assert(shiftvar != NULL);
273 assert(oldsolval != NULL);
274 assert(newsolval != NULL);
292 for( c = 0; c < nrowcols; ++c )
315 increase = (direction * val > 0.0);
325 shiftscore = ndecreases[probindex]/increaseweight;
327 shiftscore = nincreases[probindex]/increaseweight;
331 if( shiftscore <= bestshiftscore )
338 assert(direction * val < 0.0);
345 assert(activitydelta/val < 0.0);
346 shiftval = solval + activitydelta/val;
347 assert(shiftval <= solval);
350 shiftval =
MAX(shiftval, lb);
356 assert(direction * val > 0.0);
363 assert(activitydelta/val > 0.0);
364 shiftval = solval + activitydelta/val;
365 assert(shiftval >= solval);
368 shiftval = MIN(shiftval, ub);
372 if(
SCIPisEQ(scip, shiftval, solval) )
376 if( (shiftscore < bestshiftscore || deltaobj < bestdeltaobj)
379 bestshiftscore = shiftscore;
380 bestdeltaobj = deltaobj;
383 *newsolval = shiftval;
418 assert(shiftvar != NULL);
419 assert(oldsolval != NULL);
420 assert(newsolval != NULL);
426 for( v = 0; v < nlpcands; ++v )
438 if( nlocks >= maxnlocks )
441 deltaobj = obj * (shiftval - solval);
442 if( (nlocks > maxnlocks || deltaobj < bestdeltaobj) && minobj - obj <
SCIPgetCutoffbound(scip) )
445 bestdeltaobj = deltaobj;
448 *newsolval = shiftval;
454 if( nlocks >= maxnlocks )
457 deltaobj = obj * (shiftval - solval);
458 if( (nlocks > maxnlocks || deltaobj < bestdeltaobj) && minobj + obj <
SCIPgetCutoffbound(scip) )
461 bestdeltaobj = deltaobj;
464 *newsolval = shiftval;
492 assert(nviolrows >= *nviolfracrows);
497 for( r = 0; r < nrows; ++r )
506 assert(0 <= rowlppos && rowlppos < nlprows);
512 nfracsinrow[rowlppos] += incval;
513 assert(nfracsinrow[rowlppos] >= 0);
515 theviolrowpos = violrowpos[rowlppos];
518 if( theviolrowpos >= 0 )
523 if( nfracsinrow[rowlppos] == 0 )
525 assert(theviolrowpos <= *nviolfracrows - 1);
529 if( theviolrowpos < *nviolfracrows - 1 )
531 violrows[theviolrowpos] = violrows[*nviolfracrows - 1];
532 violrows[*nviolfracrows - 1] = row;
536 violrowpos[rowlppos] = *nviolfracrows - 1;
543 else if( nfracsinrow[rowlppos] == incval )
545 assert(theviolrowpos >= *nviolfracrows);
548 if( theviolrowpos > *nviolfracrows )
550 violrows[theviolrowpos] = violrows[*nviolfracrows];
551 violrows[*nviolfracrows] = row;
555 violrowpos[rowlppos] = *nviolfracrows;
572 assert(
scip != NULL);
573 assert(heur != NULL);
595 heurdata->lastlp = -1;
615 assert(heurdata != NULL);
636 assert(heurdata != NULL);
637 heurdata->lastlp = -1;
671 int nnonimprovingshifts;
680 assert(
scip != NULL);
681 assert(result != NULL);
706 assert(heurdata != NULL);
710 if( nlps == heurdata->lastlp )
712 heurdata->lastlp = nlps;
718 if( nnodes % (ncalls/(nsolsfound+1)+1) != 0 )
735 SCIPdebugMsg(
scip,
"executing intshifting heuristic: %d LP rows, %d fractionals\n", nlprows, nfrac);
755 for( r = 0; r < nlprows; ++r )
772 minactivities[r] = 0.0;
773 maxactivities[r] = 0.0;
777 for( c = 0; c < nnonz && !(mininf && maxinf); ++c )
787 minactivities[r] += act;
788 maxactivities[r] += act;
790 else if( vals[c] > 0.0 )
800 minactivities[r] += vals[c] * lb;
804 maxactivities[r] += vals[c] * ub;
806 else if( vals[c] < 0.0 )
816 minactivities[r] += vals[c] * ub;
820 maxactivities[r] += vals[c] * lb;
832 violrows[nviolrows] = row;
833 violrowpos[r] = nviolrows;
846 for( c = 0; c < nlpcands; ++c )
847 addFracCounter(nfracsinrow, violrows, violrowpos, &nviolfracrows, nviolrows, nlprows, lpcands[c], +1);
859 for( c = 0; c < nlpcands; ++c )
863 minobj += obj * (bestshiftval - lpcandssol[c]);
867 nnonimprovingshifts = 0;
868 minnviolrows = INT_MAX;
869 increaseweight = 1.0;
878 SCIPdebugMsg(
scip,
"intshifting heuristic: nfrac=%d, nviolrows=%d, obj=%g (best possible obj: %g), cutoff=%g\n",
882 nprevviolrows = nviolrows;
891 if( nviolrows > 0 && (nfrac == 0 || nnonimprovingshifts <
MAXSHIFTINGS-1) )
898 assert(nviolfracrows == 0 || nfrac > 0);
902 if( nviolfracrows > 0 )
903 rowidx = nviolfracrows - 1;
907 assert(0 <= rowidx && rowidx < nviolrows);
908 row = violrows[rowidx];
910 assert(0 <= rowpos && rowpos < nlprows);
911 assert(violrowpos[rowpos] == rowidx);
912 assert(nfracsinrow[rowpos] == 0 || rowidx == nviolfracrows - 1);
914 SCIPdebugMsg(
scip,
"intshifting heuristic: try to fix violated row <%s>: %g <= [%g,%g] <= %g\n",
925 direction, nincreases, ndecreases, increaseweight, &shiftvar, &oldsolval, &newsolval) );
928 if( shiftvar == NULL && nfrac > 0 )
930 SCIPdebugMsg(
scip,
"intshifting heuristic: search rounding variable and try to stay feasible\n");
935 if( shiftvar == NULL ||
SCIPisEQ(
scip, oldsolval, newsolval) )
937 SCIPdebugMsg(
scip,
"intshifting heuristic: -> didn't find a shifting variable\n");
943 SCIPdebugMsg(
scip,
"intshifting heuristic: -> shift var <%s>[%g,%g], type=%d, oldval=%g, newval=%g, obj=%g\n",
949 nfracsinrow, nlprows, shiftvar, oldsolval, newsolval) );
951 if( nviolrows >= nprevviolrows )
952 nnonimprovingshifts++;
953 else if( nviolrows < minnviolrows )
955 minnviolrows = nviolrows;
956 nnonimprovingshifts = 0;
965 if( oldsolvalisfrac )
969 nnonimprovingshifts = 0;
970 minnviolrows = INT_MAX;
971 addFracCounter(nfracsinrow, violrows, violrowpos, &nviolfracrows, nviolrows, nlprows, shiftvar, -1);
974 if( obj > 0.0 && newsolval > oldsolval )
976 else if( obj < 0.0 && newsolval < oldsolval )
982 minobj += obj * (newsolval - oldsolval);
986 if( !oldsolvalisfrac )
989 assert(0 <= probindex && probindex < nvars);
991 if( newsolval < oldsolval )
992 ndecreases[probindex] += increaseweight;
994 nincreases[probindex] += increaseweight;
995 if( increaseweight >= 1e+09 )
999 for( i = 0; i < nvars; ++i )
1001 nincreases[i] /= increaseweight;
1002 ndecreases[i] /= increaseweight;
1004 increaseweight = 1.0;
1008 SCIPdebugMsg(
scip,
"intshifting heuristic: -> nfrac=%d, nviolrows=%d, obj=%g (best possible obj: %g)\n",
1015 if( nfrac == 0 && nviolrows == 0 )
1025 SCIPdebugMsg(
scip,
"shifted solution is potentially feasible -> solve LP to fix continuous variables\n");
1033 for( v = 0; v < nvars; ++v )
1041 for( v = 0; v < nintvars; ++v )
1062 SCIPwarningMessage(
scip,
"Error while solving LP in Intshifting heuristic; LP solve terminated with code <%d>\n",retstat);
1126 assert(heur != NULL);
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
int SCIPgetNIntVars(SCIP *scip)
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed)
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
int SCIProwGetNNonz(SCIP_ROW *row)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_HEUREXEC(heurExecIntshifting)
const char * SCIProwGetName(SCIP_ROW *row)
int SCIProwGetNLPNonz(SCIP_ROW *row)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
enum SCIP_Retcode SCIP_RETCODE
static SCIP_RETCODE selectShifting(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *row, SCIP_Real rowactivity, int direction, SCIP_Real *nincreases, SCIP_Real *ndecreases, SCIP_Real increaseweight, SCIP_VAR **shiftvar, SCIP_Real *oldsolval, SCIP_Real *newsolval)
SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
int SCIPvarGetProbindex(SCIP_VAR *var)
struct SCIP_HeurData SCIP_HEURDATA
#define SCIPfreeBlockMemory(scip, ptr)
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPincludeHeurIntshifting(SCIP *scip)
#define SCIPfreeBufferArray(scip, ptr)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define SCIPallocBlockMemory(scip, ptr)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
int SCIPgetNContVars(SCIP *scip)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
static SCIP_DECL_HEURINIT(heurInitIntshifting)
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
static SCIP_RETCODE updateActivities(SCIP *scip, SCIP_Real *minactivities, SCIP_Real *maxactivities, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, int nlprows, SCIP_VAR *var, SCIP_Real oldsolval, SCIP_Real newsolval)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
const char * SCIPheurGetName(SCIP_HEUR *heur)
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
static SCIP_DECL_HEUREXIT(heurExitIntshifting)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void addFracCounter(int *nfracsinrow, SCIP_ROW **violrows, int *violrowpos, int *nviolfracrows, int nviolrows, int nlprows, SCIP_VAR *var, int incval)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
public data structures and miscellaneous methods
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
static void updateViolations(SCIP *scip, SCIP_ROW *row, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, SCIP_Real oldminactivity, SCIP_Real oldmaxactivity, SCIP_Real newminactivity, SCIP_Real newmaxactivity)
SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
int SCIPvarGetNLocksUp(SCIP_VAR *var)
static SCIP_RETCODE selectEssentialRounding(SCIP *scip, SCIP_SOL *sol, SCIP_Real minobj, SCIP_VAR **lpcands, int nlpcands, SCIP_VAR **shiftvar, SCIP_Real *oldsolval, SCIP_Real *newsolval)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
int SCIPgetNBinVars(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
SCIP_Real SCIPgetLPObjval(SCIP *scip)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
static SCIP_DECL_HEURCOPY(heurCopyIntshifting)
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
int SCIProwGetLPPos(SCIP_ROW *row)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
SCIP_Longint SCIPheurGetNSolsFound(SCIP_HEUR *heur)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_RETCODE SCIPstartDive(SCIP *scip)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
#define BMSclearMemoryArray(ptr, num)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
LP rounding heuristic that tries to recover from intermediate infeasibilities, shifts integer variabl...
SCIP_RETCODE SCIPendDive(SCIP *scip)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
static SCIP_DECL_HEURINITSOL(heurInitsolIntshifting)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
int SCIPcolGetNLPNonz(SCIP_COL *col)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)