SCIP Doxygen Documentation
Loading...
Searching...
No Matches
cons_integral.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file cons_integral.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief constraint handler for the integrality constraint
28 * @author Tobias Achterberg
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
33#include "scip/cons_integral.h"
34#include "scip/pub_cons.h"
35#include "scip/pub_message.h"
36#include "scip/pub_var.h"
37#include "scip/pub_sol.h"
38#include "scip/scip_branch.h"
39#include "scip/scip_cons.h"
40#include "scip/scip_exact.h"
41#include "scip/scip_lp.h"
42#include "scip/scip_lpexact.h"
43#include "scip/scip_message.h"
44#include "scip/scip_numerics.h"
45#include "scip/scip_prob.h"
46#include "scip/scip_probing.h"
47#include "scip/scip_sol.h"
48#include "scip/scip_mem.h"
49#include "scip/rational.h"
50
51
52#define CONSHDLR_NAME "integral"
53#define CONSHDLR_DESC "integrality constraint"
54#define CONSHDLR_ENFOPRIORITY 0 /**< priority of the constraint handler for constraint enforcing */
55#define CONSHDLR_CHECKPRIORITY 0 /**< priority of the constraint handler for checking feasibility */
56#define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
57 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
58#define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
59
60
61/** checks whether primal solution satisfies all integrality restrictions without tolerances */
62static
64 SCIP* scip, /**< SCIP data structure */
65 SCIP_SOL* sol, /**< solution to be checked */
66 SCIP_Bool printreason, /**< should infeasisibility reason be printed? */
67 SCIP_RESULT* result /**< pointer to store the result of the lp enforcement call */
68 )
69{
70 SCIP_RATIONAL* solval;
71 SCIP_Bool integral;
72 SCIP_VAR** vars;
73 int nintegers;
74 int ncontimplvars;
75 int ncontvars;
76 int v;
77
78 assert(result != NULL);
79
80 SCIPdebugMessage("checking exact integrality of primal solution:\n");
81
82 integral = TRUE;
83
85
86 /* get all problem variables and integer region in vars array */
87 SCIP_CALL( SCIPgetSolVarsData(scip, sol, &vars, &nintegers, NULL, NULL, NULL, NULL, &ncontimplvars, &ncontvars) );
88 nintegers -= ncontimplvars + ncontvars;
89 assert(nintegers >= 0);
90
91 /* check whether primal solution satisfies all integrality restrictions */
92 for( v = 0; v < nintegers && integral; ++v )
93 {
94 /* if the solution is exact we check the exact data, otherwise we check the fp data */
95 if( SCIPsolIsExact(sol) )
96 SCIPgetSolValExact(scip, sol, vars[v], solval);
97 else
99
102
103 if( !SCIPrationalIsIntegral(solval) )
104 {
106 if( printreason )
107 {
108 SCIPinfoMessage(scip, NULL, "violation: integrality condition of variable <%s> =",
109 SCIPvarGetName(vars[v]));
111 SCIPinfoMessage(scip, NULL, "\n");
112 }
113 integral = FALSE;
114 }
115 }
116
118
119 return SCIP_OKAY;
120}
121
122/*
123 * Callback methods
124 */
125
126/** copy method for constraint handler plugins (called when SCIP copies plugins) */
127static
128SCIP_DECL_CONSHDLRCOPY(conshdlrCopyIntegral)
129{ /*lint --e{715}*/
130 assert(scip != NULL);
131 assert(conshdlr != NULL);
132
134
135 /* call inclusion method of constraint handler */
137
138 *valid = TRUE;
139
140 return SCIP_OKAY;
141}
142
143#define consCopyIntegral NULL
144
145#define consEnfopsIntegral NULL
146
147/** constraint enforcing method of constraint handler for LP solutions */
148static
149SCIP_DECL_CONSENFOLP(consEnfolpIntegral)
150{ /*lint --e{715}*/
151 assert(conshdlr != NULL);
152 assert(scip != NULL);
153 assert(conss == NULL);
154 assert(nconss == 0);
155 assert(result != NULL);
156
158
159 SCIPdebugMsg(scip, "Enfolp method of integrality constraint: %d fractional variables\n", SCIPgetNLPBranchCands(scip));
160
162
163 /* if the root LP is unbounded, we want to terminate with UNBOUNDED or INFORUNBOUNDED,
164 * depending on whether we are able to construct an integral solution; in any case we do not want to branch
165 */
167 {
168 if( SCIPgetNLPBranchCands(scip) == 0 )
170 else
172 return SCIP_OKAY;
173 }
174
175 /* call branching methods */
177
179 {
181 }
182
183 /* if no branching was done, the LP solution was not fractional */
184 if( *result == SCIP_DIDNOTRUN )
186
187 return SCIP_OKAY;
188}
189
190/** constraint enforcing method of constraint handler for relaxation solutions */
191static
192SCIP_DECL_CONSENFORELAX(consEnforelaxIntegral)
193{ /*lint --e{715}*/
194 SCIP_VAR** vars;
195 int nbinvars;
196 int nintvars;
197 int i;
198
199 assert(conshdlr != NULL);
200 assert(scip != NULL);
201 assert(conss == NULL);
202 assert(nconss == 0);
203 assert(result != NULL);
204
206
207 SCIPdebugMsg(scip, "Enforelax method of integrality constraint\n");
208
210
211 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
212
213 int nintegers = nbinvars + nintvars + SCIPgetNBinImplVars(scip) + SCIPgetNIntImplVars(scip);
214
215 for( i = 0; i < nintegers; ++i )
216 {
217 assert(vars[i] != NULL);
219
221 {
223 {
224 SCIPdebugMsg(scip, "Cutoff for integral variable %s with bounds [%f, %f] and value %f\n", SCIPvarGetName(vars[i]),
227 return SCIP_OKAY;
228 }
229 else
230 {
231 /* @todo better way to handle this would be a BRANCHEXECRELAX callback that could also implement pseudo costs for
232 * relaxation solutions instead of using the enforelaxcallback which is mainly intended for spatial branching
233 */
236 }
237 }
238 }
239
240 /* if we have found a branching candidate, immediately branch to be able to return SCIP_BRANCHED and stop the
241 * enforcement loop
242 */
243 if( *result == SCIP_INFEASIBLE )
244 {
245 /* call branching methods for external candidates */
247
248 /* since we only call it if we added external candidates, the branching rule should always be able to branch */
250 }
251
252 return SCIP_OKAY;
253}
254
255/** feasibility check method of constraint handler for integral solutions */
256static
257SCIP_DECL_CONSCHECK(consCheckIntegral)
258{ /*lint --e{715}*/
259 SCIP_VAR** vars;
260 SCIP_Real solval;
261 int nintegers;
262 int ncontimplvars;
263 int ncontvars;
264 int v;
265
266 assert(scip != NULL);
267 assert(sol != NULL);
268
270
271 SCIPdebugMsg(scip, "Check method of integrality constraint (checkintegrality=%u)\n", checkintegrality);
272
274
275 if( !checkintegrality )
276 return SCIP_OKAY;
277
278 SCIP_CALL( SCIPgetSolVarsData(scip, sol, &vars, &nintegers, NULL, NULL, NULL, NULL, &ncontimplvars, &ncontvars) );
279 nintegers -= ncontimplvars + ncontvars;
280 assert(nintegers >= 0);
281
282 if( !SCIPisExact(scip) )
283 {
284 for( v = 0; v < nintegers; ++v )
285 {
286 solval = SCIPgetSolVal(scip, sol, vars[v]);
287
288 if( sol != NULL )
290
291 if( !SCIPisFeasIntegral(scip, solval) )
292 {
294
295 if( printreason )
296 {
297 SCIPinfoMessage(scip, NULL, "violation: integrality condition of variable <%s> = %.15g\n",
298 SCIPvarGetName(vars[v]), solval);
299 }
300 if( !completely )
301 break;
302 }
303 }
304 }
305 /* in exact solving mode, we have to check integrality without tolerances */
306 else
307 {
308 SCIP_CALL( checkIntegralityExact(scip, sol, printreason, result) );
309 }
310
311 return SCIP_OKAY;
312}
313
314/** variable rounding lock method of constraint handler */
315static
316SCIP_DECL_CONSLOCK(consLockIntegral)
317{ /*lint --e{715}*/
318 return SCIP_OKAY;
319}
320
321/** constraint handler method to suggest dive bound changes during the generic diving algorithm */
322static
323SCIP_DECL_CONSGETDIVEBDCHGS(consGetDiveBdChgsIntegral)
324{ /*lint --e{715}*/
325 SCIP_VAR** vars;
326 SCIP_Real solval;
327 SCIP_Real score;
328 SCIP_Real bestscore;
329 SCIP_Bool bestroundup;
330 int nintegers;
331 int ncontvars;
332 int nbinimplvars;
333 int nintimplvars;
334 int ncontimplvars;
335 int bestcandidx;
336 int v;
337
338 assert(scip != NULL);
339 assert(diveset != NULL);
340 assert(sol != NULL);
341
343
344 SCIPdebugMsg(scip, "integral constraint handler: determine diving bound changes\n");
345
347 &nbinimplvars, &nintimplvars, &ncontimplvars, &ncontvars) );
348 nintegers = nintegers - nbinimplvars - nintimplvars - ncontimplvars - ncontvars;
349 assert(nintegers >= 0);
350
351 bestscore = SCIP_REAL_MIN;
352 bestcandidx = -1;
353 *success = FALSE;
354 bestroundup = FALSE; /* only for lint */
355
356 /* loop over solution values and get score of fractional variables */
357 for( v = 0; v < nintegers; ++v )
358 {
359 solval = SCIPgetSolVal(scip, sol, vars[v]);
360
361 /* skip variable if solution value disagrees with the local bounds */
362 if( ! SCIPisFeasIntegral(scip, solval) && SCIPisGE(scip, solval, SCIPvarGetLbLocal(vars[v])) && SCIPisLE(scip, solval, SCIPvarGetUbLocal(vars[v])) )
363 {
365
367 solval - SCIPfloor(scip, solval), &score, &roundup) );
368
369 /* we search for candidates with maximum score */
370 if( score > bestscore )
371 {
372 bestcandidx = v;
373 bestscore = score;
374 bestroundup = roundup;
375 *success = TRUE;
376 }
377 }
378 }
379
380 assert(!(*success) || bestcandidx >= 0);
381
382 if( *success )
383 {
384 solval = SCIPgetSolVal(scip, sol, vars[bestcandidx]);
385
386 /* if we want to round up the best candidate, it is added as the preferred bound change */
388 SCIPceil(scip, solval), bestroundup) );
390 SCIPfloor(scip, solval), ! bestroundup) );
391 }
392
393 return SCIP_OKAY;
394}
395
396/*
397 * constraint specific interface methods
398 */
399
400/** creates the handler for integrality constraint and includes it in SCIP */
402 SCIP* scip /**< SCIP data structure */
403 )
404{
405 SCIP_CONSHDLR* conshdlr;
406
407 /* include constraint handler */
410 consEnfolpIntegral, consEnfopsIntegral, consCheckIntegral, consLockIntegral, NULL) );
411
412 assert(conshdlr != NULL);
413
414 /* mark constraint handler as exact */
415 SCIPconshdlrMarkExact(conshdlr);
416
417 /* set non-fundamental callbacks via specific setter functions */
418 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyIntegral, consCopyIntegral) );
419 SCIP_CALL( SCIPsetConshdlrGetDiveBdChgs(scip, conshdlr, consGetDiveBdChgsIntegral) );
420 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxIntegral) );
421
422 return SCIP_OKAY;
423}
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:96
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:88
#define CONSHDLR_DESC
Definition cons_and.c:85
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:91
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:87
#define CONSHDLR_NAME
Definition cons_and.c:84
#define consCopyIntegral
static SCIP_RETCODE checkIntegralityExact(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_RESULT *result)
#define consEnfopsIntegral
constraint handler for the integrality constraint
#define NULL
Definition def.h:257
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define EPSFRAC(x, eps)
Definition def.h:203
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_REAL_MIN
Definition def.h:168
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPincludeConshdlrIntegral(SCIP *scip)
SCIP_RETCODE SCIPgetSolVarsData(SCIP *scip, SCIP_SOL *sol, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nbinimplvars, int *nintimplvars, int *ncontimplvars, int *ncontvars)
Definition scip_prob.c:3114
int SCIPgetNBinImplVars(SCIP *scip)
Definition scip_prob.c:2432
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
int SCIPgetNIntImplVars(SCIP *scip)
Definition scip_prob.c:2477
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
#define SCIPdebugMsg
SCIP_RETCODE SCIPaddExternBranchCand(SCIP *scip, SCIP_VAR *var, SCIP_Real score, SCIP_Real solval)
SCIP_RETCODE SCIPbranchExtern(SCIP *scip, SCIP_RESULT *result)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPbranchLP(SCIP *scip, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:323
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition scip_cons.c:181
SCIP_RETCODE SCIPsetConshdlrGetDiveBdChgs(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:877
void SCIPconshdlrMarkExact(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4374
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)),)
Definition scip_cons.c:347
SCIP_RETCODE SCIPbranchLPExact(SCIP *scip, SCIP_RESULT *result)
Definition scip_exact.c:235
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition scip_mem.c:72
SCIP_RETCODE SCIPgetDivesetScore(SCIP *scip, SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
SCIP_RETCODE SCIPaddDiveBoundChange(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition rational.cpp:604
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:474
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:124
SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
void SCIPupdateSolIntegralityViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol)
Definition scip_sol.c:404
void SCIPgetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *res)
Definition scip_sol.c:1801
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
Definition sol.c:4165
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23694
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
return SCIP_OKAY
static SCIP_DIVESET * diveset
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_Bool roundup
static SCIP_VAR ** vars
public methods for managing constraints
public methods for message output
#define SCIPdebugMessage
Definition pub_message.h:96
public methods for primal CIP solutions
public methods for problem variables
wrapper for rational number arithmetic
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for exact solving
public methods for the LP relaxation, rows and columns
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
#define SCIP_DECL_CONSENFORELAX(x)
Definition type_cons.h:388
#define SCIP_DECL_CONSGETDIVEBDCHGS(x)
Definition type_cons.h:920
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:676
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
#define SCIP_DECL_CONSCHECK(x)
Definition type_cons.h:474
#define SCIP_DECL_CONSHDLRCOPY(x)
Definition type_cons.h:108
#define SCIP_DIVETYPE_INTEGRALITY
Definition type_heur.h:60
@ SCIP_BRANCHDIR_DOWNWARDS
@ SCIP_BRANCHDIR_UPWARDS
@ SCIP_LPSOLSTAT_UNBOUNDEDRAY
Definition type_lp.h:46
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_INFEASIBLE
Definition type_result.h:46
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_INTEGER
Definition type_var.h:65
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64