SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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
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
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
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 )
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
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 )
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,...)
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)
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 SCIPsetPropFree(SCIP *scip, SCIP_PROP *prop,)
Definition scip_prop.c:171
void SCIPpropSetFreq(SCIP_PROP *prop, int freq)
Definition prop.c:1054
SCIP_RETCODE SCIPsetPropInit(SCIP *scip, SCIP_PROP *prop,)
Definition scip_prop.c:187
SCIP_RETCODE SCIPsetPropExit(SCIP *scip, SCIP_PROP *prop,)
Definition scip_prop.c:203
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
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR * var
memory allocation routines
#define PROP_PRESOL_MAXROUNDS
#define PROP_PRESOLTIMING
#define PROP_DESC
#define PROP_NAME
#define PROP_DELAY
#define PROP_TIMING
#define PROP_FREQ
#define PROP_PRIORITY
#define PROP_PRESOL_PRIORITY
static SCIP_RETCODE applyBoundChanges(SCIP *scip, SCIP_PROPDATA *data, SCIP_RESULT *result, int *ntightened, int *ntightenedint)
Definition prop_sync.c:85
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
#define SCIP_DECL_PROPINIT(x)
Definition type_prop.h:77
#define SCIP_DECL_PROPFREE(x)
Definition type_prop.h:69
#define SCIP_DECL_PROPEXIT(x)
Definition type_prop.h:85
struct SCIP_Prop SCIP_PROP
Definition type_prop.h:51
#define SCIP_DECL_PROPPRESOL(x)
Definition type_prop.h:193
struct SCIP_PropData SCIP_PROPDATA
Definition type_prop.h:52
#define SCIP_DECL_PROPEXEC(x)
Definition type_prop.h:217
@ 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
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:56