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 "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
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
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
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 )
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
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 )
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,...)
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)
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: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
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:84
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
@ SCIP_INVALIDCALL
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