50 #define HEUR_NAME "sdprand" 51 #define HEUR_DESC "randomized rounding heuristic for SDPs" 52 #define HEUR_DISPCHAR '~' 53 #define HEUR_PRIORITY -1001000 55 #define HEUR_FREQOFS 0 56 #define HEUR_MAXDEPTH -1 57 #define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE 58 #define HEUR_USESSUBSCIP FALSE 65 #define DEFAULT_RANDSEED 211 66 #define DEFAULT_RUNFORLP FALSE 72 SCIP_RANDNUMGEN* randnumgen;
85 assert( scip != NULL );
86 assert( heur != NULL );
87 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
99 SCIP_HEURDATA* heurdata;
101 assert( heur != NULL );
102 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
103 assert( scip != NULL );
106 heurdata = SCIPheurGetData(heur);
107 assert(heurdata != NULL);
109 SCIPfreeBlockMemory(scip, &heurdata);
110 SCIPheurSetData(heur, NULL);
119 SCIP_HEURDATA* heurdata;
121 assert( heur != NULL );
122 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
125 heurdata = SCIPheurGetData(heur);
126 assert( heurdata != NULL );
129 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
130 SCIP_CALL( SCIPcreateRandom(scip, &(heurdata->randnumgen), SCIPinitializeRandomSeed(scip,
DEFAULT_RANDSEED), TRUE) );
139 SCIP_HEURDATA* heurdata;
141 assert( heur != NULL );
142 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
145 heurdata = SCIPheurGetData(heur);
146 assert( heurdata != NULL );
149 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
150 SCIPfreeRandom(scip, &(heurdata->randnumgen));
159 SCIP_HEURDATA* heurdata;
160 SCIP_CONSHDLR* conshdlrsdp;
161 SCIP_RELAX* relaxsdp;
162 SCIP_Real* sdpcandssol;
164 SCIP_SOL* relaxsol = NULL;
165 SCIP_Bool usesdp = TRUE;
166 SCIP_Bool cutoff = FALSE;
176 assert( heur != NULL );
177 assert( strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0 );
178 assert( scip != NULL );
179 assert( result != NULL );
181 *result = SCIP_DELAYED;
184 if ( nodeinfeasible )
187 *result = SCIP_DIDNOTRUN;
190 heurdata = SCIPheurGetData(heur);
191 assert( heurdata != NULL );
194 if ( ! SCIPisRelaxSolValid(scip) )
197 if ( ! heurdata->runforlp )
201 if ( SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
205 if ( SCIPgetSubscipDepth(scip) > 0 )
212 relaxsdp = SCIPfindRelax(scip,
"SDP");
213 if ( relaxsdp == NULL )
216 conshdlrsdp = SCIPfindConshdlr(scip,
"SDP");
217 if ( conshdlrsdp == NULL )
221 if ( SCIPconshdlrGetNConss(conshdlrsdp) <= 0 )
225 ncontvars = SCIPgetNContVars(scip) + SCIPgetNImplVars(scip);
230 SCIP_CALL( SCIPcreateRelaxSol(scip, &relaxsol, heur) );
234 SCIP_CALL( SCIPstartProbing(scip) );
237 vars = SCIPgetVars(scip);
238 nvars = SCIPgetNVars(scip);
239 SCIP_CALL( SCIPallocBufferArray(scip, &sdpcands, nvars) );
240 SCIP_CALL( SCIPallocBufferArray(scip, &sdpcandssol, nvars) );
243 SCIP_CALL( SCIPlinkRelaxSol(scip, heurdata->sol) );
246 for (v = 0; v < nvars; ++v)
252 val = SCIPgetSolVal(scip, relaxsol, var);
253 sdpcandssol[v] = val;
254 if ( SCIPvarIsIntegral(var) )
256 if ( ! SCIPisFeasIntegral(scip, val) )
257 sdpcands[nsdpcands++] = v;
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, &sdpcandssol);
293 SCIPfreeBufferArray(scip, &sdpcands);
298 *result = SCIP_DIDNOTFIND;
300 SCIPdebugMsg(scip,
"Node %"SCIP_LONGINT_FORMAT
": executing SDP randomized rounding heuristic (depth %d, %d fractionals).\n",
301 SCIPgetNNodes(scip), SCIPgetDepth(scip), nsdpcands);
302 SCIPdebugMsg(scip,
"Fixed %d bounds of variables with integral values.\n", nfixed);
307 freq = SCIPrelaxGetFreq(relaxsdp);
308 SCIP_CALL( SCIPsetIntParam(scip,
"relaxing/SDP/freq", 1) );
312 SCIPrandomPermuteIntArray(heurdata->randnumgen, sdpcands, 0, nsdpcands);
316 for (v = 0; v < nsdpcands && ! cutoff; ++v)
318 SCIP_Longint ndomreds;
331 assert( 0 <= sdpcands[v] && sdpcands[v] < nvars );
332 var = vars[sdpcands[v]];
333 val = sdpcandssol[sdpcands[v]];
334 lb = SCIPvarGetLbLocal(var);
335 ub = SCIPvarGetUbLocal(var);
337 assert( SCIPvarIsIntegral(var) );
338 assert( ! SCIPisFeasIntegral(scip, val) );
340 ceilval = SCIPfeasCeil(scip, val);
341 floorval = SCIPfeasFloor(scip, val);
345 if ( lb > ceilval + 0.5 || ub < floorval - 0.5 )
350 else if ( SCIPisFeasEQ(scip, lb, ceilval) )
352 else if ( SCIPisFeasEQ(scip, ub, floorval) )
357 r = SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0);
360 if ( SCIPfeasFrac(scip, val) <= r )
368 lbadjust = SCIPisGT(scip, newval, lb);
369 ubadjust = SCIPisLT(scip, newval, ub);
371 if ( lbadjust || ubadjust )
373 SCIP_CALL( SCIPnewProbingNode(scip) );
378 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newval) );
383 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newval) );
388 SCIP_CALL( SCIPpropagateProbing(scip, 1, &cutoff, &ndomreds) );
394 SCIP_CALL( SCIPsetSolVal(scip, heurdata->sol, var, newval) );
403 SCIPdebugMsg(scip,
"Rounded %d variables.\n", nrounded);
406 if ( ncontvars == 0 )
410 for (v = 0; v < nvars; ++v)
411 assert( ! SCIPvarIsIntegral(vars[v]) || SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, heurdata->sol, vars[v])) );
415 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
419 SCIPdebugMsg(scip,
"Found solution for full integral instance.\n");
420 *result = SCIP_FOUNDSOL;
423 SCIPdebugMsg(scip,
"Solution not feasible for full integral instance.\n");
425 else if ( nfixed > 0 )
428 SCIP_CALL( SCIPsolveProbingRelax(scip, &cutoff) );
436 SCIP_CALL( SCIPlinkRelaxSol(scip, heurdata->sol) );
439 SCIP_CALL( SCIPtrySol(scip, heurdata->sol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
444 SCIPdebugMsg(scip,
"Solution was feasible and good enough.\n");
445 *result = SCIP_FOUNDSOL;
448 SCIPdebugMsg(scip,
"Solution was not feasible.\n");
451 SCIPdebugMsg(scip,
"Problem was infeasible.\n");
455 SCIPdebugMsg(scip,
"No fixings have been performed.\n");
458 SCIPdebugMsg(scip,
"Reached cutoff after %d roundings.\n", nrounded);
461 SCIP_CALL( SCIPendProbing(scip) );
466 SCIP_CALL( SCIPsetIntParam(scip,
"relaxing/SDP/freq", freq) );
469 SCIPfreeBufferArray(scip, &sdpcandssol);
470 SCIPfreeBufferArray(scip, &sdpcands);
472 SCIPdebugMsg(scip,
"Finished randomized rounding heuristic.\n");
487 SCIP_HEURDATA* heurdata;
491 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
494 SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
498 assert( heur != NULL );
501 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopySdprand) );
502 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSdprand) );
503 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitSdprand) );
504 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSdprand) );
507 SCIP_CALL( SCIPaddBoolParam(scip,
508 "heuristics/sdprand/runforlp",
509 "Should randomized rounding be applied if we are solving LPs?",
static SCIP_DECL_HEUREXEC(heurExecSdprand)
static SCIP_DECL_HEURFREE(heurFreeSdprand)
SCIP_RETCODE SCIPincludeHeurSdpRand(SCIP *scip)
SCIP_Bool SCIPrelaxSdpSolvedProbing(SCIP_RELAX *relax)
static SCIP_DECL_HEURINIT(heurInitSdprand)
randomized rounding heuristic for SDPs
static SCIP_DECL_HEURCOPY(heurCopySdprand)
static SCIP_DECL_HEUREXIT(heurExitSdprand)
SCIP_Bool SCIPrelaxSdpIsFeasible(SCIP_RELAX *relax)