SCIP

    Solving Constraint Integer Programs

    presol_inttobinary.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_inttobinary.c
    26 * @ingroup DEFPLUGINS_PRESOL
    27 * @brief presolver that converts integer variables with domain [a,a+1] to binaries
    28 * @author Tobias Achterberg
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/debug.h"
    36#include "scip/pub_message.h"
    37#include "scip/pub_misc.h"
    38#include "scip/pub_presol.h"
    39#include "scip/pub_var.h"
    40#include "scip/scip_mem.h"
    41#include "scip/scip_message.h"
    42#include "scip/scip_numerics.h"
    43#include "scip/scip_presol.h"
    44#include "scip/scip_prob.h"
    45#include "scip/scip_var.h"
    46
    47
    48#define PRESOL_NAME "inttobinary"
    49#define PRESOL_DESC "converts integer variables with domain [a,a+1] to binaries"
    50#define PRESOL_PRIORITY +7000000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
    51#define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    52#define PRESOL_TIMING SCIP_PRESOLTIMING_FAST /* timing of the presolver (fast, medium, or exhaustive) */
    53
    54/*
    55 * Callback methods of presolver
    56 */
    57
    58/** copy method for constraint handler plugins (called when SCIP copies plugins) */
    59static
    60SCIP_DECL_PRESOLCOPY(presolCopyInttobinary)
    61{ /*lint --e{715}*/
    62 assert(scip != NULL);
    63 assert(presol != NULL);
    64
    66
    67 /* call inclusion method of presolver */
    69
    70 return SCIP_OKAY;
    71}
    72
    73
    74/** presolving execution method */
    75static
    76SCIP_DECL_PRESOLEXEC(presolExecInttobinary)
    77{ /*lint --e{715}*/
    78 SCIP_VAR** scipvars;
    79 SCIP_VAR** vars;
    80 int nbinvars;
    81 int nintvars;
    82 int v;
    83
    84 assert(result != NULL);
    85
    86 *result = SCIP_DIDNOTRUN;
    87
    88 if( SCIPdoNotAggr(scip) )
    89 return SCIP_OKAY;
    90
    91 /* get the problem variables */
    92 scipvars = SCIPgetVars(scip);
    93 nbinvars = SCIPgetNBinVars(scip);
    94 nintvars = SCIPgetNIntVars(scip);
    95 if( nintvars == 0 )
    96 return SCIP_OKAY;
    97
    98 *result = SCIP_DIDNOTFIND;
    99
    100 /* copy the integer variables into an own array, since adding binary variables affects the left-most slots in the
    101 * array and thereby interferes with our search loop
    102 */
    103 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &scipvars[nbinvars], nintvars) );
    104
    105 /* scan the integer variables for possible conversion into binaries */
    106 for( v = 0; v < nintvars; ++v )
    107 {
    108 SCIP_Real lb;
    109 SCIP_Real ub;
    110
    111 assert(SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER && !SCIPvarIsImpliedIntegral(vars[v]));
    112
    113 /* if variable cannot be aggregated, we cannot perform the conversion */
    114 if( SCIPdoNotAggrVar(scip, vars[v]) )
    115 continue;
    116
    117 /* get variable's bounds */
    118 lb = SCIPvarGetLbGlobal(vars[v]);
    119 ub = SCIPvarGetUbGlobal(vars[v]);
    120
    121 /* check if bounds are exactly one apart; if the lower bound is too large, aggregations will be rejected */
    122 if( SCIPisEQ(scip, lb, ub - 1.0) && !SCIPisHugeValue(scip, REALABS(lb) / SCIPfeastol(scip)) )
    123 {
    124 SCIP_VAR* binvar;
    125 char binvarname[SCIP_MAXSTRLEN];
    126 SCIP_Bool infeasible;
    127 SCIP_Bool redundant;
    128 SCIP_Bool aggregated;
    129
    130 SCIPdebugMsg(scip, "converting <%s>[%g,%g] into binary variable\n", SCIPvarGetName(vars[v]), lb, ub);
    131
    132 /* create binary variable */
    133 (void) SCIPsnprintf(binvarname, SCIP_MAXSTRLEN, "%s_bin", SCIPvarGetName(vars[v]));
    134 SCIP_CALL( SCIPcreateVar(scip, &binvar, binvarname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    135 SCIPvarIsInitial(vars[v]), SCIPvarIsRemovable(vars[v]), NULL, NULL, NULL, NULL, NULL) );
    136 SCIP_CALL( SCIPaddVar(scip, binvar) );
    137
    138 /* set up debug solution */
    139#ifdef WITH_DEBUG_SOLUTION
    141 {
    142 SCIP_SOL* debugsol;
    143
    144 SCIP_CALL( SCIPdebugGetSol(scip, &debugsol) );
    145
    146 /* set solution value in the debug solution if it is available */
    147 if( debugsol != NULL )
    148 {
    149 SCIP_Real val;
    150 SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
    151 SCIP_CALL( SCIPdebugAddSolVal(scip, binvar, val - lb) );
    152 }
    153 }
    154#endif
    155
    156 /* aggregate integer and binary variable */
    157 SCIP_CALL( SCIPaggregateVars(scip, vars[v], binvar, 1.0, -1.0, lb, &infeasible, &redundant, &aggregated) );
    158
    159 /* release binary variable */
    160 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
    161
    162 /* it can be the case that this aggregation detects an infeasibility; for example, during the copy of the
    163 * variable bounds from the integer variable to the binary variable, infeasibility can be detected; this can
    164 * happen because an upper bound or a lower bound of such a variable bound variable was "just" changed and the
    165 * varbound constraint handler, who would detect that infeasibility (since it was creating it from a varbound
    166 * constraint), was called before that bound change was detected due to the presolving priorities;
    167 */
    168 if( infeasible )
    169 {
    170 *result = SCIP_CUTOFF;
    171 break;
    172 }
    173 else if( aggregated )
    174 {
    175 assert(redundant);
    176
    177 (*nchgvartypes)++;
    178 ++(*naggrvars);
    179 *result = SCIP_SUCCESS;
    180 }
    181 }
    182 }
    183
    184 /* free temporary memory */
    186
    187 return SCIP_OKAY;
    188}
    189
    190
    191/*
    192 * presolver specific interface methods
    193 */
    194
    195/** creates the inttobinary presolver and includes it in SCIP */
    197 SCIP* scip /**< SCIP data structure */
    198 )
    199{
    200 SCIP_PRESOLDATA* presoldata;
    201 SCIP_PRESOL* presolptr;
    202
    203 /* create inttobinary presolver data */
    204 presoldata = NULL;
    205
    206 /* include presolver */
    208 presolExecInttobinary,
    209 presoldata) );
    210
    211 assert(presolptr != NULL);
    212
    213 SCIP_CALL( SCIPsetPresolCopy(scip, presolptr, presolCopyInttobinary) );
    214
    215 return SCIP_OKAY;
    216}
    methods for debugging
    #define SCIPdebugGetSolVal(scip, var, val)
    Definition: debug.h:313
    #define SCIPdebugAddSolVal(scip, var, val)
    Definition: debug.h:312
    #define SCIPdebugSolIsEnabled(scip)
    Definition: debug.h:317
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #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 REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPincludePresolInttobinary(SCIP *scip)
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    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 SCIPisHugeValue(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
    Definition: var.c:23546
    SCIP_Bool SCIPdoNotAggrVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:10929
    SCIP_Bool SCIPdoNotAggr(SCIP *scip)
    Definition: scip_var.c:10909
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
    Definition: scip_var.c:10550
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
    Definition: var.c:23556
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    memory allocation routines
    static SCIP_DECL_PRESOLCOPY(presolCopyInttobinary)
    #define PRESOL_NAME
    static SCIP_DECL_PRESOLEXEC(presolExecInttobinary)
    #define PRESOL_PRIORITY
    #define PRESOL_MAXROUNDS
    #define PRESOL_TIMING
    #define PRESOL_DESC
    presolver that converts integer variables with domain [a,a+1] to binaries
    public methods for message output
    public data structures and miscellaneous methods
    public methods for presolvers
    public methods for problem variables
    public methods for memory management
    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
    struct SCIP_PresolData SCIP_PRESOLDATA
    Definition: type_presol.h:51
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64