49 #define HEUR_NAME "sdpfracround" 50 #define HEUR_DESC "fractional rounding heuristic for SDPs" 51 #define HEUR_DISPCHAR '^' 52 #define HEUR_PRIORITY -1000500 54 #define HEUR_FREQOFS 0 55 #define HEUR_MAXDEPTH -1 56 #define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE 57 #define HEUR_USESSUBSCIP FALSE 64 #define DEFAULT_RUNFORLP FALSE 82 assert( scip != NULL );
83 assert( heur != NULL );
84 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
96 SCIP_HEURDATA* heurdata;
98 assert( heur != NULL );
99 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
100 assert( scip != NULL );
103 heurdata = SCIPheurGetData(heur);
104 assert(heurdata != NULL);
106 SCIPfreeBlockMemory(scip, &heurdata);
107 SCIPheurSetData(heur, NULL);
116 SCIP_HEURDATA* heurdata;
118 assert( heur != NULL );
119 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
122 heurdata = SCIPheurGetData(heur);
123 assert( heurdata != NULL );
126 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
135 SCIP_HEURDATA* heurdata;
137 assert( heur != NULL );
138 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
141 heurdata = SCIPheurGetData(heur);
142 assert( heurdata != NULL );
145 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
154 SCIP_HEURDATA* heurdata;
155 SCIP_CONSHDLR* conshdlrsdp;
156 SCIP_RELAX* relaxsdp;
157 SCIP_Real* sdpcandssol;
158 SCIP_Real* sdpcandsfrac;
161 SCIP_SOL* relaxsol = NULL;
162 SCIP_Bool usesdp = TRUE;
163 SCIP_Bool cutoff = FALSE;
172 assert( heur != NULL );
173 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
174 assert( scip != NULL );
175 assert( result != NULL );
177 *result = SCIP_DELAYED;
180 if ( nodeinfeasible )
183 *result = SCIP_DIDNOTRUN;
186 heurdata = SCIPheurGetData(heur);
187 assert( heurdata != NULL );
190 if ( ! SCIPisRelaxSolValid(scip) )
193 if ( ! heurdata->runforlp )
197 if ( SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
201 if ( SCIPgetSubscipDepth(scip) > 0 )
208 relaxsdp = SCIPfindRelax(scip,
"SDP");
209 if ( relaxsdp == NULL )
212 conshdlrsdp = SCIPfindConshdlr(scip,
"SDP");
213 if ( conshdlrsdp == NULL )
217 if ( SCIPconshdlrGetNConss(conshdlrsdp) <= 0 )
221 ncontvars = SCIPgetNContVars(scip) + SCIPgetNImplVars(scip);
226 SCIP_CALL( SCIPcreateRelaxSol(scip, &relaxsol, heur) );
230 SCIP_CALL( SCIPstartProbing(scip) );
233 vars = SCIPgetVars(scip);
234 nvars = SCIPgetNVars(scip);
235 SCIP_CALL( SCIPallocBufferArray(scip, &sdpcands, nvars) );
236 SCIP_CALL( SCIPallocBufferArray(scip, &sdpcandssol, nvars) );
237 SCIP_CALL( SCIPallocBufferArray(scip, &sdpcandsfrac, nvars) );
240 SCIP_CALL( SCIPlinkRelaxSol(scip, heurdata->sol) );
243 for (v = 0; v < nvars; ++v)
249 if ( SCIPvarIsIntegral(var) )
251 val = SCIPgetSolVal(scip, relaxsol, var);
252 if ( ! SCIPisFeasIntegral(scip, val) )
254 sdpcandssol[nsdpcands] = val;
255 sdpcandsfrac[nsdpcands] = SCIPfeasFrac(scip, val);
256 sdpcands[nsdpcands++] = var;
261 val = SCIPfeasRound(scip, val);
264 if ( SCIPisGT(scip, val, SCIPvarGetLbLocal(var)) )
266 SCIP_CALL( SCIPchgVarLbProbing(scip, var, val) );
269 if ( SCIPisLT(scip, val, SCIPvarGetUbLocal(var)) )
271 SCIP_CALL( SCIPchgVarUbProbing(scip, var, val) );
276 SCIP_CALL( SCIPsetSolVal(scip, heurdata->sol, var, val) );
282 if ( relaxsol != NULL )
284 SCIP_CALL( SCIPfreeSol(scip, &relaxsol) );
288 if ( nsdpcands == 0 )
290 SCIP_CALL( SCIPendProbing(scip) );
292 SCIPfreeBufferArray(scip, &sdpcandsfrac);
293 SCIPfreeBufferArray(scip, &sdpcandssol);
294 SCIPfreeBufferArray(scip, &sdpcands);
299 *result = SCIP_DIDNOTFIND;
301 SCIPdebugMsg(scip,
"Node %"SCIP_LONGINT_FORMAT
": executing SDP fractional rounding heuristic (depth %d, %d fractionals).\n",
302 SCIPgetNNodes(scip), SCIPgetDepth(scip), nsdpcands);
303 SCIPdebugMsg(scip,
"Fixed %d bounds of variables with integral values.\n", nfixed);
308 freq = SCIPrelaxGetFreq(relaxsdp);
309 SCIP_CALL( SCIPsetIntParam(scip,
"relaxing/SDP/freq", 1) );
313 SCIPsortRealRealPtr(sdpcandsfrac, sdpcandssol, (
void*) sdpcands, nsdpcands);
317 for (v = 0; v < nsdpcands && ! cutoff; ++v)
319 SCIP_Longint ndomreds;
332 val = sdpcandssol[v];
333 lb = SCIPvarGetLbLocal(var);
334 ub = SCIPvarGetUbLocal(var);
336 assert( SCIPvarIsIntegral(var) );
337 assert( ! SCIPisFeasIntegral(scip, val) );
339 ceilval = SCIPfeasCeil(scip, val);
340 floorval = SCIPfeasFloor(scip, val);
344 if ( lb > ceilval + 0.5 || ub < floorval - 0.5 )
349 else if ( SCIPisFeasEQ(scip, lb, ceilval) )
351 else if ( SCIPisFeasEQ(scip, ub, floorval) )
355 newval = SCIPfeasRound(scip, val);
359 lbadjust = SCIPisGT(scip, newval, lb);
360 ubadjust = SCIPisLT(scip, newval, ub);
362 if ( lbadjust || ubadjust )
364 SCIP_CALL( SCIPnewProbingNode(scip) );
369 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newval) );
374 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newval) );
379 SCIP_CALL( SCIPpropagateProbing(scip, 1, &cutoff, &ndomreds) );
385 SCIP_CALL( SCIPsetSolVal(scip, heurdata->sol, var, newval) );
394 SCIPdebugMsg(scip,
"Rounded %d variables.\n", nrounded);
397 if ( ncontvars == 0 )
401 for (v = 0; v < nvars; ++v)
402 assert( ! SCIPvarIsIntegral(vars[v]) || SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, heurdata->sol, vars[v])) );
406 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
410 SCIPdebugMsg(scip,
"Found solution for full integral instance.\n");
411 *result = SCIP_FOUNDSOL;
414 SCIPdebugMsg(scip,
"Solution not feasible for full integral instance.\n");
416 else if ( nfixed > 0 )
419 SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
427 SCIP_CALL( SCIPlinkRelaxSol(scip, heurdata->sol) );
430 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
435 SCIPdebugMsg(scip,
"Solution was feasible and good enough.\n");
436 *result = SCIP_FOUNDSOL;
439 SCIPdebugMsg(scip,
"Solution was not feasible.\n");
442 SCIPdebugMsg(scip,
"Problem was infeasible.\n");
446 SCIPdebugMsg(scip,
"No fixings have been performed.\n");
449 SCIPdebugMsg(scip,
"Reached cutoff after %d roundings.\n", nrounded);
452 SCIP_CALL( SCIPendProbing(scip) );
457 SCIP_CALL( SCIPsetIntParam(scip,
"relaxing/SDP/freq", freq) );
460 SCIPfreeBufferArray(scip, &sdpcandsfrac);
461 SCIPfreeBufferArray(scip, &sdpcandssol);
462 SCIPfreeBufferArray(scip, &sdpcands);
464 SCIPdebugMsg(scip,
"Finished fractional rounding heuristic.\n");
479 SCIP_HEURDATA* heurdata;
483 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
486 SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
490 assert( heur != NULL );
493 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopySdpfracround) );
494 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSdpfracround) );
495 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitSdpfracround) );
496 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSdpfracround) );
499 SCIP_CALL( SCIPaddBoolParam(scip,
500 "heuristics/sdpfracround/runforlp",
501 "Should fractional rounding be applied if we are solving LPs?",
static SCIP_DECL_HEUREXIT(heurExitSdpfracround)
static SCIP_DECL_HEURCOPY(heurCopySdpfracround)
fractional rounding heuristic for SDPs
static SCIP_DECL_HEURINIT(heurInitSdpfracround)
SCIP_Bool SCIPrelaxSdpSolvedProbing(SCIP_RELAX *relax)
SCIP_Bool SCIPrelaxSdpIsFeasible(SCIP_RELAX *relax)
static SCIP_DECL_HEUREXEC(heurExecSdpfracround)
SCIP_RETCODE SCIPincludeHeurSdpFracround(SCIP *scip)
static SCIP_DECL_HEURFREE(heurFreeSdpfracround)