SCIP Doxygen Documentation
Loading...
Searching...
No Matches
presol_trivial.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 presol_trivial.c
26 * @ingroup DEFPLUGINS_PRESOL
27 * @brief trivial presolver: round fractional bounds on integer variables, fix variables with equal bounds
28 * @author Tobias Achterberg
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
33#include "scip/presol_trivial.h"
34#include "scip/pub_message.h"
35#include "scip/pub_presol.h"
36#include "scip/pub_var.h"
37#include "scip/scip_message.h"
38#include "scip/scip_numerics.h"
39#include "scip/scip_presol.h"
40#include "scip/scip_prob.h"
41#include "scip/scip_var.h"
42
43
44#define PRESOL_NAME "trivial"
45#define PRESOL_DESC "round fractional bounds on integers, fix variables with equal bounds"
46#define PRESOL_PRIORITY +9000000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
47#define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
48#define PRESOL_TIMING SCIP_PRESOLTIMING_FAST /* timing of the presolver (fast, medium, or exhaustive) */
49
50#ifdef FIXSIMPLEVALUE
51#define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
52#endif
53
54
55/*
56 * Callback methods of presolver
57 */
58
59/** copy method for constraint handler plugins (called when SCIP copies plugins) */
60static
61SCIP_DECL_PRESOLCOPY(presolCopyTrivial)
62{ /*lint --e{715}*/
63 assert(scip != NULL);
64 assert(presol != NULL);
65
67
68 /* call inclusion method of presolver */
70
71 return SCIP_OKAY;
72}
73
74
75/** presolving execution method */
76static
77SCIP_DECL_PRESOLEXEC(presolExecTrivial)
78{ /*lint --e{715}*/
79 SCIP_VAR** vars;
80 int nvars;
81 int v;
82
83 assert(result != NULL);
84
86
87 /* get the problem variables */
90
91 /* scan the variables for trivial bound reductions
92 * (loop backwards, since a variable fixing can change the current and the subsequent slots in the vars array)
93 */
94 for( v = nvars-1; v >= 0; --v )
95 {
96 SCIP_Real lb;
97 SCIP_Real ub;
98 SCIP_Bool infeasible;
99 SCIP_Bool fixed;
100
101 /* get variable's bounds */
102 lb = SCIPvarGetLbGlobal(vars[v]);
103 ub = SCIPvarGetUbGlobal(vars[v]);
104
105 /* is variable integral? */
106 if( SCIPvarIsIntegral(vars[v]) )
107 {
108 SCIP_Real newlb;
109 SCIP_Real newub;
110
111 /* round fractional bounds on integer variables */
112 newlb = SCIPfeasCeil(scip, lb);
113 newub = SCIPfeasFloor(scip, ub);
114
115 /* check bounds on variable for infeasibility */
116 if( newlb > newub + 0.5 )
117 {
119 "problem infeasible: integral variable <%s> has bounds [%.17f,%.17f] rounded to [%.17f,%.17f]\n",
120 SCIPvarGetName(vars[v]), lb, ub, newlb, newub);
122 return SCIP_OKAY;
123 }
124
125 /* fix variables with equal bounds */
126 if( newlb > newub - 0.5 )
127 {
128 SCIPdebugMsg(scip, "fixing integral variable <%s>: [%.17f,%.17f] -> [%.17f,%.17f]\n", SCIPvarGetName(vars[v]), lb, ub, newlb, newub);
129 SCIP_CALL( SCIPfixVar(scip, vars[v], newlb, &infeasible, &fixed) );
130 if( infeasible )
131 {
132 SCIPdebugMsg(scip, " -> infeasible fixing\n");
134 return SCIP_OKAY;
135 }
136 assert(fixed);
137 (*nfixedvars)++;
138 }
139 else
140 {
141 /* round fractional bounds */
142 if( !SCIPisFeasEQ(scip, lb, newlb) )
143 {
144 SCIPdebugMsg(scip, "rounding lower bound of integral variable <%s>: [%.17f,%.17f] -> [%.17f,%.17f]\n",
145 SCIPvarGetName(vars[v]), lb, ub, newlb, ub);
146 SCIP_CALL( SCIPchgVarLb(scip, vars[v], newlb) );
147 (*nchgbds)++;
148 }
149 if( !SCIPisFeasEQ(scip, ub, newub) )
150 {
151 SCIPdebugMsg(scip, "rounding upper bound of integral variable <%s>: [%.17f,%.17f] -> [%.17f,%.17f]\n",
152 SCIPvarGetName(vars[v]), newlb, ub, newlb, newub);
153 SCIP_CALL( SCIPchgVarUb(scip, vars[v], newub) );
154 (*nchgbds)++;
155 }
156 }
157 }
158 else
159 {
160 /* check bounds on continuous variable for infeasibility */
161 if( SCIPisFeasGT(scip, lb, ub) )
162 {
164 "problem infeasible: continuous variable <%s> has bounds [%.17f,%.17f]\n",
165 SCIPvarGetName(vars[v]), lb, ub);
167 return SCIP_OKAY;
168 }
169
170 /* fix variables with equal bounds */
171 if( SCIPisEQ(scip, lb, ub) )
172 {
173 SCIP_Real fixval;
174
175#ifdef FIXSIMPLEVALUE
176 fixval = SCIPselectSimpleValue(lb - 0.9 * SCIPepsilon(scip), ub + 0.9 * SCIPepsilon(scip), MAXDNOM);
177#else
178 /* prefer integral values (especially 0) over midpoint */
179 fixval = SCIPround(scip, lb);
180 if( fixval < lb || fixval > ub )
181 fixval = (lb + ub)/2;
182#endif
183 SCIPdebugMsg(scip, "fixing continuous variable <%s>[%.17f,%.17f] to %.17f\n", SCIPvarGetName(vars[v]), lb, ub, fixval);
184 SCIP_CALL( SCIPfixVar(scip, vars[v], fixval, &infeasible, &fixed) );
185 if( infeasible )
186 {
187 SCIPdebugMsg(scip, " -> infeasible fixing\n");
189 return SCIP_OKAY;
190 }
191 assert(fixed);
192 (*nfixedvars)++;
193 }
194 }
195 }
196
197 return SCIP_OKAY;
198}
199
200
201/*
202 * presolver specific interface methods
203 */
204
205/** creates the trivial presolver and includes it in SCIP */
207 SCIP* scip /**< SCIP data structure */
208 )
209{
210 SCIP_PRESOL* presolptr;
211
212 /* include presolver */
214
215 assert(presolptr != NULL);
216
217 SCIP_CALL( SCIPsetPresolCopy(scip, presolptr, presolCopyTrivial) );
218
219 return SCIP_OKAY;
220}
#define MAXDNOM
#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 SCIP_CALL(x)
Definition def.h:364
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition misc.c:10041
SCIP_RETCODE SCIPincludePresolTrivial(SCIP *scip)
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol,)
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition presol.c:625
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5697
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5875
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition scip_var.c:10318
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
static SCIP_VAR ** vars
#define PRESOL_NAME
#define PRESOL_PRIORITY
#define PRESOL_MAXROUNDS
#define PRESOL_TIMING
#define PRESOL_DESC
trivial presolver: round fractional bounds on integer variables, fix variables with equal bounds
public methods for message output
public methods for presolvers
public methods for problem variables
public methods for message handling
public methods for numerical tolerances
public methods for presolving plugins
public methods for global and local (sub)problems
public methods for SCIP variables
@ SCIP_VERBLEVEL_NORMAL
#define SCIP_DECL_PRESOLCOPY(x)
Definition type_presol.h:60
struct SCIP_Presol SCIP_PRESOL
Definition type_presol.h:50
#define SCIP_DECL_PRESOLEXEC(x)
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Var SCIP_VAR
Definition type_var.h:166