Scippy

    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#include <string.h>
    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 assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
    65
    66 /* call inclusion method of presolver */
    68
    69 return SCIP_OKAY;
    70}
    71
    72
    73/** presolving execution method */
    74static
    75SCIP_DECL_PRESOLEXEC(presolExecInttobinary)
    76{ /*lint --e{715}*/
    77 SCIP_VAR** scipvars;
    78 SCIP_VAR** vars;
    79 int nbinvars;
    80 int nintvars;
    81 int v;
    82
    83 assert(result != NULL);
    84
    85 *result = SCIP_DIDNOTRUN;
    86
    87 if( SCIPdoNotAggr(scip) )
    88 return SCIP_OKAY;
    89
    90 /* get the problem variables */
    91 scipvars = SCIPgetVars(scip);
    92 nbinvars = SCIPgetNBinVars(scip);
    93 nintvars = SCIPgetNIntVars(scip);
    94 if( nintvars == 0 )
    95 return SCIP_OKAY;
    96
    97 *result = SCIP_DIDNOTFIND;
    98
    99 /* copy the integer variables into an own array, since adding binary variables affects the left-most slots in the
    100 * array and thereby interferes with our search loop
    101 */
    102 SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &scipvars[nbinvars], nintvars) );
    103
    104 /* scan the integer variables for possible conversion into binaries */
    105 for( v = 0; v < nintvars; ++v )
    106 {
    107 SCIP_Real lb;
    108 SCIP_Real ub;
    109
    110 assert(SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER && !SCIPvarIsImpliedIntegral(vars[v]));
    111
    112 /* if variable cannot be aggregated, we cannot perform the conversion */
    113 if( SCIPdoNotAggrVar(scip, vars[v]) )
    114 continue;
    115
    116 /* get variable's bounds */
    117 lb = SCIPvarGetLbGlobal(vars[v]);
    118 ub = SCIPvarGetUbGlobal(vars[v]);
    119
    120 /* check if bounds are exactly one apart; if the lower bound is too large, aggregations will be rejected */
    121 if( SCIPisEQ(scip, lb, ub - 1.0) && !SCIPisHugeValue(scip, REALABS(lb) / SCIPfeastol(scip)) )
    122 {
    123 SCIP_VAR* binvar;
    124 char binvarname[SCIP_MAXSTRLEN];
    125 SCIP_Bool infeasible;
    126 SCIP_Bool redundant;
    127 SCIP_Bool aggregated;
    128
    129 SCIPdebugMsg(scip, "converting <%s>[%g,%g] into binary variable\n", SCIPvarGetName(vars[v]), lb, ub);
    130
    131 /* create binary variable */
    132 (void) SCIPsnprintf(binvarname, SCIP_MAXSTRLEN, "%s_bin", SCIPvarGetName(vars[v]));
    133 SCIP_CALL( SCIPcreateVar(scip, &binvar, binvarname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
    134 SCIPvarIsInitial(vars[v]), SCIPvarIsRemovable(vars[v]), NULL, NULL, NULL, NULL, NULL) );
    135 SCIP_CALL( SCIPaddVar(scip, binvar) );
    136
    137 /* set up debug solution */
    138#ifdef WITH_DEBUG_SOLUTION
    140 {
    141 SCIP_SOL* debugsol;
    142
    143 SCIP_CALL( SCIPdebugGetSol(scip, &debugsol) );
    144
    145 /* set solution value in the debug solution if it is available */
    146 if( debugsol != NULL )
    147 {
    148 SCIP_Real val;
    149 SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
    150 SCIP_CALL( SCIPdebugAddSolVal(scip, binvar, val - lb) );
    151 }
    152 }
    153#endif
    154
    155 /* aggregate integer and binary variable */
    156 SCIP_CALL( SCIPaggregateVars(scip, vars[v], binvar, 1.0, -1.0, lb, &infeasible, &redundant, &aggregated) );
    157
    158 /* release binary variable */
    159 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
    160
    161 /* it can be the case that this aggregation detects an infeasibility; for example, during the copy of the
    162 * variable bounds from the integer variable to the binary variable, infeasibility can be detected; this can
    163 * happen because an upper bound or a lower bound of such a variable bound variable was "just" changed and the
    164 * varbound constraint handler, who would detect that infeasibility (since it was creating it from a varbound
    165 * constraint), was called before that bound change was detected due to the presolving priorities;
    166 */
    167 if( infeasible )
    168 {
    169 *result = SCIP_CUTOFF;
    170 break;
    171 }
    172 else if( aggregated )
    173 {
    174 assert(redundant);
    175
    176 (*nchgvartypes)++;
    177 ++(*naggrvars);
    178 *result = SCIP_SUCCESS;
    179 }
    180 }
    181 }
    182
    183 /* free temporary memory */
    185
    186 return SCIP_OKAY;
    187}
    188
    189
    190/*
    191 * presolver specific interface methods
    192 */
    193
    194/** creates the inttobinary presolver and includes it in SCIP */
    196 SCIP* scip /**< SCIP data structure */
    197 )
    198{
    199 SCIP_PRESOLDATA* presoldata;
    200 SCIP_PRESOL* presolptr;
    201
    202 /* create inttobinary presolver data */
    203 presoldata = NULL;
    204
    205 /* include presolver */
    207 presolExecInttobinary,
    208 presoldata) );
    209
    210 assert(presolptr != NULL);
    211
    212 SCIP_CALL( SCIPsetPresolCopy(scip, presolptr, presolCopyInttobinary) );
    213
    214 return SCIP_OKAY;
    215}
    methods for debugging
    #define SCIPdebugGetSolVal(scip, var, val)
    Definition: debug.h:312
    #define SCIPdebugAddSolVal(scip, var, val)
    Definition: debug.h:311
    #define SCIPdebugSolIsEnabled(scip)
    Definition: debug.h:316
    #define NULL
    Definition: def.h:255
    #define SCIP_MAXSTRLEN
    Definition: def.h:276
    #define SCIP_Bool
    Definition: def.h:98
    #define SCIP_Real
    Definition: def.h:163
    #define REALABS(x)
    Definition: def.h:189
    #define SCIP_CALL(x)
    Definition: def.h:362
    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:23514
    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:23498
    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:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
    Definition: var.c:23524
    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:24120
    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
    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