SCIP

    Solving Constraint Integer Programs

    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
    85 *result = SCIP_DIDNOTFIND;
    86
    87 /* get the problem variables */
    88 vars = SCIPgetVars(scip);
    89 nvars = SCIPgetNVars(scip);
    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);
    121 *result = SCIP_CUTOFF;
    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");
    133 *result = SCIP_CUTOFF;
    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);
    166 *result = SCIP_CUTOFF;
    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");
    188 *result = SCIP_CUTOFF;
    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
    Definition: cons_linear.c:166
    #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,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    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_DECL_PRESOLCOPY((*presolcopy)))
    Definition: scip_presol.c:148
    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)
    Definition: scip_presol.c:113
    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
    #define PRESOL_NAME
    static SCIP_DECL_PRESOLCOPY(presolCopyTrivial)
    #define PRESOL_PRIORITY
    static SCIP_DECL_PRESOLEXEC(presolExecTrivial)
    #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
    Definition: type_message.h:60
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63