28 #define HEUR_NAME "octane" 29 #define HEUR_DESC "octane primal heuristic for pure {0;1}-problems based on Balas et al." 30 #define HEUR_DISPCHAR 'O' 31 #define HEUR_PRIORITY -1008000 33 #define HEUR_FREQOFS 0 34 #define HEUR_MAXDEPTH -1 35 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE 36 #define HEUR_USESSUBSCIP FALSE 38 #define DEFAULT_FMAX 100 39 #define DEFAULT_FFIRST 10 40 #define DEFAULT_USEFRACSPACE TRUE 81 assert(facets !=
NULL);
82 assert(lambda !=
NULL);
83 assert(nfacets !=
NULL);
88 lastfacet = facets[f_max];
91 for( k = f_max; k > 0 &&
SCIPisFeasGT(scip, lambda[k-1], lam); --k )
93 lambda[k] = lambda[k-1];
94 facets[k] = facets[k-1];
96 assert(i < k && k < f_max );
99 facets[k] = lastfacet;
104 facets[k][j] = !facets[k][j];
121 assert(scip !=
NULL);
122 assert(facet !=
NULL);
124 assert(sign !=
NULL);
125 assert(subspacevars !=
NULL);
128 for( v = nsubspacevars - 1; v >= 0; --v )
132 if( facet[v] == sign[v] )
156 assert(scip !=
NULL);
157 assert(raydirection !=
NULL);
158 assert(subspacevars !=
NULL);
160 for( v = nsubspacevars - 1; v >= 0; --v )
176 assert(scip !=
NULL);
177 assert(raydirection !=
NULL);
178 assert(subspacevars !=
NULL);
180 for( v = nsubspacevars - 1; v >= 0; --v )
201 int** tableaurowinds;
202 int* ntableaurowinds;
212 assert(scip !=
NULL);
213 assert(raydirection !=
NULL);
214 assert(subspacevars !=
NULL);
215 assert(nsubspacevars > 0);
220 assert(rows !=
NULL);
226 for( j = nsubspacevars - 1; j >= 0; --j )
240 for( j = nsubspacevars - 1; j >= 0; --j )
245 if( ntableaurowinds[j] == -1 )
247 assert(sparse == 0 || sparse == -1);
250 for( i = nrows - 1; i >= 0; --i )
251 rownorm[i] += tableaurows[j][i] * tableaurows[j][i];
255 assert(sparse == 1 || sparse == -1);
259 if( usedrowids ==
NULL )
266 for( i = ntableaurowinds[j] - 1; i >= 0; --i )
268 tableaurowind = tableaurowinds[j][i];
269 rownorm[tableaurowind] += tableaurows[j][tableaurowind] * tableaurows[j][tableaurowind];
270 if( !usedrowids[tableaurowind] )
272 usedrowids[tableaurowind] =
TRUE;
273 rowids[nrowids] = tableaurowind;
275 assert(nrowids <= nrows);
285 for( i = nrows - 1; i >= 0; --i )
290 rownorm[i] = SQRT(rownorm[i]);
301 for( j = nsubspacevars - 1; j >= 0; --j )
303 raydirection[j] += tableaurows[j][i] / (rownorm[i] * rowweight);
315 assert(usedrowids !=
NULL);
316 assert(rowids !=
NULL);
318 assert(0 <= nrowids && nrowids <= nrows);
323 for( i = nrowids - 1; i >= 0; --i )
326 assert(0 <= r && r < nrows);
327 assert(usedrowids[r]);
331 usedrowids[r] =
FALSE;
336 rownorm[r] = SQRT(rownorm[r]);
343 usedrowids[r] =
FALSE;
355 for( j = nsubspacevars - 1; j >= 0; --j )
357 for( k = ntableaurowinds[j] - 1; k >= 0; --k )
359 tableaurowind = tableaurowinds[j][k];
361 if( usedrowids[tableaurowind] )
363 raydirection[j] += tableaurows[j][tableaurowind] / (rownorm[tableaurowind] * rowweights[tableaurowind]);
374 assert(usedrowids ==
NULL);
378 for( j = 0; j < nsubspacevars; ++j )
407 assert(scip !=
NULL);
408 assert(raydirection !=
NULL);
409 assert(fracspace !=
NULL);
410 assert(subspacevars !=
NULL);
416 for( i = nsubspacevars - 1; i >= 0; --i )
423 raydirection[i] = +1.0;
425 raydirection[i] = -1.0;
427 raydirection[i] = 0.0;
431 for( i = nrows - 1; i >= 0; --i )
455 for( j = nnonz - 1; j >= 0; --j )
460 rownorm += coeffs[j] * coeffs[j];
468 rownorm = SQRT(rownorm);
471 for( j = nnonz - 1; j >= 0; --j )
481 raydirection[f] += factor * coeffs[j] / rownorm;
500 assert(scip !=
NULL);
501 assert(rayorigin !=
NULL);
502 assert(subspacevars !=
NULL);
504 for( v = nsubspacevars - 1; v >= 0; --v )
523 assert(rayorigin !=
NULL);
524 assert(raydirection !=
NULL);
525 assert(sign !=
NULL);
527 for( v = nsubspacevars - 1; v >= 0; --v )
530 if( raydirection[v] < 0 )
533 raydirection[v] *= -1.0;
534 rayorigin[v] *= -1.0;
564 assert(scip !=
NULL);
565 assert(facets !=
NULL);
566 assert(facets[i] !=
NULL);
567 assert(lambda !=
NULL);
568 assert(rayorigin !=
NULL);
569 assert(raydirection !=
NULL);
570 assert(negquotient !=
NULL);
571 assert(nfacets !=
NULL);
572 assert(0 <= i && i < f_max);
575 p = 0.5 * nsubspacevars;
577 for( j = nsubspacevars - 1; j >= 0; --j )
582 q += raydirection[j];
587 q -= raydirection[j];
593 for( j = 0; j < nsubspacevars; ++j )
603 assert(minplus >= 0);
606 assert(lambda[i] >= 0.0);
610 for( j = 0; j < nsubspacevars && !facets[i][j] &&
SCIPisFeasGT(scip, negquotient[j], lambda[i]); ++j )
614 lam = (p - 2*rayorigin[j]) / (q + 2*raydirection[j]);
615 tryToInsert(scip, facets, lambda, i, j, f_max, nsubspacevars, lam, nfacets);
621 for( j = nsubspacevars - 1; j >= 0 && facets[i][j] &&
SCIPisFeasLE(scip, negquotient[j], lambda[i]); --j )
625 lam = (p + 2*rayorigin[j]) / (q - 2*raydirection[j]);
626 if( negquotient[minplus] <= lam )
627 tryToInsert(scip, facets, lambda, i, j, f_max, nsubspacevars, lam, nfacets);
631 for( j = 1; j < f_max; j++)
647 assert(scip !=
NULL);
648 assert(raydirection !=
NULL);
650 for( v = nsubspacevars - 1; v >= 0; --v )
657 raydirection[v] = 0.0;
672 assert(heur !=
NULL);
687 assert(heur !=
NULL);
693 assert(heurdata !=
NULL);
707 assert(heur !=
NULL);
712 assert(heurdata !=
NULL);
718 heurdata->lastrule = 0;
719 heurdata->nsuccess = 0;
732 assert(heur !=
NULL);
737 assert(heurdata !=
NULL);
788 assert(heur !=
NULL);
791 assert(result !=
NULL);
813 if( nvars != nbinvars )
818 assert( heurdata !=
NULL );
833 assert( sol !=
NULL );
834 f_max = heurdata->f_max;
835 f_first = heurdata->f_first;
836 usefracspace = heurdata->usefracspace;
843 nsubspacevars = nfracvars;
846 for( i = nvars - 1; i >= 0; --i )
848 for( i = nsubspacevars - 1; i >= 0; --i )
855 nsubspacevars = nvars;
860 for( i = 0; i < nvars; ++i )
864 subspacevars[currentindex] = vars[i];
865 fracspace[i] = currentindex;
878 if( nsubspacevars == 0 )
881 assert(0 < nsubspacevars && nsubspacevars <= nvars);
883 for( i = 0; i < nsubspacevars; i++)
887 if( nsubspacevars < 30 )
891 f_max =
MIN(f_max, 1 << (nsubspacevars - 1) );
894 f_first =
MIN(f_first, f_max);
906 for( i = f_max; i >= 0; --i )
916 SCIPdebugMsg(
scip,
"run Octane heuristic on %s variables, which are %d vars, generate at most %d facets, using rule number %d\n",
917 usefracspace ?
"fractional" :
"all", nsubspacevars, f_max, (heurdata->lastrule+1)%5);
921 for( i = nsubspacevars - 1; i >= 0; --i )
924 firstrule = heurdata->lastrule;
935 if( !heurdata->useavgnbray )
941 if( !heurdata->useobjray )
947 if( !heurdata->usediffray )
970 if(
isZero(
scip, raydirection, nsubspacevars) )
974 flipCoords(rayorigin, raydirection, sign, nsubspacevars);
976 for( i = f_max - 1; i >= 0; --i)
980 p = 0.5 * nsubspacevars;
982 for( i = nsubspacevars - 1; i >= 0; --i )
987 if( rayorigin[i] < 0 )
993 negquotient[i] = - (rayorigin[i] / raydirection[i]);
1000 q += raydirection[i];
1009 for( i = 0; i < nsubspacevars; i++ )
1011 assert( raydirection[i] >= 0 );
1014 for( i = 1; i < nsubspacevars; i++ )
1015 assert( negquotient[i - 1] >= negquotient[i] );
1020 for( i = 0; i < nsubspacevars && negquotient[i] * q > p; ++i )
1022 facets[0][i] =
FALSE;
1023 p += 2 * rayorigin[i];
1024 q -= 2 * raydirection[i];
1040 for( i = 0; i < nfacets && i < f_first; ++i)
1044 for( i = 0; i < nfacets && i < f_first; ++i )
1048 assert( first_sols[i] !=
NULL );
1054 for( i = nrows - 1; i >= 0; --i )
1076 for( j = nnonzerovars - 1; j >= 0; --j )
1083 for( k =
MIN(f_first, nfacets) - 1; k > 0; --k )
1086 for( j = nnonzerovars - 1; j >= 0; --j )
1096 else if( rhs < rowval )
1099 for( k =
MIN(f_first, nfacets) - 1; k > 0; --k )
1102 for( j = nnonzerovars - 1; j >= 0; --j )
1121 for( i =
MIN(f_first, nfacets) - 1; i >= 0; --i )
1123 assert(first_sols[i] !=
NULL);
1129 for( i = f_first; i < f_max; ++i)
1142 for( i =
MIN(f_first, nfacets) - 1; i >= 0; --i )
1147 heurdata->lastrule = r;
1150 ++(heurdata->nsuccess);
1154 for( i = 0; i <= f_max; ++i )
1190 assert(heur !=
NULL);
1200 "heuristics/octane/fmax",
1201 "number of 0-1-points to be tested as possible solutions by OCTANE",
1205 "heuristics/octane/ffirst",
1206 "number of 0-1-points to be tested at first whether they violate a common row",
1210 "heuristics/octane/usefracspace",
1211 "execute OCTANE only in the space of fractional variables (TRUE) or in the full space?",
1215 "heuristics/octane/useobjray",
1216 "should the inner normal of the objective be used as one ray direction?",
1220 "heuristics/octane/useavgray",
1221 "should the average of the basic cone be used as one ray direction?",
1225 "heuristics/octane/usediffray",
1226 "should the difference between the root solution and the current LP solution be used as one ray direction?",
1230 "heuristics/octane/useavgwgtray",
1231 "should the weighted average of the basic cone be used as one ray direction?",
1235 "heuristics/octane/useavgnbray",
1236 "should the weighted average of the nonbasic cone be used as one ray direction?",
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
#define DEFAULT_USEFRACSPACE
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
void SCIPsortDownRealRealRealBoolPtr(SCIP_Real *realarray1, SCIP_Real *realarray2, SCIP_Real *realarray3, SCIP_Bool *boolarray, void **ptrarray, int len)
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
static SCIP_RETCODE generateStartingPoint(SCIP *scip, SCIP_Real *rayorigin, SCIP_VAR **subspacevars, int nsubspacevars)
static SCIP_RETCODE generateDifferenceRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars)
int SCIProwGetNNonz(SCIP_ROW *row)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_Bool isZero(SCIP *scip, SCIP_Real *raydirection, int nsubspacevars)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
SCIP_Real SCIPinfinity(SCIP *scip)
enum SCIP_Retcode SCIP_RETCODE
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)
#define SCIPfreeBufferArray(scip, ptr)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
static void flipCoords(SCIP_Real *rayorigin, SCIP_Real *raydirection, SCIP_Bool *sign, int nsubspacevars)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
const char * SCIPheurGetName(SCIP_HEUR *heur)
static SCIP_DECL_HEURCOPY(heurCopyOctane)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
static SCIP_RETCODE generateAverageRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars, SCIP_Bool weighted)
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
static SCIP_DECL_HEUREXIT(heurExitOctane)
SCIPInterval sign(const SCIPInterval &x)
SCIP_RETCODE SCIPincludeHeurOctane(SCIP *scip)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
static SCIP_DECL_HEUREXEC(heurExecOctane)
static SCIP_DECL_HEURINIT(heurInitOctane)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
static SCIP_RETCODE generateObjectiveRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
SCIP_RETCODE SCIPgetLPBInvACol(SCIP *scip, int c, SCIP_Real *coefs, int *inds, int *ninds)
#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)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
static void generateNeighborFacets(SCIP *scip, SCIP_Bool **facets, SCIP_Real *lambda, SCIP_Real *rayorigin, SCIP_Real *raydirection, SCIP_Real *negquotient, int nsubspacevars, int f_max, int i, int *nfacets)
static SCIP_RETCODE getSolFromFacet(SCIP *scip, SCIP_Bool *facet, SCIP_SOL *sol, SCIP_Bool *sign, SCIP_VAR **subspacevars, int nsubspacevars)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
#define BMScopyMemoryArray(ptr, source, num)
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
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)
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
SCIP_Real SCIPgetLPObjval(SCIP *scip)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
static SCIP_DECL_HEURFREE(heurFreeOctane)
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisStopped(SCIP *scip)
static SCIP_RETCODE generateAverageNBRay(SCIP *scip, SCIP_Real *raydirection, int *fracspace, SCIP_VAR **subspacevars, int nsubspacevars)
octane primal heuristic based on Balas, Ceria, Dawande, Margot, and Pataki
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
#define BMSclearMemoryArray(ptr, num)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
static void tryToInsert(SCIP *scip, SCIP_Bool **facets, SCIP_Real *lambda, int i, int j, int f_max, int nsubspacevars, SCIP_Real lam, int *nfacets)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
int SCIPcolGetLPPos(SCIP_COL *col)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)