Scippy

    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 <string.h>
    47#include "tpi/tpi.h"
    48
    49/* fundamental propagator properties */
    50#define PROP_NAME "sync"
    51#define PROP_DESC "propagator for synchronization of bound changes"
    52#define PROP_PRIORITY (INT_MAX/4) /**< propagator priority */
    53#define PROP_FREQ -1 /**< propagator frequency */
    54#define PROP_DELAY FALSE /**< should propagation method be delayed, if other propagators found reductions? */
    55#define PROP_TIMING SCIP_PROPTIMING_ALWAYS /**< propagation timing mask */
    56
    57#define PROP_PRESOL_PRIORITY (INT_MAX/4) /**< priority of the presolving method (>= 0: before, < 0: after constraint handlers); combined with presolvers */
    58#define PROP_PRESOLTIMING SCIP_PRESOLTIMING_ALWAYS /* timing of the presolving method (fast, medium, or exhaustive) */
    59#define PROP_PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    60
    61/*
    62 * Data structures
    63 */
    64
    65/** propagator data */
    66struct SCIP_PropData
    67{
    68 SCIP_VAR** bndvar; /**< array of variables with a bound change */
    69 SCIP_Real* bndval; /**< array of new bound values */
    70 SCIP_BOUNDTYPE* bndtype; /**< array of bound types */
    71 int nbnds; /**< number of boundchanges */
    72 int bndsize; /**< current size of bound change array */
    73 SCIP_Longint ntightened; /**< number of tightened bounds */
    74 SCIP_Longint ntightenedint; /**< number of tightened bounds of integer variables */
    75};
    76
    77
    78/*
    79 * Local methods
    80 */
    81
    82
    83/** apply the stored bound changes */
    84static
    86 SCIP* scip, /**< SCIP data structure */
    87 SCIP_PROPDATA* data, /**< propagator data */
    88 SCIP_RESULT* result, /**< result of propagations */
    89 int* ntightened, /**< pointer to store the number of tightened bounds */
    90 int* ntightenedint /**< pointer to store the number of tightened integer bounds */
    91 )
    92{
    93 int i;
    94
    95 assert(data != NULL);
    96 assert(result != NULL);
    97 assert(ntightened != NULL);
    98 assert(ntightenedint != NULL);
    99
    100 *ntightened = 0;
    101 *ntightenedint = 0;
    102
    104 *result = SCIP_DIDNOTFIND;
    105
    106 for( i = 0; i < data->nbnds; ++i )
    107 {
    108 SCIP_Bool infeas;
    109 SCIP_Bool tightened;
    110
    111 SCIP_CALL( SCIPvarGetProbvarBound(&data->bndvar[i], &data->bndval[i], &data->bndtype[i]) );
    112
    113 /* cannot change bounds of multi-aggregated variables so skip this bound-change */
    114 if( SCIPvarGetStatus(data->bndvar[i]) == SCIP_VARSTATUS_MULTAGGR )
    115 continue;
    116
    117 if( data->bndtype[i] == SCIP_BOUNDTYPE_LOWER )
    118 {
    119 SCIP_CALL( SCIPtightenVarLbGlobal(scip, data->bndvar[i], data->bndval[i], FALSE, &infeas, &tightened) );
    120 }
    121 else
    122 {
    123 assert(data->bndtype[i] == SCIP_BOUNDTYPE_UPPER);
    124 SCIP_CALL( SCIPtightenVarUbGlobal(scip, data->bndvar[i], data->bndval[i], FALSE, &infeas, &tightened) );
    125 }
    126
    127 if( tightened )
    128 {
    129 ++(*ntightened);
    130 if( SCIPvarIsNonimpliedIntegral(data->bndvar[i]) )
    131 ++(*ntightenedint);
    132 }
    133
    134 if( infeas )
    135 {
    136#ifndef NDEBUG
    137 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "sync propagator found cutoff in thread %i.\n", SCIPtpiGetThreadNum());
    138#endif
    139 *result = SCIP_CUTOFF;
    140 break;
    141 }
    142 }
    143
    144 data->nbnds = 0;
    146
    147 return SCIP_OKAY;
    148}
    149
    150
    151/*
    152 * Callback methods of propagator
    153 */
    154
    155/** destructor of propagator to free user data (called when SCIP is exiting) */
    156static
    158{ /*lint --e{715}*/
    159 SCIP_PROPDATA* propdata;
    160
    161 assert(scip != NULL);
    162 assert(prop != NULL);
    163 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    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 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    182
    183 data = SCIPpropGetData(prop);
    184 assert(data != NULL);
    185
    186 data->bndsize = 0;
    187 data->nbnds = 0;
    188 data->bndvar = NULL;
    189 data->bndval = NULL;
    190 data->bndtype = NULL;
    191 data->ntightened = 0;
    192 data->ntightenedint = 0;
    193
    194 return SCIP_OKAY;
    195}
    196
    197/** deinitialization method of propagator (called before transformed problem is freed) */
    198static
    200{ /*lint --e{715}*/
    201 SCIP_PROPDATA* data;
    202
    203 assert(prop != NULL);
    204 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    205
    206 data = SCIPpropGetData(prop);
    207 assert(data != NULL);
    208
    209 SCIPfreeBlockMemoryArrayNull(scip, &data->bndvar, data->bndsize);
    210 SCIPfreeBlockMemoryArrayNull(scip, &data->bndval, data->bndsize);
    211 SCIPfreeBlockMemoryArrayNull(scip, &data->bndtype, data->bndsize);
    212
    213 return SCIP_OKAY;
    214}
    215
    216/** presolving method of propagator */
    217static
    218SCIP_DECL_PROPPRESOL(propPresolSync)
    219{ /*lint --e{715}*/
    220 SCIP_PROPDATA* data;
    221 int ntightened;
    222 int ntightenedint;
    223
    224 assert(prop != NULL);
    225 assert(result != NULL);
    226 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    227
    228 data = SCIPpropGetData(prop);
    229 assert(data != NULL);
    230
    231 *result = SCIP_DIDNOTRUN;
    232
    233 if( data->nbnds == 0 || SCIPinProbing(scip) )
    234 return SCIP_OKAY;
    235
    236 /* remember number of tightened bounds before applying new bound tightenings */
    237 SCIP_CALL( applyBoundChanges(scip, data, result, &ntightened, &ntightenedint) );
    238
    239 /* add number of tightened bounds to the total number of presolving boundchanges */
    240 if( ntightened > 0 )
    241 {
    242 *nchgbds += ntightened;
    243 data->ntightened += ntightened;
    244 data->ntightenedint += ntightened;
    245 if( *result != SCIP_CUTOFF )
    246 *result = SCIP_SUCCESS;
    247 }
    248
    249 SCIPpropSetFreq(prop, -1);
    250
    251 return SCIP_OKAY;
    252}
    253
    254/** execution method of propagator */
    255static
    257{ /*lint --e{715}*/
    258 SCIP_PROPDATA* data;
    259 int ntightened;
    260 int ntightenedint;
    261
    262 assert(prop != NULL);
    263 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    264
    265 *result = SCIP_DIDNOTRUN;
    266
    267 if( SCIPinProbing(scip) )
    268 return SCIP_OKAY;
    269
    270 data = SCIPpropGetData(prop);
    271 assert(data != NULL);
    272
    273 SCIP_CALL( applyBoundChanges(scip, data, result, &ntightened, &ntightenedint) );
    274
    275 if( ntightened > 0 )
    276 {
    277 data->ntightened += ntightened;
    278 data->ntightenedint += ntightenedint;
    279 if( *result != SCIP_CUTOFF )
    280 *result = SCIP_REDUCEDDOM;
    281 }
    282
    283 SCIPpropSetFreq(prop, -1);
    284
    285 return SCIP_OKAY;
    286}
    287
    288/*
    289 * propagator specific interface methods
    290 */
    291
    292/** creates the sync propagator and includes it in SCIP */
    294 SCIP* scip /**< SCIP data structure */
    295 )
    296{
    297 SCIP_PROPDATA* propdata = NULL;
    298 SCIP_PROP* prop = NULL;
    299
    300 SCIP_CALL( SCIPallocBlockMemory(scip, &propdata) );
    301
    302 /* include propagator */
    304 propExecSync, propdata) );
    305 assert(prop != NULL);
    306
    307 /* set optional callbacks via setter functions */
    308 SCIP_CALL( SCIPsetPropFree(scip, prop, propFreeSync) );
    309 SCIP_CALL( SCIPsetPropInit(scip, prop, propInitSync) );
    310 SCIP_CALL( SCIPsetPropExit(scip, prop, propExitSync) );
    312
    313 return SCIP_OKAY;
    314}
    315
    316
    317/** adds a boundchange to the sync propagator */
    319 SCIP* scip, /**< SCIP data structure */
    320 SCIP_PROP* prop, /**< sync propagator */
    321 SCIP_VAR* var, /**< variable for bound */
    322 SCIP_Real val, /**< value of bound */
    323 SCIP_BOUNDTYPE bndtype /**< type of bound */
    324 )
    325{
    326 SCIP_PROPDATA* data;
    327
    328 assert(prop != NULL);
    329 assert(strcmp(SCIPpropGetName(prop), PROP_NAME) == 0);
    330
    331 data = SCIPpropGetData(prop);
    332 assert(data != NULL);
    333
    334 if( data->nbnds + 1 > data->bndsize )
    335 {
    336 int newsize;
    337 newsize = SCIPcalcMemGrowSize(scip, data->nbnds+1);
    338 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndvar, data->bndsize, newsize) );
    339 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndval, data->bndsize, newsize) );
    340 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &data->bndtype, data->bndsize, newsize) );
    341 data->bndsize = newsize;
    342 }
    343
    344 data->bndvar[data->nbnds] = var;
    345 data->bndval[data->nbnds] = val;
    346 data->bndtype[data->nbnds] = bndtype;
    347
    348 if( data->nbnds == 0 )
    349 {
    350 SCIPpropSetFreq(prop, 1);
    351 }
    352 ++data->nbnds;
    353
    354 return SCIP_OKAY;
    355}
    356
    357/** returns the total number of tightened bounds found by the sync propagator */
    359 SCIP_PROP* prop /**< sync propagator */
    360 )
    361{
    362 SCIP_PROPDATA* data;
    363
    364 assert(prop != NULL);
    365
    366 data = SCIPpropGetData(prop);
    367 assert(data != NULL);
    368
    369 return data->ntightened;
    370}
    371
    372/** returns the total number of tightened bounds for integer variables found by the sync propagator */
    374 SCIP_PROP* prop /**< sync propagator */
    375 )
    376{
    377 SCIP_PROPDATA* data;
    378
    379 assert(prop != NULL);
    380
    381 data = SCIPpropGetData(prop);
    382 assert(data != NULL);
    383
    384 return data->ntightenedint;
    385}
    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:255
    #define SCIP_Longint
    Definition: def.h:148
    #define SCIP_Bool
    Definition: def.h:98
    #define SCIP_Real
    Definition: def.h:163
    #define FALSE
    Definition: def.h:101
    #define SCIP_CALL(x)
    Definition: def.h:362
    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:358
    SCIP_RETCODE SCIPpropSyncAddBndchg(SCIP *scip, SCIP_PROP *prop, SCIP_VAR *var, SCIP_Real val, SCIP_BOUNDTYPE bndtype)
    Definition: prop_sync.c:318
    SCIP_Longint SCIPpropSyncGetNTightenedIntBnds(SCIP_PROP *prop)
    Definition: prop_sync.c:373
    SCIP_RETCODE SCIPincludePropSync(SCIP *scip)
    Definition: prop_sync.c:293
    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:17801
    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:23386
    SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23506
    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:59
    #define PROP_PRESOLTIMING
    Definition: prop_sync.c:58
    #define PROP_DESC
    Definition: prop_sync.c:51
    static SCIP_DECL_PROPFREE(propFreeSync)
    Definition: prop_sync.c:157
    static SCIP_DECL_PROPEXEC(propExecSync)
    Definition: prop_sync.c:256
    #define PROP_NAME
    Definition: prop_sync.c:50
    static SCIP_DECL_PROPINIT(propInitSync)
    Definition: prop_sync.c:176
    static SCIP_DECL_PROPEXIT(propExitSync)
    Definition: prop_sync.c:199
    static SCIP_RETCODE applyBoundChanges(SCIP *scip, SCIP_PROPDATA *data, SCIP_RESULT *result, int *ntightened, int *ntightenedint)
    Definition: prop_sync.c:85
    #define PROP_DELAY
    Definition: prop_sync.c:54
    static SCIP_DECL_PROPPRESOL(propPresolSync)
    Definition: prop_sync.c:218
    #define PROP_TIMING
    Definition: prop_sync.c:55
    #define PROP_FREQ
    Definition: prop_sync.c:53
    #define PROP_PRIORITY
    Definition: prop_sync.c:52
    #define PROP_PRESOL_PRIORITY
    Definition: prop_sync.c:57
    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
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56