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#include <string.h>
51
52
53#define CONSHDLR_NAME "integral"
54#define CONSHDLR_DESC "integrality constraint"
55#define CONSHDLR_ENFOPRIORITY 0 /**< priority of the constraint handler for constraint enforcing */
56#define CONSHDLR_CHECKPRIORITY 0 /**< priority of the constraint handler for checking feasibility */
57#define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
58 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
59#define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
60
61
62/** checks whether primal solution satisfies all integrality restrictions without tolerances */
63static
65 SCIP* scip, /**< SCIP data structure */
66 SCIP_SOL* sol, /**< solution to be checked */
67 SCIP_Bool printreason, /**< should infeasisibility reason be printed? */
68 SCIP_RESULT* result /**< pointer to store the result of the lp enforcement call */
69 )
70{
71 SCIP_RATIONAL* solval;
72 SCIP_Bool integral;
73 SCIP_VAR** vars;
74 int nintegers;
75 int ncontimplvars;
76 int ncontvars;
77 int v;
78
79 assert(result != NULL);
80
81 SCIPdebugMessage("checking exact integrality of primal solution:\n");
82
83 integral = TRUE;
84
86
87 /* get all problem variables and integer region in vars array */
88 SCIP_CALL( SCIPgetSolVarsData(scip, sol, &vars, &nintegers, NULL, NULL, NULL, NULL, &ncontimplvars, &ncontvars) );
89 nintegers -= ncontimplvars + ncontvars;
90 assert(nintegers >= 0);
91
92 /* check whether primal solution satisfies all integrality restrictions */
93 for( v = 0; v < nintegers && integral; ++v )
94 {
95 /* if the solution is exact we check the exact data, otherwise we check the fp data */
96 if( SCIPsolIsExact(sol) )
97 SCIPgetSolValExact(scip, sol, vars[v], solval);
98 else
100
103
104 if( !SCIPrationalIsIntegral(solval) )
105 {
107 if( printreason )
108 {
109 SCIPinfoMessage(scip, NULL, "violation: integrality condition of variable <%s> =",
110 SCIPvarGetName(vars[v]));
112 SCIPinfoMessage(scip, NULL, "\n");
113 }
114 integral = FALSE;
115 }
116 }
117
119
120 return SCIP_OKAY;
121}
122
123/*
124 * Callback methods
125 */
126
127/** copy method for constraint handler plugins (called when SCIP copies plugins) */
128static
129SCIP_DECL_CONSHDLRCOPY(conshdlrCopyIntegral)
130{ /*lint --e{715}*/
131 assert(scip != NULL);
132 assert(conshdlr != NULL);
133 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
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(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
153 assert(scip != NULL);
154 assert(conss == NULL);
155 assert(nconss == 0);
156 assert(result != NULL);
157
158 SCIPdebugMsg(scip, "Enfolp method of integrality constraint: %d fractional variables\n", SCIPgetNLPBranchCands(scip));
159
161
162 /* if the root LP is unbounded, we want to terminate with UNBOUNDED or INFORUNBOUNDED,
163 * depending on whether we are able to construct an integral solution; in any case we do not want to branch
164 */
166 {
167 if( SCIPgetNLPBranchCands(scip) == 0 )
169 else
171 return SCIP_OKAY;
172 }
173
174 /* call branching methods */
176
178 {
180 }
181
182 /* if no branching was done, the LP solution was not fractional */
183 if( *result == SCIP_DIDNOTRUN )
185
186 return SCIP_OKAY;
187}
188
189/** constraint enforcing method of constraint handler for relaxation solutions */
190static
191SCIP_DECL_CONSENFORELAX(consEnforelaxIntegral)
192{ /*lint --e{715}*/
193 SCIP_VAR** vars;
194 int nbinvars;
195 int nintvars;
196 int i;
197
198 assert(conshdlr != NULL);
199 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
200 assert(scip != NULL);
201 assert(conss == NULL);
202 assert(nconss == 0);
203 assert(result != NULL);
204
205 SCIPdebugMsg(scip, "Enforelax method of integrality constraint\n");
206
208
209 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
210
211 int nintegers = nbinvars + nintvars + SCIPgetNBinImplVars(scip) + SCIPgetNIntImplVars(scip);
212
213 for( i = 0; i < nintegers; ++i )
214 {
215 assert(vars[i] != NULL);
217
219 {
221 {
222 SCIPdebugMsg(scip, "Cutoff for integral variable %s with bounds [%f, %f] and value %f\n", SCIPvarGetName(vars[i]),
225 return SCIP_OKAY;
226 }
227 else
228 {
229 /* @todo better way to handle this would be a BRANCHEXECRELAX callback that could also implement pseudo costs for
230 * relaxation solutions instead of using the enforelaxcallback which is mainly intended for spatial branching
231 */
234 }
235 }
236 }
237
238 /* if we have found a branching candidate, immediately branch to be able to return SCIP_BRANCHED and stop the
239 * enforcement loop
240 */
241 if( *result == SCIP_INFEASIBLE )
242 {
243 /* call branching methods for external candidates */
245
246 /* since we only call it if we added external candidates, the branching rule should always be able to branch */
248 }
249
250 return SCIP_OKAY;
251}
252
253/** feasibility check method of constraint handler for integral solutions */
254static
255SCIP_DECL_CONSCHECK(consCheckIntegral)
256{ /*lint --e{715}*/
257 SCIP_VAR** vars;
258 SCIP_Real solval;
259 int nintegers;
260 int ncontimplvars;
261 int ncontvars;
262 int v;
263
264 assert(scip != NULL);
265 assert(sol != NULL);
266 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
267
268 SCIPdebugMsg(scip, "Check method of integrality constraint (checkintegrality=%u)\n", checkintegrality);
269
271
272 if( !checkintegrality )
273 return SCIP_OKAY;
274
275 SCIP_CALL( SCIPgetSolVarsData(scip, sol, &vars, &nintegers, NULL, NULL, NULL, NULL, &ncontimplvars, &ncontvars) );
276 nintegers -= ncontimplvars + ncontvars;
277 assert(nintegers >= 0);
278
279 if( !SCIPisExact(scip) )
280 {
281 for( v = 0; v < nintegers; ++v )
282 {
283 solval = SCIPgetSolVal(scip, sol, vars[v]);
284
285 if( sol != NULL )
287
288 if( !SCIPisFeasIntegral(scip, solval) )
289 {
291
292 if( printreason )
293 {
294 SCIPinfoMessage(scip, NULL, "violation: integrality condition of variable <%s> = %.15g\n",
295 SCIPvarGetName(vars[v]), solval);
296 }
297 if( !completely )
298 break;
299 }
300 }
301 }
302 /* in exact solving mode, we have to check integrality without tolerances */
303 else
304 {
305 SCIP_CALL( checkIntegralityExact(scip, sol, printreason, result) );
306 }
307
308 return SCIP_OKAY;
309}
310
311/** variable rounding lock method of constraint handler */
312static
313SCIP_DECL_CONSLOCK(consLockIntegral)
314{ /*lint --e{715}*/
315 return SCIP_OKAY;
316}
317
318/** constraint handler method to suggest dive bound changes during the generic diving algorithm */
319static
320SCIP_DECL_CONSGETDIVEBDCHGS(consGetDiveBdChgsIntegral)
321{ /*lint --e{715}*/
322 SCIP_VAR** vars;
323 SCIP_Real solval;
324 SCIP_Real score;
325 SCIP_Real bestscore;
326 SCIP_Bool bestroundup;
327 int nintegers;
328 int ncontvars;
329 int nbinimplvars;
330 int nintimplvars;
331 int ncontimplvars;
332 int bestcandidx;
333 int v;
334
335 assert(scip != NULL);
336 assert(diveset != NULL);
337 assert(sol != NULL);
338 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
339
340 SCIPdebugMsg(scip, "integral constraint handler: determine diving bound changes\n");
341
343 &nbinimplvars, &nintimplvars, &ncontimplvars, &ncontvars) );
344 nintegers = nintegers - nbinimplvars - nintimplvars - ncontimplvars - ncontvars;
345 assert(nintegers >= 0);
346
347 bestscore = SCIP_REAL_MIN;
348 bestcandidx = -1;
349 *success = FALSE;
350 bestroundup = FALSE; /* only for lint */
351
352 /* loop over solution values and get score of fractional variables */
353 for( v = 0; v < nintegers; ++v )
354 {
355 solval = SCIPgetSolVal(scip, sol, vars[v]);
356
357 /* skip variable if solution value disagrees with the local bounds */
358 if( ! SCIPisFeasIntegral(scip, solval) && SCIPisGE(scip, solval, SCIPvarGetLbLocal(vars[v])) && SCIPisLE(scip, solval, SCIPvarGetUbLocal(vars[v])) )
359 {
361
363 solval - SCIPfloor(scip, solval), &score, &roundup) );
364
365 /* we search for candidates with maximum score */
366 if( score > bestscore )
367 {
368 bestcandidx = v;
369 bestscore = score;
370 bestroundup = roundup;
371 *success = TRUE;
372 }
373 }
374 }
375
376 assert(!(*success) || bestcandidx >= 0);
377
378 if( *success )
379 {
380 solval = SCIPgetSolVal(scip, sol, vars[bestcandidx]);
381
382 /* if we want to round up the best candidate, it is added as the preferred bound change */
384 SCIPceil(scip, solval), bestroundup) );
386 SCIPfloor(scip, solval), ! bestroundup) );
387 }
388
389 return SCIP_OKAY;
390}
391
392/*
393 * constraint specific interface methods
394 */
395
396/** creates the handler for integrality constraint and includes it in SCIP */
398 SCIP* scip /**< SCIP data structure */
399 )
400{
401 SCIP_CONSHDLR* conshdlr;
402
403 /* include constraint handler */
406 consEnfolpIntegral, consEnfopsIntegral, consCheckIntegral, consLockIntegral, NULL) );
407
408 assert(conshdlr != NULL);
409
410 /* mark constraint handler as exact */
411 SCIPconshdlrMarkExact(conshdlr);
412
413 /* set non-fundamental callbacks via specific setter functions */
414 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyIntegral, consCopyIntegral) );
415 SCIP_CALL( SCIPsetConshdlrGetDiveBdChgs(scip, conshdlr, consGetDiveBdChgsIntegral) );
416 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxIntegral) );
417
418 return SCIP_OKAY;
419}
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:97
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:89
#define CONSHDLR_DESC
Definition cons_and.c:86
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:92
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:88
#define CONSHDLR_NAME
Definition cons_and.c:85
#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:255
#define SCIP_Bool
Definition def.h:98
#define SCIP_Real
Definition def.h:163
#define EPSFRAC(x, eps)
Definition def.h:201
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIP_REAL_MIN
Definition def.h:166
#define SCIP_CALL(x)
Definition def.h:362
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:4370
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4316
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:406
void SCIPgetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *res)
Definition scip_sol.c:1803
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1765
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:24268
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23453
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23267
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23490
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24234
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:919
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:675
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
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