22 #include "scip/cons_linear.h"
23 #include "scip/scip.h"
28 #define CONSHDLR_NAME "rowcuts"
29 #define CONSHDLR_DESC "adds row cuts generated by Couenne in a Branch-and-Check fashion"
30 #define CONSHDLR_SEPAPRIORITY 0
31 #define CONSHDLR_ENFOPRIORITY -9999999
32 #define CONSHDLR_CHECKPRIORITY -9999999
33 #define CONSHDLR_SEPAFREQ -1
34 #define CONSHDLR_PROPFREQ -1
35 #define CONSHDLR_EAGERFREQ 100
37 #define CONSHDLR_MAXPREROUNDS 0
38 #define CONSHDLR_DELAYSEPA FALSE
39 #define CONSHDLR_DELAYPROP FALSE
40 #define CONSHDLR_DELAYPRESOL FALSE
41 #define CONSHDLR_NEEDSCONS FALSE
43 #define DEFAULT_MAXCUTTINGROUNDS 5
45 using namespace Couenne;
52 struct SCIP_ConshdlrData
54 CouenneCutGenerator* cutgenerator;
55 OsiSolverInterface* milp;
67 SCIP_RETCODE checkRowcuts(
69 SCIP_CONSHDLR* conshdlr,
74 SCIP_CONSHDLRDATA* conshdlrdata;
75 CouenneProblem* problem;
83 assert(conshdlr != NULL);
84 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
85 assert(result != NULL);
88 conshdlrdata = SCIPconshdlrGetData(conshdlr);
89 assert(conshdlrdata != NULL);
92 problem = conshdlrdata->cutgenerator-> Problem ();
95 nvars = SCIPgetNVars(scip);
96 vars = SCIPgetVars(scip);
97 sol =
new SCIP_Real [nvars];
98 SCIP_CALL( SCIPgetSolVals(scip, NULL, nvars, vars, sol) );
101 conshdlrdata -> milp -> setColSolution(sol);
104 problem -> domain () -> push (problem -> nVars (), sol,
105 problem -> domain () -> current () -> lb (),
106 problem -> domain () -> current () -> ub ());
107 conshdlrdata -> cutgenerator -> genRowCuts (*(conshdlrdata->milp), cs, 0, NULL);
108 problem -> domain () -> pop ();
112 *result = (cs.sizeRowCuts() == 0) ? SCIP_FEASIBLE : SCIP_INFEASIBLE;
116 for( i = 0; i < cs.sizeRowCuts(); i++ )
118 CoinPackedVector row;
123 char consname[SCIP_MAXSTRLEN];
134 lhs = cs.rowCut(i).lb();
135 rhs = cs.rowCut(i).ub();
136 row = cs.rowCut(i).row();
139 nvals = row.getNumElements();
140 idxs = row.getIndices();
141 vals = row.getElements();
143 (
void) SCIPsnprintf(consname, SCIP_MAXSTRLEN,
"rowcut", i);
146 SCIP_CALL_ABORT( SCIPcreateConsLinear(scip, &cons, consname, 0, NULL, NULL, lhs, rhs,
147 TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
150 vars = SCIPgetVars(scip);
153 for( j = 0; j < nvals; j++ )
155 SCIP_CALL( SCIPaddCoefLinear(scip, cons, vars[idxs[j]], vals[j]) );
159 SCIP_CALL( SCIPaddCons(scip, cons) );
161 SCIP_CALL( SCIPprintCons(scip,cons,NULL) );
163 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
165 *result = SCIP_CONSADDED;
169 if (cs.sizeRowCuts ()) {
170 conshdlrdata -> milp -> applyCuts (cs);
181 #define conshdlrCopyRowcuts NULL
185 SCIP_DECL_CONSFREE(consFreeRowcuts)
187 SCIP_CONSHDLRDATA* conshdlrdata;
189 assert(conshdlr != NULL);
190 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
191 assert(scip != NULL);
194 conshdlrdata = SCIPconshdlrGetData(conshdlr);
195 assert(conshdlrdata != NULL);
198 SCIPfreeMemory(scip, &conshdlrdata);
199 SCIPconshdlrSetData(conshdlr, NULL);
205 #define consInitRowcuts NULL
208 #define consExitRowcuts NULL
211 #define consInitpreRowcuts NULL
214 #define consExitpreRowcuts NULL
217 #define consInitsolRowcuts NULL
220 #define consExitsolRowcuts NULL
223 #define consDeleteRowcuts NULL
226 #define consTransRowcuts NULL
229 #define consInitlpRowcuts NULL
232 #define consSepalpRowcuts NULL
235 #define consSepasolRowcuts NULL
239 SCIP_DECL_CONSENFOLP(consEnfolpRowcuts)
241 SCIP_CONSHDLRDATA* conshdlrdata;
243 assert(scip != NULL);
244 assert(conshdlr != NULL);
245 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
246 assert(nconss == 0 && conss == NULL);
247 assert(result != NULL);
250 conshdlrdata = SCIPconshdlrGetData(conshdlr);
251 assert(conshdlrdata != NULL);
252 if( conshdlrdata->ncuttingrounds < conshdlrdata->maxcuttingrounds )
254 SCIP_CALL( checkRowcuts(scip, conshdlr, result, TRUE) );
255 conshdlrdata->ncuttingrounds++;
259 *result = SCIP_FEASIBLE;
266 SCIP_DECL_CONSENFOPS(consEnfopsRowcuts)
268 SCIP_CONSHDLRDATA* conshdlrdata;
270 assert(scip != NULL);
271 assert(conshdlr != NULL);
272 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
273 assert(nconss == 0 && conss == NULL);
274 assert(result != NULL);
277 conshdlrdata = SCIPconshdlrGetData(conshdlr);
278 assert(conshdlrdata != NULL);
280 if( conshdlrdata->ncuttingrounds < conshdlrdata->maxcuttingrounds )
282 SCIP_CALL( checkRowcuts(scip, conshdlr, result, TRUE) );
283 conshdlrdata->ncuttingrounds++;
287 *result = SCIP_FEASIBLE;
294 SCIP_DECL_CONSCHECK(consCheckRowcuts)
296 SCIP_CONSHDLRDATA* conshdlrdata;
298 assert(scip != NULL);
299 assert(conshdlr != NULL);
300 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
301 assert(nconss == 0 && conss == NULL);
302 assert(result != NULL);
305 conshdlrdata = SCIPconshdlrGetData(conshdlr);
306 assert(conshdlrdata != NULL);
307 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && conshdlrdata->ncuttingrounds < conshdlrdata->maxcuttingrounds )
309 SCIP_CALL( checkRowcuts(scip, conshdlr, result, TRUE) );
310 conshdlrdata->ncuttingrounds++;
313 *result = SCIP_FEASIBLE;
319 #define consPropRowcuts NULL
322 #define consPresolRowcuts NULL
325 #define consRespropRowcuts NULL
329 SCIP_DECL_CONSLOCK(consLockRowcuts)
331 assert(cons == NULL);
337 #define consActiveRowcuts NULL
340 #define consDeactiveRowcuts NULL
343 #define consEnableRowcuts NULL
346 #define consDisableRowcuts NULL
349 #define consPrintRowcuts NULL
352 #define consCopyRowcuts NULL
355 #define consParseRowcuts NULL
362 SCIP_RETCODE SCIPincludeConshdlrRowcuts(
364 CouenneCutGenerator* cutgenerator,
365 OsiSolverInterface* milp
368 SCIP_CONSHDLRDATA* conshdlrdata;
371 SCIP_CALL( SCIPallocMemory(scip, &conshdlrdata) );
372 conshdlrdata->cutgenerator = cutgenerator;
373 conshdlrdata->milp = milp;
374 conshdlrdata->ncuttingrounds = 0;
376 #if SCIP_VERSION >= 400
378 SCIP_CALL( SCIPincludeConshdlr(scip, CONSHDLR_NAME, CONSHDLR_DESC,
379 CONSHDLR_SEPAPRIORITY, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY,
380 CONSHDLR_SEPAFREQ, CONSHDLR_PROPFREQ, CONSHDLR_EAGERFREQ, CONSHDLR_MAXPREROUNDS,
381 CONSHDLR_DELAYSEPA, CONSHDLR_DELAYPROP, CONSHDLR_NEEDSCONS,
382 SCIP_PROPTIMING_BEFORELP, SCIP_PRESOLTIMING_NONE,
384 consFreeRowcuts, consInitRowcuts, consExitRowcuts,
385 consInitpreRowcuts, consExitpreRowcuts, consInitsolRowcuts, consExitsolRowcuts,
386 consDeleteRowcuts, consTransRowcuts, consInitlpRowcuts,
387 consSepalpRowcuts, consSepasolRowcuts, consEnfolpRowcuts, NULL, consEnfopsRowcuts, consCheckRowcuts,
388 consPropRowcuts, consPresolRowcuts, consRespropRowcuts, consLockRowcuts,
389 consActiveRowcuts, consDeactiveRowcuts,
390 consEnableRowcuts, consDisableRowcuts, NULL,
391 consPrintRowcuts, consCopyRowcuts, consParseRowcuts, NULL, NULL, NULL,
393 #elif SCIP_VERSION >= 320
395 SCIP_CALL( SCIPincludeConshdlr(scip, CONSHDLR_NAME, CONSHDLR_DESC,
396 CONSHDLR_SEPAPRIORITY, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY,
397 CONSHDLR_SEPAFREQ, CONSHDLR_PROPFREQ, CONSHDLR_EAGERFREQ, CONSHDLR_MAXPREROUNDS,
398 CONSHDLR_DELAYSEPA, CONSHDLR_DELAYPROP, CONSHDLR_NEEDSCONS,
399 SCIP_PROPTIMING_BEFORELP, SCIP_PRESOLTIMING_NONE,
401 consFreeRowcuts, consInitRowcuts, consExitRowcuts,
402 consInitpreRowcuts, consExitpreRowcuts, consInitsolRowcuts, consExitsolRowcuts,
403 consDeleteRowcuts, consTransRowcuts, consInitlpRowcuts,
404 consSepalpRowcuts, consSepasolRowcuts, consEnfolpRowcuts, consEnfopsRowcuts, consCheckRowcuts,
405 consPropRowcuts, consPresolRowcuts, consRespropRowcuts, consLockRowcuts,
406 consActiveRowcuts, consDeactiveRowcuts,
407 consEnableRowcuts, consDisableRowcuts, NULL,
408 consPrintRowcuts, consCopyRowcuts, consParseRowcuts, NULL, NULL, NULL,
410 #elif SCIP_VERSION >= 300
412 SCIP_CALL( SCIPincludeConshdlr(scip, CONSHDLR_NAME, CONSHDLR_DESC,
413 CONSHDLR_SEPAPRIORITY, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY,
414 CONSHDLR_SEPAFREQ, CONSHDLR_PROPFREQ, CONSHDLR_EAGERFREQ, CONSHDLR_MAXPREROUNDS,
415 CONSHDLR_DELAYSEPA, CONSHDLR_DELAYPROP, CONSHDLR_DELAYPRESOL, CONSHDLR_NEEDSCONS,
416 SCIP_PROPTIMING_BEFORELP,
418 consFreeRowcuts, consInitRowcuts, consExitRowcuts,
419 consInitpreRowcuts, consExitpreRowcuts, consInitsolRowcuts, consExitsolRowcuts,
420 consDeleteRowcuts, consTransRowcuts, consInitlpRowcuts,
421 consSepalpRowcuts, consSepasolRowcuts, consEnfolpRowcuts, consEnfopsRowcuts, consCheckRowcuts,
422 consPropRowcuts, consPresolRowcuts, consRespropRowcuts, consLockRowcuts,
423 consActiveRowcuts, consDeactiveRowcuts,
424 consEnableRowcuts, consDisableRowcuts, NULL,
425 consPrintRowcuts, consCopyRowcuts, consParseRowcuts, NULL, NULL,
427 #elif SCIP_VERSION >= 210
429 SCIP_CALL( SCIPincludeConshdlr(scip, CONSHDLR_NAME, CONSHDLR_DESC,
430 CONSHDLR_SEPAPRIORITY, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY,
431 CONSHDLR_SEPAFREQ, CONSHDLR_PROPFREQ, CONSHDLR_EAGERFREQ, CONSHDLR_MAXPREROUNDS,
432 CONSHDLR_DELAYSEPA, CONSHDLR_DELAYPROP, CONSHDLR_DELAYPRESOL, CONSHDLR_NEEDSCONS,
433 SCIP_PROPTIMING_BEFORELP,
435 consFreeRowcuts, consInitRowcuts, consExitRowcuts,
436 consInitpreRowcuts, consExitpreRowcuts, consInitsolRowcuts, consExitsolRowcuts,
437 consDeleteRowcuts, consTransRowcuts, consInitlpRowcuts,
438 consSepalpRowcuts, consSepasolRowcuts, consEnfolpRowcuts, consEnfopsRowcuts, consCheckRowcuts,
439 consPropRowcuts, consPresolRowcuts, consRespropRowcuts, consLockRowcuts,
440 consActiveRowcuts, consDeactiveRowcuts,
441 consEnableRowcuts, consDisableRowcuts, NULL,
442 consPrintRowcuts, consCopyRowcuts, consParseRowcuts,
446 SCIP_CALL( SCIPincludeConshdlr(scip, CONSHDLR_NAME, CONSHDLR_DESC,
447 CONSHDLR_SEPAPRIORITY, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY,
448 CONSHDLR_SEPAFREQ, CONSHDLR_PROPFREQ, CONSHDLR_EAGERFREQ, CONSHDLR_MAXPREROUNDS,
449 CONSHDLR_DELAYSEPA, CONSHDLR_DELAYPROP, CONSHDLR_DELAYPRESOL, CONSHDLR_NEEDSCONS,
451 consFreeRowcuts, consInitRowcuts, consExitRowcuts,
452 consInitpreRowcuts, consExitpreRowcuts, consInitsolRowcuts, consExitsolRowcuts,
453 consDeleteRowcuts, consTransRowcuts, consInitlpRowcuts,
454 consSepalpRowcuts, consSepasolRowcuts, consEnfolpRowcuts, consEnfopsRowcuts, consCheckRowcuts,
455 consPropRowcuts, consPresolRowcuts, consRespropRowcuts, consLockRowcuts,
456 consActiveRowcuts, consDeactiveRowcuts,
457 consEnableRowcuts, consDisableRowcuts,
458 consPrintRowcuts, consCopyRowcuts, consParseRowcuts,
463 SCIP_CALL( SCIPaddIntParam(scip,
464 "constraints/" CONSHDLR_NAME
"/maxcuttingrounds",
465 "how many rounds of cuts should be applied at most?",
466 &conshdlrdata->maxcuttingrounds, FALSE, DEFAULT_MAXCUTTINGROUNDS, -1, INT_MAX, NULL, NULL) );
constraint handler for rowcuts constraints enables separation of convexification cuts during SCIP sol...