SCIP

    Solving Constraint Integer Programs

    prop_sync.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 prop_sync.c
    26 * @ingroup DEFPLUGINS_PROP
    27 * @brief propagator for applying global bound changes that were communicated by other
    28 * concurrent solvers
    29 * @author Leona Gottwald
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/concurrent.h"
    36#include "scip/prop_sync.h"
    37#include "scip/pub_message.h"
    38#include "scip/pub_prop.h"
    39#include "scip/pub_var.h"
    40#include "scip/scip_mem.h"
    41#include "scip/scip_message.h"
    42#include "scip/scip_probing.h"
    43#include "scip/scip_prop.h"
    44#include "scip/scip_var.h"
    45#include "scip/scip_message.h"
    46#include "tpi/tpi.h"
    47
    48/* fundamental propagator properties */
    49#define PROP_NAME "sync"
    50#define PROP_DESC "propagator for synchronization of bound changes"
    51#define PROP_PRIORITY (INT_MAX/4) /**< propagator priority */
    52#define PROP_FREQ -1 /**< propagator frequency */
    53#define PROP_DELAY FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    54#define PROP_TIMING SCIP_PROPTIMING_ALWAYS /**< propagation timing mask */
    55
    56#define PROP_PRESOL_PRIORITY (INT_MAX/4) /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers); combined with presolvers */
    57#define PROP_PRESOLTIMING SCIP_PRESOLTIMING_ALWAYS /* timing of the presolving method (fast, medium, or exhaustive) */
    58#define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    59
    60/*
    61 * Data structures
    62 */
    63
    64/** propagator data */
    65struct SCIP_PropData
    66{
    67 SCIP_VAR** bndvar; /**< array of variables with a bound change */
    68 SCIP_Real* bndval; /**< array of new bound values */
    69 SCIP_BOUNDTYPE* bndtype; /**< array of bound types */
    70 int nbnds; /**< number of boundchanges */
    71 int bndsize; /**< current size of bound change array */
    72 SCIP_Longint ntightened; /**< number of tightened bounds */
    73 SCIP_Longint ntightenedint; /**< number of tightened bounds of integer variables */
    74};
    75
    76
    77/*
    78 * Local methods
    79 */
    80
    81
    82/** apply the stored bound changes */
    83static
    85 SCIP* scip, /**< SCIP data structure */
    86 SCIP_PROPDATA* data, /**< propagator data */
    87 SCIP_RESULT* result, /**< result of propagations */
    88 int* ntightened, /**< pointer to store the number of tightened bounds */
    89 int* ntightenedint /**< pointer to store the number of tightened integer bounds */
    90 )
    91{
    92 int i;
    93
    94 assert(data != NULL);
    95 assert(result != NULL);
    96 assert(ntightened != NULL);
    97 assert(ntightenedint != NULL);
    98
    99 *ntightened = 0;
    100 *ntightenedint = 0;
    101
    103 *result = SCIP_DIDNOTFIND;
    104
    105 for( i = 0; i < data->nbnds; ++i )
    106 {
    107 SCIP_Bool infeas;
    108 SCIP_Bool tightened;
    109
    110 SCIP_CALL( SCIPvarGetProbvarBound(&data->bndvar[i], &data->bndval[i], &data->bndtype[i]) );
    111
    112 /* cannot change bounds of multi-aggregated variables so skip this bound-change */
    113 if( SCIPvarGetStatus(data->bndvar[i]) == SCIP_VARSTATUS_MULTAGGR )
    114 continue;
    115
    116 if( data->bndtype[i] == SCIP_BOUNDTYPE_LOWER )
    117 {
    118 SCIP_CALL( SCIPtightenVarLbGlobal(scip, data->bndvar[i], data->bndval[i], FALSE, &infeas, &tightened) );
    119 }
    120 else
    121 {
    122 assert(data->bndtype[i] == SCIP_BOUNDTYPE_UPPER);
    123 SCIP_CALL( SCIPtightenVarUbGlobal(scip, data->bndvar[i], data->bndval[i], FALSE, &infeas, &tightened) );
    124 }
    125
    126 if( tightened )
    127 {
    128 ++(*ntightened);
    129 if( SCIPvarIsNonimpliedIntegral(data->bndvar[i]) )
    130 ++(*ntightenedint);
    131 }
    132
    133 if( infeas )
    134 {
    135#ifndef NDEBUG
    136 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "sync propagator found cutoff in thread %i.\n", SCIPtpiGetThreadNum());
    137#endif
    138 *result = SCIP_CUTOFF;
    139 break;
    140 }
    141 }
    142
    143 data->nbnds = 0;
    145
    146 return SCIP_OKAY;
    147}
    148
    149
    150/*
    151 * Callback methods of propagator
    152 */
    153
    154/** destructor of propagator to free user data (called when SCIP is exiting) */
    155static
    157{ /*lint --e{715}*/
    158 SCIP_PROPDATA* propdata;
    159
    160 assert(scip != NULL);
    161 assert(prop != NULL);
    162
    164
    165 propdata = SCIPpropGetData(prop);
    166 assert(propdata != NULL);
    167
    168 SCIPfreeBlockMemory(scip, &propdata);
    169 SCIPpropSetData(prop, NULL);
    170
    171 return SCIP_OKAY;
    172}
    173
    174/** initialization method of propagator (called after problem was transformed) */
    175static
    177{ /*lint --e{715}*/
    178 SCIP_PROPDATA* data;
    179
    180 assert(prop != NULL);
    181
    183
    184 data = SCIPpropGetData(prop);
    185 assert(data != NULL);
    186
    187 data->bndsize = 0;
    188 data->nbnds = 0;
    189 data->bndvar = NULL;
    190 data->bndval = NULL;
    191 data->bndtype = NULL;
    192 data->ntightened = 0;
    193 data->ntightenedint = 0;
    194
    195 return SCIP_OKAY;
    196}
    197
    198/** deinitialization method of propagator (called before transformed problem is freed) */
    199static
    201{ /*lint --e{715}*/
    202 SCIP_PROPDATA* data;
    203
    204 assert(prop != NULL);
    205
    207
    208 data = SCIPpropGetData(prop);
    209 assert(data != NULL);
    210
    211 SCIPfreeBlockMemoryArrayNull(scip, &data->bndvar, data->bndsize);
    212 SCIPfreeBlockMemoryArrayNull(scip, &data->bndval, data->bndsize);
    213 SCIPfreeBlockMemoryArrayNull(scip, &data->bndtype, data->bndsize);
    214
    215 return SCIP_OKAY;
    216}
    217
    218/** presolving method of propagator */
    219static
    220SCIP_DECL_PROPPRESOL(propPresolSync)
    221{ /*lint --e{715}*/
    222 SCIP_PROPDATA* data;
    223 int ntightened;
    224 int ntightenedint;
    225
    226 assert(prop != NULL);
    227 assert(result != NULL);
    228
    230
    231 data = SCIPpropGetData(prop);
    232 assert(data != NULL);
    233
    234 *result = SCIP_DIDNOTRUN;
    235
    236 if( data->nbnds == 0 || SCIPinProbing(scip) )
    237 return SCIP_OKAY;
    238
    239 /* remember number of tightened bounds before applying new bound tightenings */
    240 SCIP_CALL( applyBoundChanges(scip, data, result, &ntightened, &ntightenedint) );
    241
    242 /* add number of tightened bounds to the total number of presolving boundchanges */
    243 if( ntightened > 0 )
    244 {
    245 *nchgbds += ntightened;
    246 data->ntightened += ntightened;
    247 data->ntightenedint += ntightened;
    248 if( *result != SCIP_CUTOFF )
    249 *result = SCIP_SUCCESS;
    250 }
    251
    252 SCIPpropSetFreq(prop, -1);
    253
    254 return SCIP_OKAY;
    255}
    256
    257/** execution method of propagator */
    258static
    260{ /*lint --e{715}*/
    261 SCIP_PROPDATA* data;
    262 int ntightened;
    263 int ntightenedint;
    264
    265 assert(prop != NULL);
    266
    268
    269 *result = SCIP_DIDNOTRUN;
    270
    271 if( SCIPinProbing(scip) )
    272 return SCIP_OKAY;
    273
    274 data = SCIPpropGetData(prop);
    275 assert(data != NULL);
    276
    277 SCIP_CALL( applyBoundChanges(scip, data, result, &ntightened, &ntightenedint) );
    278
    279 if( ntightened > 0 )
    280 {
    281 data->ntightened += ntightened;
    282 data->ntightenedint += ntightenedint;
    283 if( *result != SCIP_CUTOFF )
    284 *result = SCIP_REDUCEDDOM;
    285 }
    286
    287 SCIPpropSetFreq(prop, -1);
    288
    289 return SCIP_OKAY;
    290}
    291
    292/*
    293 * propagator specific interface methods
    294 */
    295
    296/** creates the sync propagator and includes it in SCIP */
    298 SCIP* scip /**< SCIP data structure */
    299 )
    300{
    301 SCIP_PROPDATA* propdata = NULL;
    302 SCIP_PROP* prop = NULL;
    303
    304 SCIP_CALL( SCIPallocBlockMemory(scip, &propdata) );
    305
    306 /* include propagator */
    308 propExecSync, propdata) );
    309 assert(prop != NULL);
    310
    311 /* set optional callbacks via setter functions */
    312 SCIP_CALL( SCIPsetPropFree(scip, prop, propFreeSync) );
    313 SCIP_CALL( SCIPsetPropInit(scip, prop, propInitSync) );
    314 SCIP_CALL( SCIPsetPropExit(scip, prop, propExitSync) );
    316
    317 return SCIP_OKAY;
    318}
    319
    320
    321/** adds a boundchange to the sync propagator */
    323 SCIP* scip, /**< SCIP data structure */
    324 SCIP_PROP* prop, /**< sync propagator */
    325 SCIP_VAR* var, /**< variable for bound */
    326 SCIP_Real val, /**< value of bound */
    327 SCIP_BOUNDTYPE bndtype /**< type of bound */
    328 )
    329{
    330 SCIP_PROPDATA* data;
    331
    332 assert(prop != NULL);
    333
    335
    336 data = SCIPpropGetData(prop);
    337 assert(data != NULL);
    338
    339 if( data->nbnds + 1 > data->bndsize )
    340 {
    341 int newsize;
    342 newsize = SCIPcalcMemGrowSize(scip, data->nbnds+1);
    343 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndvar, data->bndsize, newsize) );
    344 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndval, data->bndsize, newsize) );
    345 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndtype, data->bndsize, newsize) );
    346 data->bndsize = newsize;
    347 }
    348
    349 data->bndvar[data->nbnds] = var;
    350 data->bndval[data->nbnds] = val;
    351 data->bndtype[data->nbnds] = bndtype;
    352
    353 if( data->nbnds == 0 )
    354 {
    355 SCIPpropSetFreq(prop, 1);
    356 }
    357 ++data->nbnds;
    358
    359 return SCIP_OKAY;
    360}
    361
    362/** returns the total number of tightened bounds found by the sync propagator */
    364 SCIP_PROP* prop /**< sync propagator */
    365 )
    366{
    367 SCIP_PROPDATA* data;
    368
    369 assert(prop != NULL);
    370
    371 data = SCIPpropGetData(prop);
    372 assert(data != NULL);
    373
    374 return data->ntightened;
    375}
    376
    377/** returns the total number of tightened bounds for integer variables found by the sync propagator */
    379 SCIP_PROP* prop /**< sync propagator */
    380 )
    381{
    382 SCIP_PROPDATA* data;
    383
    384 assert(prop != NULL);
    385
    386 data = SCIPpropGetData(prop);
    387 assert(data != NULL);
    388
    389 return data->ntightenedint;
    390}
    void SCIPenableConcurrentBoundStorage(SCIP *scip)
    Definition: concurrent.c:288
    void SCIPdisableConcurrentBoundStorage(SCIP *scip)
    Definition: concurrent.c:276
    helper functions for concurrent scip solvers
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #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 FALSE
    Definition: def.h:103
    #define SCIP_CALL(x)
    Definition: def.h:364
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    SCIP_Longint SCIPpropSyncGetNTightenedBnds(SCIP_PROP *prop)
    Definition: prop_sync.c:363
    SCIP_RETCODE SCIPpropSyncAddBndchg(SCIP *scip, SCIP_PROP *prop, SCIP_VAR *var, SCIP_Real val, SCIP_BOUNDTYPE bndtype)
    Definition: prop_sync.c:322
    SCIP_Longint SCIPpropSyncGetNTightenedIntBnds(SCIP_PROP *prop)
    Definition: prop_sync.c:378
    SCIP_RETCODE SCIPincludePropSync(SCIP *scip)
    Definition: prop_sync.c:297
    int SCIPcalcMemGrowSize(SCIP *scip, int num)
    Definition: scip_mem.c:139
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    void SCIPpropSetData(SCIP_PROP *prop, SCIP_PROPDATA *propdata)
    Definition: prop.c:801
    SCIP_PROPDATA * SCIPpropGetData(SCIP_PROP *prop)
    Definition: prop.c:791
    SCIP_RETCODE SCIPsetPropPresol(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPPRESOL((*proppresol)), int presolpriority, int presolmaxrounds, SCIP_PRESOLTIMING presoltiming)
    Definition: scip_prop.c:283
    const char * SCIPpropGetName(SCIP_PROP *prop)
    Definition: prop.c:951
    SCIP_RETCODE SCIPsetPropExit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPEXIT((*propexit)))
    Definition: scip_prop.c:203
    void SCIPpropSetFreq(SCIP_PROP *prop, int freq)
    Definition: prop.c:1054
    SCIP_RETCODE SCIPsetPropInit(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPINIT((*propinit)))
    Definition: scip_prop.c:187
    SCIP_RETCODE SCIPsetPropFree(SCIP *scip, SCIP_PROP *prop, SCIP_DECL_PROPFREE((*propfree)))
    Definition: scip_prop.c:171
    SCIP_RETCODE SCIPincludePropBasic(SCIP *scip, SCIP_PROP **propptr, const char *name, const char *desc, int priority, int freq, SCIP_Bool delay, SCIP_PROPTIMING timingmask, SCIP_DECL_PROPEXEC((*propexec)), SCIP_PROPDATA *propdata)
    Definition: scip_prop.c:118
    SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
    Definition: var.c:17846
    SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:8257
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23538
    SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:8026
    memory allocation routines
    #define PROP_PRESOL_MAXROUNDS
    Definition: prop_sync.c:58
    #define PROP_PRESOLTIMING
    Definition: prop_sync.c:57
    #define PROP_DESC
    Definition: prop_sync.c:50
    static SCIP_DECL_PROPFREE(propFreeSync)
    Definition: prop_sync.c:156
    static SCIP_DECL_PROPEXEC(propExecSync)
    Definition: prop_sync.c:259
    #define PROP_NAME
    Definition: prop_sync.c:49
    static SCIP_DECL_PROPINIT(propInitSync)
    Definition: prop_sync.c:176
    static SCIP_DECL_PROPEXIT(propExitSync)
    Definition: prop_sync.c:200
    static SCIP_RETCODE applyBoundChanges(SCIP *scip, SCIP_PROPDATA *data, SCIP_RESULT *result, int *ntightened, int *ntightenedint)
    Definition: prop_sync.c:84
    #define PROP_DELAY
    Definition: prop_sync.c:53
    static SCIP_DECL_PROPPRESOL(propPresolSync)
    Definition: prop_sync.c:220
    #define PROP_TIMING
    Definition: prop_sync.c:54
    #define PROP_FREQ
    Definition: prop_sync.c:52
    #define PROP_PRIORITY
    Definition: prop_sync.c:51
    #define PROP_PRESOL_PRIORITY
    Definition: prop_sync.c:56
    propagator for applying global bound changes that were communicated by other concurrent solvers
    public methods for message output
    public methods for propagators
    public methods for problem variables
    public methods for memory management
    public methods for message handling
    public methods for the probing mode
    public methods for propagator plugins
    public methods for SCIP variables
    the type definitions for the SCIP parallel interface
    int SCIPtpiGetThreadNum(void)
    Definition: tpi_none.c:142
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    struct SCIP_PropData SCIP_PROPDATA
    Definition: type_prop.h:52
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ 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_VARSTATUS_MULTAGGR
    Definition: type_var.h:56