Scippy

SCIP

Solving Constraint Integer Programs

scip_solve.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-2024 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 scip_solve.c
26 * @ingroup OTHER_CFILES
27 * @brief public solving methods
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Gerald Gamrath
31 * @author Leona Gottwald
32 * @author Stefan Heinz
33 * @author Gregor Hendel
34 * @author Thorsten Koch
35 * @author Alexander Martin
36 * @author Marc Pfetsch
37 * @author Michael Winkler
38 * @author Kati Wolter
39 *
40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
46#include "scip/branch.h"
47#include "scip/clock.h"
48#include "scip/compr.h"
49#include "scip/concsolver.h"
50#include "scip/concurrent.h"
51#include "scip/conflict.h"
52#include "scip/conflictstore.h"
53#include "scip/cons.h"
54#include "scip/cutpool.h"
55#include "scip/dcmp.h"
56#include "scip/debug.h"
57#include "scip/event.h"
58#include "scip/implics.h"
59#include "scip/interrupt.h"
60#include "scip/lp.h"
61#include "scip/nlp.h"
62#include "scip/presol.h"
63#include "scip/pricestore.h"
64#include "scip/primal.h"
65#include "scip/prob.h"
66#include "scip/prop.h"
67#include "scip/pub_branch.h"
68#include "scip/pub_compr.h"
69#include "scip/pub_cons.h"
70#include "scip/pub_heur.h"
71#include "scip/pub_message.h"
72#include "scip/pub_misc.h"
74#include "scip/pub_presol.h"
75#include "scip/pub_prop.h"
76#include "scip/pub_sol.h"
77#include "scip/pub_var.h"
78#include "scip/relax.h"
79#include "scip/reopt.h"
80#include "scip/scip_benders.h"
81#include "scip/scip_branch.h"
83#include "scip/scip_cons.h"
84#include "scip/scip_general.h"
85#include "scip/scip_lp.h"
86#include "scip/scip_mem.h"
87#include "scip/scip_message.h"
88#include "scip/scip_numerics.h"
89#include "scip/scip_param.h"
90#include "scip/scip_prob.h"
92#include "scip/scip_sol.h"
93#include "scip/scip_solve.h"
95#include "scip/scip_timing.h"
96#include "scip/scip_tree.h"
97#include "scip/scip_var.h"
98#include "scip/sepastore.h"
99#include "scip/set.h"
100#include "scip/sol.h"
101#include "scip/solve.h"
102#include "scip/stat.h"
103#include "scip/struct_event.h"
104#include "scip/struct_mem.h"
105#include "scip/struct_primal.h"
106#include "scip/struct_prob.h"
107#include "scip/struct_scip.h"
108#include "scip/struct_set.h"
109#include "scip/struct_stat.h"
110#include "scip/struct_tree.h"
111#include "scip/syncstore.h"
112#include "scip/tree.h"
113#include "scip/var.h"
114#include "scip/visual.h"
115#include "tpi/tpi.h"
116
117/** calculates number of nonzeros in problem */
118static
120 SCIP* scip, /**< SCIP data structure */
121 SCIP_Longint* nchecknonzeros, /**< pointer to store number of non-zeros in all check constraints */
122 SCIP_Longint* nactivenonzeros, /**< pointer to store number of non-zeros in all active constraints */
123 SCIP_Bool* approxchecknonzeros,/**< pointer to store if the number of non-zeros in all check constraints
124 * is only a lowerbound
125 */
126 SCIP_Bool* approxactivenonzeros/**< pointer to store if the number of non-zeros in all active constraints
127 * is only a lowerbound
128 */
129 )
130{
131 SCIP_CONS** conss;
132 SCIP_Bool success;
133 SCIP_Bool ischeck;
134 int nconss;
135 int nvars;
136 int c;
137 int h;
138
139 *nchecknonzeros = 0LL;
140 *nactivenonzeros = 0LL;
141 *approxchecknonzeros = FALSE;
142 *approxactivenonzeros = FALSE;
143
144 /* computes number of non-zeros over all active constraints */
145 for( h = scip->set->nconshdlrs - 1; h >= 0; --h )
146 {
147 nconss = SCIPconshdlrGetNActiveConss(scip->set->conshdlrs[h]);
148
149 if( nconss > 0 )
150 {
151 conss = SCIPconshdlrGetConss(scip->set->conshdlrs[h]);
152
153 /* calculate all active constraints */
154 for( c = nconss - 1; c >= 0; --c )
155 {
156 SCIP_CALL( SCIPconsGetNVars(conss[c], scip->set, &nvars, &success) );
157 ischeck = SCIPconsIsChecked(conss[c]);
158
159 if( !success )
160 {
161 *approxactivenonzeros = TRUE;
162 if( ischeck )
163 *approxchecknonzeros = TRUE;
164 }
165 else
166 {
167 *nactivenonzeros += nvars;
168 if( ischeck )
169 *nchecknonzeros += nvars;
170 }
171 }
172 }
173
174 /* add nonzeros on inactive check constraints */
175 nconss = SCIPconshdlrGetNCheckConss(scip->set->conshdlrs[h]);
176 if( nconss > 0 )
177 {
178 conss = SCIPconshdlrGetCheckConss(scip->set->conshdlrs[h]);
179
180 for( c = nconss - 1; c >= 0; --c )
181 {
182 if( !SCIPconsIsActive(conss[c]) )
183 {
184 SCIP_CALL( SCIPconsGetNVars(conss[c], scip->set, &nvars, &success) );
185
186 if( !success )
187 *approxchecknonzeros = TRUE;
188 else
189 *nchecknonzeros += nvars;
190 }
191 }
192 }
193 }
194
195 return SCIP_OKAY;
196}
197
198
199/** initializes solving data structures and transforms problem
200 *
201 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
202 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
203 *
204 * @pre This method can be called if @p scip is in one of the following stages:
205 * - \ref SCIP_STAGE_PROBLEM
206 * - \ref SCIP_STAGE_TRANSFORMED
207 * - \ref SCIP_STAGE_INITPRESOLVE
208 * - \ref SCIP_STAGE_PRESOLVING
209 * - \ref SCIP_STAGE_EXITPRESOLVE
210 * - \ref SCIP_STAGE_PRESOLVED
211 * - \ref SCIP_STAGE_INITSOLVE
212 * - \ref SCIP_STAGE_SOLVING
213 * - \ref SCIP_STAGE_SOLVED
214 * - \ref SCIP_STAGE_EXITSOLVE
215 * - \ref SCIP_STAGE_FREETRANS
216 * - \ref SCIP_STAGE_FREE
217 *
218 * @post When calling this method in the \ref SCIP_STAGE_PROBLEM stage, the \SCIP stage is changed to \ref
219 * SCIP_STAGE_TRANSFORMED; otherwise, the stage is not changed
220 *
221 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
222 */
224 SCIP* scip /**< SCIP data structure */
225 )
226{
227 SCIP_Longint oldnsolsfound;
228 int nfeassols;
229 int ncandsols;
230 int h;
231 int s;
232
233 SCIP_CALL( SCIPcheckStage(scip, "SCIPtransformProb", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
234
235 /* check, if the problem was already transformed */
236 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED )
237 return SCIP_OKAY;
238
239 assert(scip->stat->status == SCIP_STATUS_UNKNOWN);
240
241 /* check, if a node selector exists */
242 if( SCIPsetGetNodesel(scip->set, scip->stat) == NULL )
243 {
244 SCIPerrorMessage("no node selector available\n");
245 return SCIP_PLUGINNOTFOUND;
246 }
247
248 /* call garbage collector on original problem and parameter settings memory spaces */
250 BMSgarbagecollectBlockMemory(scip->mem->probmem);
251
252 /* remember number of constraints */
253 SCIPprobMarkNConss(scip->origprob);
254
255 /* switch stage to TRANSFORMING */
256 scip->set->stage = SCIP_STAGE_TRANSFORMING;
257
258 /* mark statistics before solving */
259 SCIPstatMark(scip->stat);
260
261 /* init solve data structures */
262 SCIP_CALL( SCIPeventfilterCreate(&scip->eventfilter, scip->mem->probmem) );
263 SCIP_CALL( SCIPeventqueueCreate(&scip->eventqueue) );
264 SCIP_CALL( SCIPbranchcandCreate(&scip->branchcand) );
265 SCIP_CALL( SCIPlpCreate(&scip->lp, scip->set, scip->messagehdlr, scip->stat, SCIPprobGetName(scip->origprob)) );
266 SCIP_CALL( SCIPprimalCreate(&scip->primal) );
267 SCIP_CALL( SCIPtreeCreate(&scip->tree, scip->mem->probmem, scip->set, SCIPsetGetNodesel(scip->set, scip->stat)) );
268 SCIP_CALL( SCIPrelaxationCreate(&scip->relaxation, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree) );
269 SCIP_CALL( SCIPconflictCreate(&scip->conflict, scip->mem->probmem, scip->set) );
270 SCIP_CALL( SCIPcliquetableCreate(&scip->cliquetable, scip->set, scip->mem->probmem) );
271
272 /* copy problem in solve memory */
273 SCIP_CALL( SCIPprobTransform(scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree,
274 scip->reopt, scip->lp, scip->branchcand, scip->eventfilter, scip->eventqueue, scip->conflictstore,
275 &scip->transprob) );
276
277 /* switch stage to TRANSFORMED */
278 scip->set->stage = SCIP_STAGE_TRANSFORMED;
279
280 /* check, whether objective value is always integral by inspecting the problem, if it is the case adjust the
281 * cutoff bound if primal solution is already known
282 */
283 SCIP_CALL( SCIPprobCheckObjIntegral(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
284 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
285
286 /* if possible, scale objective function such that it becomes integral with gcd 1 */
287 SCIP_CALL( SCIPprobScaleObj(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
288 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
289
290 /* check solution of solution candidate storage */
291 nfeassols = 0;
292 ncandsols = scip->origprimal->nsols;
293 oldnsolsfound = 0;
294
295 /* update upper bound and cutoff bound due to objective limit in primal data */
296 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
297 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
298
299 /* do not consider original solutions of a benders decomposition because their cost information is incomplete */
300 if( !scip->set->reopt_enable && scip->set->nactivebenders == 0 )
301 {
302 oldnsolsfound = scip->primal->nsolsfound;
303 for( s = scip->origprimal->nsols - 1; s >= 0; --s )
304 {
305 SCIP_Bool feasible;
306 SCIP_SOL* sol;
307
308 sol = scip->origprimal->sols[s];
309
310 /* recompute objective function, since the objective might have changed in the meantime */
311 SCIPsolRecomputeObj(sol, scip->set, scip->stat, scip->origprob);
312
313 /* SCIPprimalTrySol() can only be called on transformed solutions; therefore check solutions in original problem
314 * including modifiable constraints
315 */
316 SCIP_CALL( SCIPsolCheckOrig(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal,
317 (scip->set->disp_verblevel >= SCIP_VERBLEVEL_HIGH ? scip->set->misc_printreason : FALSE),
318 FALSE, TRUE, TRUE, TRUE, TRUE, &feasible) );
319
320 if( feasible )
321 {
322 SCIP_Real abssolobj;
323
324 abssolobj = REALABS(SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
325
326 /* we do not want to add solutions with objective value +infinity */
327 if( !SCIPisInfinity(scip, abssolobj) )
328 {
329 SCIP_SOL* bestsol = SCIPgetBestSol(scip);
330 SCIP_Bool stored;
331
332 /* add primal solution to solution storage by copying it */
333 SCIP_CALL( SCIPprimalAddSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob,
334 scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, sol, &stored) );
335
336 if( stored )
337 {
338 nfeassols++;
339
340 if( bestsol != SCIPgetBestSol(scip) )
342 }
343 }
344 }
345
346 SCIP_CALL( SCIPsolFree(&sol, scip->mem->probmem, scip->origprimal) );
347 scip->origprimal->nsols--;
348 }
349 }
350
351 assert(scip->origprimal->nsols == 0);
352
353 scip->stat->nexternalsolsfound += scip->primal->nsolsfound - oldnsolsfound;
354
355 if( nfeassols > 0 )
356 {
357 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
358 "%d/%d feasible solution%s given by solution candidate storage, new primal bound %.6e\n\n",
359 nfeassols, ncandsols, (nfeassols > 1 ? "s" : ""), SCIPgetSolOrigObj(scip, SCIPgetBestSol(scip)));
360 }
361 else if( ncandsols > 0 && !scip->set->reopt_enable )
362 {
363 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
364 "all %d solutions given by solution candidate storage are infeasible\n\n", ncandsols);
365 }
366
367 /* print transformed problem statistics */
368 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
369 "transformed problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
370 scip->transprob->nvars, scip->transprob->nbinvars, scip->transprob->nintvars, scip->transprob->nimplvars,
371 scip->transprob->ncontvars, scip->transprob->nconss);
372
373 for( h = 0; h < scip->set->nconshdlrs; ++h )
374 {
375 int nactiveconss;
376
377 nactiveconss = SCIPconshdlrGetNActiveConss(scip->set->conshdlrs[h]);
378 if( nactiveconss > 0 )
379 {
380 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
381 "%7d constraints of type <%s>\n", nactiveconss, SCIPconshdlrGetName(scip->set->conshdlrs[h]));
382 }
383 }
384 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
385
386 {
387 SCIP_Real maxnonzeros;
388 SCIP_Longint nchecknonzeros;
389 SCIP_Longint nactivenonzeros;
390 SCIP_Bool approxchecknonzeros;
391 SCIP_Bool approxactivenonzeros;
392
393 /* determine number of non-zeros */
394 maxnonzeros = (SCIP_Real)SCIPgetNConss(scip) * SCIPgetNVars(scip);
395 maxnonzeros = MAX(maxnonzeros, 1.0);
396 SCIP_CALL( calcNonZeros(scip, &nchecknonzeros, &nactivenonzeros, &approxchecknonzeros, &approxactivenonzeros) );
397 scip->stat->nnz = nactivenonzeros;
398 scip->stat->avgnnz = (SCIPgetNConss(scip) == 0 ? 0.0 : (SCIP_Real) nactivenonzeros / ((SCIP_Real) SCIPgetNConss(scip)));
399
400 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
401 "original problem has %s%" SCIP_LONGINT_FORMAT " active (%g%%) nonzeros and %s%" SCIP_LONGINT_FORMAT " (%g%%) check nonzeros\n",
402 approxactivenonzeros ? "more than " : "", nactivenonzeros, nactivenonzeros/maxnonzeros * 100,
403 approxchecknonzeros ? "more than " : "", nchecknonzeros, nchecknonzeros/maxnonzeros * 100);
404 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
405 }
406
407 /* call initialization methods of plugins */
408 SCIP_CALL( SCIPsetInitPlugins(scip->set, scip->mem->probmem, scip->stat) );
409
410 /* in case the permutation seed is different to 0, permute the transformed problem */
411 if( scip->set->random_permutationseed > 0 )
412 {
413 SCIP_Bool permuteconss;
414 SCIP_Bool permutevars;
415 int permutationseed;
416
417 permuteconss = scip->set->random_permuteconss;
418 permutevars = scip->set->random_permutevars;
419 permutationseed = scip->set->random_permutationseed;
420
421 SCIP_CALL( SCIPpermuteProb(scip, (unsigned int)permutationseed, permuteconss, permutevars, permutevars, permutevars, permutevars) );
422 }
423
424 if( scip->set->misc_estimexternmem )
425 {
426 /* the following formula was estimated empirically using linear regression */
427 scip->stat->externmemestim = (SCIP_Longint) (MAX(1, 8.5e-04 * SCIPgetNConss(scip) + 7.6e-04 * SCIPgetNVars(scip) + 3.5e-05 * scip->stat->nnz) * 1048576.0); /*lint !e666*/
428 SCIPdebugMsg(scip, "external memory usage estimated to %" SCIP_LONGINT_FORMAT " byte\n", scip->stat->externmemestim);
429 }
430
431 return SCIP_OKAY;
432}
433
434/** initializes presolving */
435static
437 SCIP* scip /**< SCIP data structure */
438 )
439{
440#ifndef NDEBUG
441 size_t nusedbuffers;
442 size_t nusedcleanbuffers;
443#endif
444
445 assert(scip != NULL);
446 assert(scip->mem != NULL);
447 assert(scip->set != NULL);
448 assert(scip->stat != NULL);
449 assert(scip->transprob != NULL);
450 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
451
452 /* reset statistics for presolving and current branch and bound run */
453 SCIPstatResetPresolving(scip->stat, scip->set, scip->transprob, scip->origprob);
454
455 /* increase number of branch and bound runs */
456 scip->stat->nruns++;
457
458 /* remember problem size of previous run */
459 scip->stat->prevrunnvars = scip->transprob->nvars;
460
461 /* switch stage to INITPRESOLVE */
462 scip->set->stage = SCIP_STAGE_INITPRESOLVE;
463
464 /* create temporary presolving root node */
465 SCIP_CALL( SCIPtreeCreatePresolvingRoot(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr,
466 scip->stat, scip->transprob, scip->origprob, scip->primal, scip->lp, scip->branchcand, scip->conflict,
467 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable) );
468
469 /* retransform all existing solutions to original problem space, because the transformed problem space may
470 * get modified in presolving and the solutions may become invalid for the transformed problem
471 */
472 SCIP_CALL( SCIPprimalRetransformSolutions(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
473 scip->eventqueue, scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp) );
474
475 /* initialize lower bound of the presolving root node if a valid dual bound is at hand */
476 if( scip->transprob->dualbound != SCIP_INVALID ) /*lint !e777*/
477 {
478 scip->tree->root->lowerbound = SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, scip->transprob->dualbound);
479 scip->tree->root->estimate = scip->tree->root->lowerbound;
480 scip->stat->rootlowerbound = scip->tree->root->lowerbound;
481
482 if( scip->set->misc_calcintegral )
483 SCIPstatUpdatePrimalDualIntegrals(scip->stat, scip->set, scip->transprob, scip->origprob, SCIPinfinity(scip), scip->tree->root->lowerbound);
484 }
485
486 /* GCG wants to perform presolving during the reading process of a file reader;
487 * hence the number of used buffers does not need to be zero, however, it should not
488 * change by calling SCIPsetInitprePlugins()
489 */
490#ifndef NDEBUG
491 nusedbuffers = BMSgetNUsedBufferMemory(SCIPbuffer(scip));
492 nusedcleanbuffers = BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip));
493#endif
494
495 /* inform plugins that the presolving is abound to begin */
496 SCIP_CALL( SCIPsetInitprePlugins(scip->set, scip->mem->probmem, scip->stat) );
497 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
498 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
499
500 /* delete the variables from the problems that were marked to be deleted */
501 SCIP_CALL( SCIPprobPerformVarDeletions(scip->transprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp, scip->branchcand) );
502
503 /* switch stage to PRESOLVING */
504 scip->set->stage = SCIP_STAGE_PRESOLVING;
505
506 return SCIP_OKAY;
507}
508
509/** deinitializes presolving */
510static
512 SCIP* scip, /**< SCIP data structure */
513 SCIP_Bool solved, /**< is problem already solved? */
514 SCIP_Bool* infeasible /**< pointer to store if the clique clean up detects an infeasibility */
515 )
516{
517#ifndef NDEBUG
518 size_t nusedbuffers;
519 size_t nusedcleanbuffers;
520#endif
521
522 assert(scip != NULL);
523 assert(scip->mem != NULL);
524 assert(scip->set != NULL);
525 assert(scip->stat != NULL);
526 assert(scip->transprob != NULL);
527 assert(scip->set->stage == SCIP_STAGE_PRESOLVING);
528 assert(infeasible != NULL);
529
530 *infeasible = FALSE;
531
532 /* switch stage to EXITPRESOLVE */
533 scip->set->stage = SCIP_STAGE_EXITPRESOLVE;
534
535 if( !solved )
536 {
537 SCIP_VAR** vars;
538 int nvars;
539 int v;
540
541 /* flatten all variables */
542 vars = SCIPgetFixedVars(scip);
543 nvars = SCIPgetNFixedVars(scip);
544 assert(nvars == 0 || vars != NULL);
545
546 for( v = nvars - 1; v >= 0; --v )
547 {
548 SCIP_VAR* var;
549#ifndef NDEBUG
550 SCIP_VAR** multvars;
551 int i;
552#endif
553 var = vars[v]; /*lint !e613*/
554 assert(var != NULL);
555
557 {
558 /* flattens aggregation graph of multi-aggregated variable in order to avoid exponential recursion later-on */
559 SCIP_CALL( SCIPvarFlattenAggregationGraph(var, scip->mem->probmem, scip->set, scip->eventqueue) );
560
561#ifndef NDEBUG
562 multvars = SCIPvarGetMultaggrVars(var);
563 for( i = SCIPvarGetMultaggrNVars(var) - 1; i >= 0; --i)
564 assert(SCIPvarGetStatus(multvars[i]) != SCIP_VARSTATUS_MULTAGGR);
565#endif
566 }
567 }
568 }
569
570 /* exitPresolve() might be called during the reading process of a file reader;
571 * hence the number of used buffers does not need to be zero, however, it should not
572 * change by calling SCIPsetExitprePlugins() or SCIPprobExitPresolve()
573 */
574#ifndef NDEBUG
575 nusedbuffers = BMSgetNUsedBufferMemory(SCIPbuffer(scip));
576 nusedcleanbuffers = BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip));
577#endif
578
579 /* inform plugins that the presolving is finished, and perform final modifications */
580 SCIP_CALL( SCIPsetExitprePlugins(scip->set, scip->mem->probmem, scip->stat) );
581 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
582 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
583
584 /* remove empty and single variable cliques from the clique table, and convert all two variable cliques
585 * into implications
586 * delete the variables from the problems that were marked to be deleted
587 */
588 if( !solved )
589 {
590 int nlocalbdchgs = 0;
591
592 SCIP_CALL( SCIPprobPerformVarDeletions(scip->transprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue,
593 scip->cliquetable, scip->lp, scip->branchcand) );
594
595 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
596 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
597 infeasible) );
598
599 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
600 "clique table cleanup detected %d bound changes%s\n", nlocalbdchgs, *infeasible ? " and infeasibility" : "");
601 }
602
603 /* exit presolving */
604 SCIP_CALL( SCIPprobExitPresolve(scip->transprob, scip->set) );
605 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
606 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
607
608 if( !solved )
609 {
610 /* check, whether objective value is always integral by inspecting the problem, if it is the case adjust the
611 * cutoff bound if primal solution is already known
612 */
613 SCIP_CALL( SCIPprobCheckObjIntegral(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
614 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
615
616 /* if possible, scale objective function such that it becomes integral with gcd 1 */
617 SCIP_CALL( SCIPprobScaleObj(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
618 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
619 }
620
621 /* free temporary presolving root node */
622 SCIP_CALL( SCIPtreeFreePresolvingRoot(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr,
623 scip->stat, scip->transprob, scip->origprob, scip->primal, scip->lp, scip->branchcand, scip->conflict,
624 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable) );
625
626 /* switch stage to PRESOLVED */
627 scip->set->stage = SCIP_STAGE_PRESOLVED;
628
629 return SCIP_OKAY;
630}
631
632/** applies one round of presolving with the given presolving timing
633 *
634 * This method will always be called with presoltiming fast first. It iterates over all presolvers, propagators, and
635 * constraint handlers and calls their presolving callbacks with timing fast. If enough reductions are found, it
636 * returns and the next presolving round will be started (again with timing fast). If the fast presolving does not
637 * find enough reductions, this methods calls itself recursively with presoltiming medium. Again, it calls the
638 * presolving callbacks of all presolvers, propagators, and constraint handlers with timing medium. If enough
639 * reductions are found, it returns and the next presolving round will be started (with timing fast). Otherwise, it is
640 * called recursively with presoltiming exhaustive. In exhaustive presolving, presolvers, propagators, and constraint
641 * handlers are called w.r.t. their priority, but this time, we stop as soon as enough reductions were found and do not
642 * necessarily call all presolving methods. If we stop, we return and another presolving round is started with timing
643 * fast.
644 *
645 * @todo check if we want to do the following (currently disabled):
646 * In order to avoid calling the same expensive presolving methods again and again (which is possibly ineffective
647 * for the current instance), we continue the loop for exhaustive presolving where we stopped it the last time. The
648 * {presol/prop/cons}start pointers are used to this end: they provide the plugins to start the loop with in the
649 * current presolving round (if we reach exhaustive presolving), and are updated in this case to the next ones to be
650 * called in the next round. In case we reach the end of the loop in exhaustive presolving, we call the method again
651 * with exhaustive timing, now starting with the first presolving steps in the loop until we reach the ones we started
652 * the last call with. This way, we won't stop until all exhaustive presolvers were called without finding enough
653 * reductions (in sum).
654 */
655static
657 SCIP* scip, /**< SCIP data structure */
658 SCIP_PRESOLTIMING* timing, /**< pointer to current presolving timing */
659 SCIP_Bool* unbounded, /**< pointer to store whether presolving detected unboundedness */
660 SCIP_Bool* infeasible, /**< pointer to store whether presolving detected infeasibility */
661 SCIP_Bool lastround, /**< is this the last presolving round due to a presolving round limit? */
662 int* presolstart, /**< pointer to get the presolver to start exhaustive presolving with in
663 * the current round and store the one to start with in the next round */
664 int presolend, /**< last presolver to treat in exhaustive presolving */
665 int* propstart, /**< pointer to get the propagator to start exhaustive presolving with in
666 * the current round and store the one to start with in the next round */
667 int propend, /**< last propagator to treat in exhaustive presolving */
668 int* consstart, /**< pointer to get the constraint handler to start exhaustive presolving with in
669 * the current round and store the one to start with in the next round */
670 int consend /**< last constraint handler to treat in exhaustive presolving */
671 )
672{
673 SCIP_RESULT result;
674 SCIP_EVENT event;
675 SCIP_Bool aborted;
676 SCIP_Bool lastranpresol;
677#ifdef SCIP_DISABLED_CODE
678 int oldpresolstart = 0;
679 int oldpropstart = 0;
680 int oldconsstart = 0;
681#endif
682 int priopresol;
683 int prioprop;
684 int i;
685 int j;
686 int k;
687#ifndef NDEBUG
688 size_t nusedbuffers;
689 size_t nusedcleanbuffers;
690#endif
691
692 assert(scip != NULL);
693 assert(scip->set != NULL);
694 assert(unbounded != NULL);
695 assert(infeasible != NULL);
696 assert(presolstart != NULL);
697 assert(propstart != NULL);
698 assert(consstart != NULL);
699
700 assert((presolend == scip->set->npresols && propend == scip->set->nprops && consend == scip->set->nconshdlrs)
701 || (*presolstart == 0 && *propstart == 0 && *consstart == 0));
702
703 *unbounded = FALSE;
704 *infeasible = FALSE;
705 aborted = FALSE;
706
707 assert( scip->set->propspresolsorted );
708
709 /* GCG wants to perform presolving during the reading process of a file reader;
710 * hence the number of used buffers does not need to be zero, however, it should not
711 * change by calling the presolving callbacks
712 */
713#ifndef NDEBUG
714 nusedbuffers = BMSgetNUsedBufferMemory(SCIPbuffer(scip));
715 nusedcleanbuffers = BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip));
716#endif
717
718 if( *timing == SCIP_PRESOLTIMING_EXHAUSTIVE )
719 {
720 /* In exhaustive presolving, we continue the loop where we stopped last time to avoid calling the same
721 * (possibly ineffective) presolving step again and again. If we reach the end of the arrays of presolvers,
722 * propagators, and constraint handlers without having made enough reductions, we start again from the beginning
723 */
724 i = *presolstart;
725 j = *propstart;
726 k = *consstart;
727#ifdef SCIP_DISABLED_CODE
728 oldpresolstart = i;
729 oldpropstart = j;
730 oldconsstart = k;
731#endif
732 if( i >= presolend && j >= propend && k >= consend )
733 return SCIP_OKAY;
734
735 if( i == 0 && j == 0 && k == 0 )
736 ++(scip->stat->npresolroundsext);
737 }
738 else
739 {
740 /* in fast and medium presolving, we always iterate over all presolvers, propagators, and constraint handlers */
741 assert(presolend == scip->set->npresols);
742 assert(propend == scip->set->nprops);
743 assert(consend == scip->set->nconshdlrs);
744
745 i = 0;
746 j = 0;
747 k = 0;
748
749 if( *timing == SCIP_PRESOLTIMING_FAST )
750 ++(scip->stat->npresolroundsfast);
751 if( *timing == SCIP_PRESOLTIMING_MEDIUM )
752 ++(scip->stat->npresolroundsmed);
753 }
754
755 SCIPdebugMsg(scip, "starting presolving round %d (%d/%d/%d), timing = %u\n",
756 scip->stat->npresolrounds, scip->stat->npresolroundsfast, scip->stat->npresolroundsmed,
757 scip->stat->npresolroundsext, *timing);
758
759 /* call included presolvers with nonnegative priority */
760 while( !(*unbounded) && !(*infeasible) && !aborted && (i < presolend || j < propend) )
761 {
762 if( i < presolend )
763 priopresol = SCIPpresolGetPriority(scip->set->presols[i]);
764 else
765 priopresol = -1;
766
767 if( j < propend )
768 prioprop = SCIPpropGetPresolPriority(scip->set->props_presol[j]);
769 else
770 prioprop = -1;
771
772 /* call next propagator */
773 if( prioprop >= priopresol )
774 {
775 /* only presolving methods which have non-negative priority will be called before constraint handlers */
776 if( prioprop < 0 )
777 break;
778
779 SCIPdebugMsg(scip, "executing presolving of propagator <%s>\n", SCIPpropGetName(scip->set->props_presol[j]));
780 SCIP_CALL( SCIPpropPresol(scip->set->props_presol[j], scip->set, *timing, scip->stat->npresolrounds,
781 &scip->stat->npresolfixedvars, &scip->stat->npresolaggrvars, &scip->stat->npresolchgvartypes,
782 &scip->stat->npresolchgbds, &scip->stat->npresoladdholes, &scip->stat->npresoldelconss,
783 &scip->stat->npresoladdconss, &scip->stat->npresolupgdconss, &scip->stat->npresolchgcoefs,
784 &scip->stat->npresolchgsides, &result) );
785 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
786 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
787
788 lastranpresol = FALSE;
789 ++j;
790 }
791 /* call next presolver */
792 else
793 {
794 /* only presolving methods which have non-negative priority will be called before constraint handlers */
795 if( priopresol < 0 )
796 break;
797
798 SCIPdebugMsg(scip, "executing presolver <%s>\n", SCIPpresolGetName(scip->set->presols[i]));
799 SCIP_CALL( SCIPpresolExec(scip->set->presols[i], scip->set, *timing, scip->stat->npresolrounds,
800 &scip->stat->npresolfixedvars, &scip->stat->npresolaggrvars, &scip->stat->npresolchgvartypes,
801 &scip->stat->npresolchgbds, &scip->stat->npresoladdholes, &scip->stat->npresoldelconss,
802 &scip->stat->npresoladdconss, &scip->stat->npresolupgdconss, &scip->stat->npresolchgcoefs,
803 &scip->stat->npresolchgsides, &result) );
804 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
805 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
806
807 lastranpresol = TRUE;
808 ++i;
809 }
810
811 if( result == SCIP_CUTOFF )
812 {
813 *infeasible = TRUE;
814
815 if( lastranpresol )
816 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
817 "presolver <%s> detected infeasibility\n", SCIPpresolGetName(scip->set->presols[i-1]));
818 else
819 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
820 "propagator <%s> detected infeasibility\n", SCIPpropGetName(scip->set->props_presol[j-1]));
821 }
822 else if( result == SCIP_UNBOUNDED )
823 {
824 *unbounded = TRUE;
825
826 if( lastranpresol )
827 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
828 "presolver <%s> detected unboundedness (or infeasibility)\n", SCIPpresolGetName(scip->set->presols[i-1]));
829 else
830 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
831 "propagator <%s> detected unboundedness (or infeasibility)\n", SCIPpropGetName(scip->set->props_presol[j-1]));
832 }
833
834 /* delete the variables from the problems that were marked to be deleted */
835 SCIP_CALL( SCIPprobPerformVarDeletions(scip->transprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp,
836 scip->branchcand) );
837
838 SCIPdebugMsg(scip, "presolving callback returned result <%d>\n", result);
839
840 /* if we work off the exhaustive presolvers, we stop immediately if a reduction was found */
841 if( (*timing == SCIP_PRESOLTIMING_EXHAUSTIVE) && !lastround && !SCIPisPresolveFinished(scip) )
842 {
843 assert(*consstart == 0);
844
845 if( lastranpresol )
846 {
847 *presolstart = i + 1;
848 *propstart = j;
849 }
850 else
851 {
852 *presolstart = i;
853 *propstart = j + 1;
854 }
855 aborted = TRUE;
856
857 break;
858 }
859 }
860
861 /* call presolve methods of constraint handlers */
862 while( k < consend && !(*unbounded) && !(*infeasible) && !aborted )
863 {
864 SCIPdebugMsg(scip, "executing presolve method of constraint handler <%s>\n",
865 SCIPconshdlrGetName(scip->set->conshdlrs[k]));
866 SCIP_CALL( SCIPconshdlrPresolve(scip->set->conshdlrs[k], scip->mem->probmem, scip->set, scip->stat,
867 *timing, scip->stat->npresolrounds,
868 &scip->stat->npresolfixedvars, &scip->stat->npresolaggrvars, &scip->stat->npresolchgvartypes,
869 &scip->stat->npresolchgbds, &scip->stat->npresoladdholes, &scip->stat->npresoldelconss,
870 &scip->stat->npresoladdconss, &scip->stat->npresolupgdconss, &scip->stat->npresolchgcoefs,
871 &scip->stat->npresolchgsides, &result) );
872 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
873 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
874
875 ++k;
876
877 if( result == SCIP_CUTOFF )
878 {
879 *infeasible = TRUE;
880 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
881 "constraint handler <%s> detected infeasibility\n", SCIPconshdlrGetName(scip->set->conshdlrs[k-1]));
882 }
883 else if( result == SCIP_UNBOUNDED )
884 {
885 *unbounded = TRUE;
886 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
887 "constraint handler <%s> detected unboundedness (or infeasibility)\n",
888 SCIPconshdlrGetName(scip->set->conshdlrs[k-1]));
889 }
890
891 /* delete the variables from the problems that were marked to be deleted */
892 SCIP_CALL( SCIPprobPerformVarDeletions(scip->transprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp,
893 scip->branchcand) );
894
895 SCIPdebugMsg(scip, "presolving callback returned with result <%d>\n", result);
896
897 /* if we work off the exhaustive presolvers, we stop immediately if a reduction was found */
898 if( (*timing == SCIP_PRESOLTIMING_EXHAUSTIVE) && !lastround && !SCIPisPresolveFinished(scip) )
899 {
900 *presolstart = i;
901 *propstart = j;
902 *consstart = k + 1;
903 aborted = TRUE;
904
905 break;
906 }
907 }
908
909 assert( scip->set->propspresolsorted );
910
911 /* call included presolvers with negative priority */
912 while( !(*unbounded) && !(*infeasible) && !aborted && (i < presolend || j < propend) )
913 {
914 if( i < scip->set->npresols )
915 priopresol = SCIPpresolGetPriority(scip->set->presols[i]);
916 else
917 priopresol = -INT_MAX;
918
919 if( j < scip->set->nprops )
920 prioprop = SCIPpropGetPresolPriority(scip->set->props_presol[j]);
921 else
922 prioprop = -INT_MAX;
923
924 /* choose presolving */
925 if( prioprop >= priopresol )
926 {
927 assert(prioprop <= 0);
928
929 SCIPdebugMsg(scip, "executing presolving of propagator <%s>\n", SCIPpropGetName(scip->set->props_presol[j]));
930 SCIP_CALL( SCIPpropPresol(scip->set->props_presol[j], scip->set, *timing, scip->stat->npresolrounds,
931 &scip->stat->npresolfixedvars, &scip->stat->npresolaggrvars, &scip->stat->npresolchgvartypes,
932 &scip->stat->npresolchgbds, &scip->stat->npresoladdholes, &scip->stat->npresoldelconss,
933 &scip->stat->npresoladdconss, &scip->stat->npresolupgdconss, &scip->stat->npresolchgcoefs,
934 &scip->stat->npresolchgsides, &result) );
935 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
936 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
937
938 lastranpresol = FALSE;
939 ++j;
940 }
941 else
942 {
943 assert(priopresol < 0);
944
945 SCIPdebugMsg(scip, "executing presolver <%s>\n", SCIPpresolGetName(scip->set->presols[i]));
946 SCIP_CALL( SCIPpresolExec(scip->set->presols[i], scip->set, *timing, scip->stat->npresolrounds,
947 &scip->stat->npresolfixedvars, &scip->stat->npresolaggrvars, &scip->stat->npresolchgvartypes,
948 &scip->stat->npresolchgbds, &scip->stat->npresoladdholes, &scip->stat->npresoldelconss,
949 &scip->stat->npresoladdconss, &scip->stat->npresolupgdconss, &scip->stat->npresolchgcoefs,
950 &scip->stat->npresolchgsides, &result) );
951 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
952 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
953
954 lastranpresol = TRUE;
955 ++i;
956 }
957
958 if( result == SCIP_CUTOFF )
959 {
960 *infeasible = TRUE;
961
962 if( lastranpresol )
963 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
964 "presolver <%s> detected infeasibility\n", SCIPpresolGetName(scip->set->presols[i-1]));
965 else
966 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
967 "propagator <%s> detected infeasibility\n", SCIPpropGetName(scip->set->props_presol[j-1]));
968 }
969 else if( result == SCIP_UNBOUNDED )
970 {
971 *unbounded = TRUE;
972
973 if( lastranpresol )
974 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
975 "presolver <%s> detected unboundedness (or infeasibility)\n", SCIPpresolGetName(scip->set->presols[i-1]));
976 else
977 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
978 "propagator <%s> detected unboundedness (or infeasibility)\n", SCIPpropGetName(scip->set->props_presol[j-1]));
979 }
980
981 /* delete the variables from the problems that were marked to be deleted */
982 SCIP_CALL( SCIPprobPerformVarDeletions(scip->transprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp,
983 scip->branchcand) );
984
985 SCIPdebugMsg(scip, "presolving callback return with result <%d>\n", result);
986
987 /* if we work off the exhaustive presolvers, we stop immediately if a reduction was found */
988 if( (*timing == SCIP_PRESOLTIMING_EXHAUSTIVE) && !lastround && !SCIPisPresolveFinished(scip) )
989 {
990 assert(k == consend);
991
992 if( lastranpresol )
993 {
994 *presolstart = i + 1;
995 *propstart = j;
996 }
997 else
998 {
999 *presolstart = i;
1000 *propstart = j + 1;
1001 }
1002 *consstart = k;
1003
1004 break;
1005 }
1006 }
1007
1008 /* remove empty and single variable cliques from the clique table */
1009 if( !(*unbounded) && !(*infeasible) )
1010 {
1011 int nlocalbdchgs = 0;
1012
1013 SCIP_CALL( SCIPcliquetableCleanup(scip->cliquetable, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
1014 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, &nlocalbdchgs,
1015 infeasible) );
1016
1017 if( nlocalbdchgs > 0 || *infeasible )
1018 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
1019 "clique table cleanup detected %d bound changes%s\n", nlocalbdchgs, *infeasible ? " and infeasibility" : "");
1020
1021 scip->stat->npresolfixedvars += nlocalbdchgs;
1022
1023 /* do not call heuristics during presolving on a benders decomposition
1024 * because the cost information of the retransformed original solutions would be incomplete
1025 */
1026 if( !*infeasible && scip->set->nheurs > 0 && scip->set->nactivebenders == 0 )
1027 {
1028 /* call primal heuristics that are applicable during presolving */
1029 SCIP_Bool foundsol;
1030
1031 SCIPdebugMsg(scip, "calling primal heuristics during presolving\n");
1032
1033 /* call primal heuristics */
1034 SCIP_CALL( SCIPprimalHeuristics(scip->set, scip->stat, scip->transprob, scip->primal, NULL, NULL, NULL,
1035 SCIP_HEURTIMING_DURINGPRESOLLOOP, FALSE, &foundsol, unbounded) );
1036
1037 /* output a message, if a solution was found */
1038 if( foundsol )
1039 {
1040 SCIP_SOL* sol;
1041
1042 assert(SCIPgetNSols(scip) > 0);
1043 sol = SCIPgetBestSol(scip);
1044 assert(sol != NULL);
1045 assert(SCIPgetSolOrigObj(scip,sol) != SCIP_INVALID); /*lint !e777*/
1046
1047 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
1048 "feasible solution found by %s heuristic after %.1f seconds, objective value %.6e\n",
1050 }
1051 }
1052 }
1053
1054 if( !(*unbounded) && !(*infeasible) )
1055 {
1056 /* call more expensive presolvers */
1057 if( (SCIPisPresolveFinished(scip) || lastround) )
1058 {
1059 if( *timing != SCIP_PRESOLTIMING_FINAL )
1060 {
1061 assert((*timing == SCIP_PRESOLTIMING_FAST) || (*timing == SCIP_PRESOLTIMING_MEDIUM) || (*timing == SCIP_PRESOLTIMING_EXHAUSTIVE));
1062
1063 SCIPdebugMsg(scip, "not enough reductions in %s presolving, running %s presolving now...\n",
1064 *timing == SCIP_PRESOLTIMING_FAST ? "fast" : *timing == SCIP_PRESOLTIMING_MEDIUM ? "medium" : "exhaustive",
1065 *timing == SCIP_PRESOLTIMING_FAST ? "medium" : *timing == SCIP_PRESOLTIMING_MEDIUM ? "exhaustive" : "final");
1066
1067 /* increase timing */
1069
1070 /* computational experiments showed that always starting the loop of exhaustive presolvers from the beginning
1071 * performs better than continuing from the last processed presolver. Therefore, we start from 0, but keep
1072 * the mechanisms to possibly change this back later.
1073 * @todo try starting from the last processed exhaustive presolver
1074 */
1075 *presolstart = 0;
1076 *propstart = 0;
1077 *consstart = 0;
1078
1079 SCIP_CALL( presolveRound(scip, timing, unbounded, infeasible, lastround, presolstart, presolend,
1080 propstart, propend, consstart, consend) );
1081 }
1082#ifdef SCIP_DISABLED_CODE
1083 /* run remaining exhaustive presolvers (if we did not start from the beginning anyway) */
1084 else if( (oldpresolstart > 0 || oldpropstart > 0 || oldconsstart > 0) && presolend == scip->set->npresols
1085 && propend == scip->set->nprops && consend == scip->set->nconshdlrs )
1086 {
1087 int newpresolstart = 0;
1088 int newpropstart = 0;
1089 int newconsstart = 0;
1090
1091 SCIPdebugMsg(scip, "reached end of exhaustive presolving loop, starting from the beginning...\n");
1092
1093 SCIP_CALL( presolveRound(scip, timing, unbounded, infeasible, lastround, &newpresolstart,
1094 oldpresolstart, &newpropstart, oldpropstart, &newconsstart, oldconsstart) );
1095
1096 *presolstart = newpresolstart;
1097 *propstart = newpropstart;
1098 *consstart = newconsstart;
1099 }
1100#endif
1101 }
1102 }
1103
1104 /* issue PRESOLVEROUND event */
1106 SCIP_CALL( SCIPeventProcess(&event, scip->set, NULL, NULL, NULL, scip->eventfilter) );
1107
1108 return SCIP_OKAY;
1109}
1110
1111
1112/** loops through the included presolvers and constraint's presolve methods, until changes are too few */
1113static
1115 SCIP* scip, /**< SCIP data structure */
1116 SCIP_Bool* unbounded, /**< pointer to store whether presolving detected unboundedness */
1117 SCIP_Bool* infeasible, /**< pointer to store whether presolving detected infeasibility */
1118 SCIP_Bool* vanished /**< pointer to store whether the problem vanished in presolving */
1119 )
1120{
1121 SCIP_PRESOLTIMING presoltiming;
1122 SCIP_Bool finished;
1123 SCIP_Bool stopped;
1124 SCIP_Bool lastround;
1125 int presolstart = 0;
1126 int propstart = 0;
1127 int consstart = 0;
1128#ifndef NDEBUG
1129 size_t nusedbuffers;
1130 size_t nusedcleanbuffers;
1131#endif
1132
1133 assert(scip != NULL);
1134 assert(scip->mem != NULL);
1135 assert(scip->primal != NULL);
1136 assert(scip->set != NULL);
1137 assert(scip->stat != NULL);
1138 assert(scip->transprob != NULL);
1139 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED || scip->set->stage == SCIP_STAGE_PRESOLVING);
1140 assert(unbounded != NULL);
1141 assert(infeasible != NULL);
1142
1143 *unbounded = FALSE;
1144 *vanished = FALSE;
1145
1146 /* GCG wants to perform presolving during the reading process of a file reader;
1147 * hence the number of used buffers does not need to be zero, however, it should
1148 * be the same again after presolve is finished
1149 */
1150#ifndef NDEBUG
1151 nusedbuffers = BMSgetNUsedBufferMemory(SCIPbuffer(scip));
1152 nusedcleanbuffers = BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip));
1153#endif
1154
1155 /* switch status to unknown */
1156 scip->stat->status = SCIP_STATUS_UNKNOWN;
1157
1158 /* update upper bound and cutoff bound due to objective limit in primal data */
1159 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1160 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1161
1162 /* start presolving timer */
1163 SCIPclockStart(scip->stat->presolvingtime, scip->set);
1164 SCIPclockStart(scip->stat->presolvingtimeoverall, scip->set);
1165
1166 /* initialize presolving */
1167 if( scip->set->stage == SCIP_STAGE_TRANSFORMED )
1168 {
1170 }
1171 assert(scip->set->stage == SCIP_STAGE_PRESOLVING);
1172
1173 /* call primal heuristics that are applicable before presolving but not on a benders decomposition
1174 * because the cost information of the retransformed original solutions would be incomplete
1175 */
1176 if( scip->set->nheurs > 0 && scip->set->nactivebenders == 0 )
1177 {
1178 SCIP_Bool foundsol;
1179
1180 SCIPdebugMsg(scip, "calling primal heuristics before presolving\n");
1181
1182 /* call primal heuristics */
1183 SCIP_CALL( SCIPprimalHeuristics(scip->set, scip->stat, scip->transprob, scip->primal, NULL, NULL, NULL,
1184 SCIP_HEURTIMING_BEFOREPRESOL, FALSE, &foundsol, unbounded) );
1185
1186 /* output a message, if a solution was found */
1187 if( foundsol )
1188 {
1189 SCIP_SOL* sol;
1190
1191 assert(SCIPgetNSols(scip) > 0);
1192 sol = SCIPgetBestSol(scip);
1193 assert(sol != NULL);
1194 assert(SCIPgetSolOrigObj(scip,sol) != SCIP_INVALID); /*lint !e777*/
1195
1196 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
1197 "feasible solution found by %s heuristic after %.1f seconds, objective value %.6e\n",
1199 }
1200 }
1201
1202 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "presolving:\n");
1203
1204 *infeasible = FALSE;
1205 *unbounded = (*unbounded) || (SCIPgetNSols(scip) > 0 && SCIPisInfinity(scip, -SCIPgetSolOrigObj(scip, SCIPgetBestSol(scip))));
1206 *vanished = scip->transprob->nvars == 0 && scip->transprob->nconss == 0 && scip->set->nactivepricers == 0;
1207
1208 finished = (scip->set->presol_maxrounds != -1 && scip->stat->npresolrounds >= scip->set->presol_maxrounds)
1209 || (*unbounded) || (*vanished) || (scip->set->reopt_enable && scip->stat->nreoptruns >= 1);
1210
1211 /* abort if time limit was reached or user interrupted */
1212 stopped = SCIPsolveIsStopped(scip->set, scip->stat, FALSE);
1213
1214 /* perform presolving rounds */
1215 while( !finished && !stopped )
1216 {
1217 /* store current number of reductions */
1218 scip->stat->lastnpresolfixedvars = scip->stat->npresolfixedvars;
1219 scip->stat->lastnpresolaggrvars = scip->stat->npresolaggrvars;
1220 scip->stat->lastnpresolchgvartypes = scip->stat->npresolchgvartypes;
1221 scip->stat->lastnpresolchgbds = scip->stat->npresolchgbds;
1222 scip->stat->lastnpresoladdholes = scip->stat->npresoladdholes;
1223 scip->stat->lastnpresoldelconss = scip->stat->npresoldelconss;
1224 scip->stat->lastnpresoladdconss = scip->stat->npresoladdconss;
1225 scip->stat->lastnpresolupgdconss = scip->stat->npresolupgdconss;
1226 scip->stat->lastnpresolchgcoefs = scip->stat->npresolchgcoefs;
1227 scip->stat->lastnpresolchgsides = scip->stat->npresolchgsides;
1228#ifdef SCIP_DISABLED_CODE
1229 scip->stat->lastnpresolimplications = scip->stat->nimplications;
1230 scip->stat->lastnpresolcliques = SCIPcliquetableGetNCliques(scip->cliquetable);
1231#endif
1232
1233 /* set presolving flag */
1234 scip->stat->performpresol = TRUE;
1235
1236 /* sort propagators */
1238
1239 /* sort presolvers by priority */
1241
1242 /* check if this will be the last presolving round (in that case, we want to run all presolvers) */
1243 lastround = (scip->set->presol_maxrounds == -1 ? FALSE : (scip->stat->npresolrounds + 1 >= scip->set->presol_maxrounds));
1244
1245 presoltiming = SCIP_PRESOLTIMING_FAST;
1246
1247 /* perform the presolving round by calling the presolvers, propagators, and constraint handlers */
1248 assert(!(*unbounded));
1249 assert(!(*infeasible));
1250 SCIP_CALL( presolveRound(scip, &presoltiming, unbounded, infeasible, lastround,
1251 &presolstart, scip->set->npresols, &propstart, scip->set->nprops, &consstart, scip->set->nconshdlrs) );
1252
1253 /* check, if we should abort presolving due to not enough changes in the last round */
1254 finished = SCIPisPresolveFinished(scip) || presoltiming == SCIP_PRESOLTIMING_FINAL;
1255
1256 SCIPdebugMsg(scip, "presolving round %d returned with unbounded = %u, infeasible = %u, finished = %u\n", scip->stat->npresolrounds, *unbounded, *infeasible, finished);
1257
1258 /* check whether problem is infeasible or unbounded or vanished */
1259 *vanished = scip->transprob->nvars == 0 && scip->transprob->nconss == 0 && scip->set->nactivepricers == 0;
1260 finished = finished || *unbounded || *infeasible || *vanished;
1261
1262 /* increase round number */
1263 scip->stat->npresolrounds++;
1264
1265 if( !finished )
1266 {
1267 /* print presolving statistics */
1268 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
1269 "(round %d, %-11s %d del vars, %d del conss, %d add conss, %d chg bounds, %d chg sides, %d chg coeffs, %d upgd conss, %d impls, %d clqs\n",
1270 scip->stat->npresolrounds, ( presoltiming == SCIP_PRESOLTIMING_FAST ? "fast)" :
1271 (presoltiming == SCIP_PRESOLTIMING_MEDIUM ? "medium)" :
1272 (presoltiming == SCIP_PRESOLTIMING_EXHAUSTIVE ?"exhaustive)" :
1273 "final)")) ),
1274 scip->stat->npresolfixedvars + scip->stat->npresolaggrvars,
1275 scip->stat->npresoldelconss, scip->stat->npresoladdconss,
1276 scip->stat->npresolchgbds, scip->stat->npresolchgsides,
1277 scip->stat->npresolchgcoefs, scip->stat->npresolupgdconss,
1278 scip->stat->nimplications, SCIPcliquetableGetNCliques(scip->cliquetable));
1279 }
1280
1281 /* abort if time limit was reached or user interrupted */
1282 stopped = SCIPsolveIsStopped(scip->set, scip->stat, FALSE);
1283 }
1284
1285 /* first change status of scip, so that all plugins in their exitpre callbacks can ask SCIP for the correct status */
1286 if( *infeasible )
1287 {
1288 /* switch status to OPTIMAL */
1289 if( scip->primal->nlimsolsfound > 0 )
1290 {
1291 scip->stat->status = SCIP_STATUS_OPTIMAL;
1292 }
1293 else /* switch status to INFEASIBLE */
1294 scip->stat->status = SCIP_STATUS_INFEASIBLE;
1295 }
1296 else if( *unbounded )
1297 {
1298 if( scip->primal->nsols >= 1 ) /* switch status to UNBOUNDED */
1299 scip->stat->status = SCIP_STATUS_UNBOUNDED;
1300 else /* switch status to INFORUNBD */
1301 scip->stat->status = SCIP_STATUS_INFORUNBD;
1302 }
1303 /* if no variables and constraints are present, we try to add the empty solution (constraint handlers with needscons
1304 * flag FALSE could theoretically reject it); if no active pricers could create variables later, we conclude
1305 * optimality or infeasibility */
1306 else if( scip->transprob->nvars == 0 && scip->transprob->nconss == 0 )
1307 {
1308 SCIP_SOL* sol;
1309 SCIP_Bool stored;
1310
1311 SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );
1312 SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, FALSE, FALSE, &stored) );
1313
1314 if( scip->set->nactivepricers == 0 )
1315 {
1316 assert(*vanished);
1317
1318 if( scip->primal->nlimsolsfound > 0 )
1319 scip->stat->status = SCIP_STATUS_OPTIMAL;
1320 else
1321 scip->stat->status = SCIP_STATUS_INFEASIBLE;
1322 }
1323 }
1324
1325 /* deinitialize presolving */
1326 if( finished && (!stopped || *unbounded || *infeasible || *vanished) )
1327 {
1328 SCIP_Real maxnonzeros;
1329 SCIP_Longint nchecknonzeros;
1330 SCIP_Longint nactivenonzeros;
1331 SCIP_Bool approxchecknonzeros;
1332 SCIP_Bool approxactivenonzeros;
1333 SCIP_Bool infeas;
1334 int j;
1335
1336 /* flatten aggregation graph in order to avoid complicated multi-aggregated variables */
1337 for( j = 0; j < scip->transprob->nfixedvars; ++j )
1338 {
1339 if( SCIPvarGetStatus(scip->transprob->fixedvars[j]) == SCIP_VARSTATUS_MULTAGGR )
1340 {
1341 SCIP_CALL( SCIPflattenVarAggregationGraph(scip, scip->transprob->fixedvars[j]) );
1342 }
1343 }
1344
1345 SCIP_CALL( exitPresolve(scip, *unbounded || *infeasible || *vanished, &infeas) );
1346 *infeasible = *infeasible || infeas;
1347
1348 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
1349
1350 /* resort variables if we are not already done (unless variable permutation was explicitly activated) */
1351 if( !scip->set->random_permutevars && !(*infeasible) && !(*unbounded) && !(*vanished) )
1352 {
1353 /* (Re)Sort the variables, which appear in the four categories (binary, integer, implicit, continuous) after
1354 * presolve with respect to their original index (within their categories). Adjust the problem index afterwards
1355 * which is supposed to reflect the position in the variable array. This additional (re)sorting is supposed to
1356 * get more robust against the order presolving fixed variables. (We also reobtain a possible block structure
1357 * induced by the user model)
1358 */
1359 SCIPprobResortVars(scip->transprob);
1360 }
1361
1362 /* determine number of non-zeros */
1363 maxnonzeros = (SCIP_Real)SCIPgetNConss(scip) * SCIPgetNVars(scip);
1364 maxnonzeros = MAX(maxnonzeros, 1.0);
1365 SCIP_CALL( calcNonZeros(scip, &nchecknonzeros, &nactivenonzeros, &approxchecknonzeros, &approxactivenonzeros) );
1366 scip->stat->nnz = nactivenonzeros;
1367
1368 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
1369 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
1370 "presolved problem has %s%" SCIP_LONGINT_FORMAT " active (%g%%) nonzeros and %s%" SCIP_LONGINT_FORMAT " (%g%%) check nonzeros\n",
1371 approxactivenonzeros ? "more than " : "", nactivenonzeros, nactivenonzeros/maxnonzeros * 100,
1372 approxchecknonzeros ? "more than " : "", nchecknonzeros, nchecknonzeros/maxnonzeros * 100);
1373 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
1374 }
1375 assert(BMSgetNUsedBufferMemory(SCIPbuffer(scip)) == nusedbuffers);
1376 assert(BMSgetNUsedBufferMemory(SCIPcleanbuffer(scip)) == nusedcleanbuffers);
1377
1378 /* stop presolving time */
1379 SCIPclockStop(scip->stat->presolvingtime, scip->set);
1380 SCIPclockStop(scip->stat->presolvingtimeoverall, scip->set);
1381
1382 /* print presolving statistics */
1383 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1384 "presolving (%d rounds: %d fast, %d medium, %d exhaustive):\n", scip->stat->npresolrounds,
1385 scip->stat->npresolroundsfast, scip->stat->npresolroundsmed, scip->stat->npresolroundsext);
1386 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1387 " %d deleted vars, %d deleted constraints, %d added constraints, %d tightened bounds, %d added holes, %d changed sides, %d changed coefficients\n",
1388 scip->stat->npresolfixedvars + scip->stat->npresolaggrvars, scip->stat->npresoldelconss, scip->stat->npresoladdconss,
1389 scip->stat->npresolchgbds, scip->stat->npresoladdholes, scip->stat->npresolchgsides, scip->stat->npresolchgcoefs);
1390 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1391 " %d implications, %d cliques\n", scip->stat->nimplications, SCIPcliquetableGetNCliques(scip->cliquetable));
1392
1393 /* remember number of constraints */
1394 SCIPprobMarkNConss(scip->transprob);
1395
1396 return SCIP_OKAY;
1397}
1398
1399/** tries to transform original solutions to the transformed problem space */
1400static
1402 SCIP* scip /**< SCIP data structure */
1403 )
1404{
1405 SCIP_SOL** sols;
1406 SCIP_SOL** scipsols;
1407 SCIP_SOL* sol;
1408 SCIP_Real* solvals;
1409 SCIP_Bool* solvalset;
1410 SCIP_Bool added;
1411 SCIP_Longint oldnsolsfound;
1412 int nsols;
1413 int ntransvars;
1414 int naddedsols;
1415 int s;
1416
1417 nsols = SCIPgetNSols(scip);
1418 oldnsolsfound = scip->primal->nsolsfound;
1419
1420 /* no solution to transform */
1421 if( nsols == 0 )
1422 return SCIP_OKAY;
1423
1424 SCIPdebugMsg(scip, "try to transfer %d original solutions into the transformed problem space\n", nsols);
1425
1426 ntransvars = scip->transprob->nvars;
1427 naddedsols = 0;
1428
1429 /* It might happen, that the added transferred solution does not equal the corresponding original one, which might
1430 * result in the array of solutions being changed. Thus we temporarily copy the array and traverse it in reverse
1431 * order to ensure that the regarded solution in the copied array was not already freed when new solutions were added
1432 * and the worst solutions were freed.
1433 */
1434 scipsols = SCIPgetSols(scip);
1435 SCIP_CALL( SCIPduplicateBufferArray(scip, &sols, scipsols, nsols) );
1436 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, ntransvars) );
1437 SCIP_CALL( SCIPallocBufferArray(scip, &solvalset, ntransvars) );
1438
1439 for( s = nsols-1; s >= 0; --s )
1440 {
1441 sol = sols[s];
1442
1443 /* it might happen that a transferred original solution has a better objective than its original counterpart
1444 * (e.g., because multi-aggregated variables get another value, but the solution is still feasible);
1445 * in this case, it might happen that the solution is not an original one and we just skip this solution
1446 */
1447 if( !SCIPsolIsOriginal(sol) )
1448 continue;
1449
1450 SCIP_CALL( SCIPprimalTransformSol(scip->primal, sol, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
1451 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, solvals,
1452 solvalset, ntransvars, &added) );
1453
1454 if( added )
1455 ++naddedsols;
1456 }
1457
1458 if( naddedsols > 0 )
1459 {
1461 "transformed %d/%d original solutions to the transformed problem space\n",
1462 naddedsols, nsols);
1463
1464 scip->stat->nexternalsolsfound += scip->primal->nsolsfound - oldnsolsfound;
1465 }
1466
1467 SCIPfreeBufferArray(scip, &solvalset);
1468 SCIPfreeBufferArray(scip, &solvals);
1469 SCIPfreeBufferArray(scip, &sols);
1470
1471 return SCIP_OKAY;
1472}
1473
1474/** initializes solution process data structures */
1475static
1477 SCIP* scip, /**< SCIP data structure */
1478 SCIP_Bool solved /**< is problem already solved? */
1479 )
1480{
1481 assert(scip != NULL);
1482 assert(scip->mem != NULL);
1483 assert(scip->set != NULL);
1484 assert(scip->stat != NULL);
1485 assert(scip->nlp == NULL);
1486 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
1487
1488 /**@todo check whether other methodscan be skipped if problem has been solved */
1489 /* if problem has been solved, several time consuming tasks must not be performed */
1490 if( !solved )
1491 {
1492 /* reset statistics for current branch and bound run */
1493 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, solved);
1495
1496 /* LP is empty anyway; mark empty LP to be solved and update validsollp counter */
1497 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1498
1499 /* update upper bound and cutoff bound due to objective limit in primal data */
1500 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1501 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1502 }
1503
1504 /* switch stage to INITSOLVE */
1505 scip->set->stage = SCIP_STAGE_INITSOLVE;
1506
1507 /* initialize NLP if there are nonlinearities */
1508 if( scip->transprob->nlpenabled && !scip->set->nlp_disable )
1509 {
1510 SCIPdebugMsg(scip, "constructing empty NLP\n");
1511
1512 SCIP_CALL( SCIPnlpCreate(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, SCIPprobGetName(scip->transprob), scip->transprob->nvars) );
1513 assert(scip->nlp != NULL);
1514
1515 SCIP_CALL( SCIPnlpAddVars(scip->nlp, scip->mem->probmem, scip->set, scip->transprob->nvars, scip->transprob->vars) );
1516
1517 /* Adjust estimation of external memory: SCIPtransformProb() estimated the memory used for the LP-solver. As a
1518 * very crude approximation just double this number. Only do this once in the first run. */
1519 if( scip->set->misc_estimexternmem && scip->stat->nruns <= 1 )
1520 {
1521 scip->stat->externmemestim *= 2;
1522 SCIPdebugMsg(scip, "external memory usage estimated to %" SCIP_LONGINT_FORMAT " byte\n", scip->stat->externmemestim);
1523 }
1524 }
1525
1526 /* possibly create visualization output file */
1527 SCIP_CALL( SCIPvisualInit(scip->stat->visual, scip->mem->probmem, scip->set, scip->messagehdlr) );
1528
1529 /* initialize solution process data structures */
1530 SCIP_CALL( SCIPpricestoreCreate(&scip->pricestore) );
1531 SCIP_CALL( SCIPsepastoreCreate(&scip->sepastore, scip->mem->probmem, scip->set) );
1532 SCIP_CALL( SCIPsepastoreCreate(&scip->sepastoreprobing, scip->mem->probmem, scip->set) );
1533 SCIP_CALL( SCIPcutpoolCreate(&scip->cutpool, scip->mem->probmem, scip->set, scip->set->sepa_cutagelimit, TRUE) );
1534 SCIP_CALL( SCIPcutpoolCreate(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->set->sepa_cutagelimit, FALSE) );
1535 SCIP_CALL( SCIPtreeCreateRoot(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue,
1536 scip->lp) );
1537
1538 /* try to transform original solutions to the transformed problem space */
1539 if( scip->set->misc_transorigsols )
1540 {
1542 }
1543
1544 /* restore lower bound of the root node if a valid dual bound is at hand */
1545 if( scip->transprob->dualbound != SCIP_INVALID ) /*lint !e777*/
1546 {
1547 scip->tree->root->lowerbound = SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, scip->transprob->dualbound);
1548 scip->tree->root->estimate = scip->tree->root->lowerbound;
1549 scip->stat->rootlowerbound = scip->tree->root->lowerbound;
1550
1551 if( scip->set->misc_calcintegral )
1552 SCIPstatUpdatePrimalDualIntegrals(scip->stat, scip->set, scip->transprob, scip->origprob, SCIPinfinity(scip), scip->tree->root->lowerbound);
1553 }
1554
1555 /* inform the transformed problem that the branch and bound process starts now */
1556 SCIP_CALL( SCIPprobInitSolve(scip->transprob, scip->set) );
1557
1558 /* transform the decomposition storage */
1560
1561 /* inform plugins that the branch and bound process starts now */
1562 SCIP_CALL( SCIPsetInitsolPlugins(scip->set, scip->mem->probmem, scip->stat) );
1563
1564 /* remember number of constraints */
1565 SCIPprobMarkNConss(scip->transprob);
1566
1567 /* if all variables are known, calculate a trivial primal bound by setting all variables to their worst bound */
1568 if( scip->set->nactivepricers == 0 )
1569 {
1570 SCIP_VAR* var;
1571 SCIP_Real obj;
1572 SCIP_Real objbound;
1573 SCIP_Real bd;
1574 int v;
1575
1576 objbound = 0.0;
1577 for( v = 0; v < scip->transprob->nvars && !SCIPsetIsInfinity(scip->set, objbound); ++v )
1578 {
1579 var = scip->transprob->vars[v];
1580 obj = SCIPvarGetObj(var);
1581 if( !SCIPsetIsZero(scip->set, obj) )
1582 {
1584 if( SCIPsetIsInfinity(scip->set, REALABS(bd)) )
1585 objbound = SCIPsetInfinity(scip->set);
1586 else
1587 objbound += obj * bd;
1588 }
1589 }
1590
1591 /* adjust primal bound, such that solution with worst bound may be found */
1592 if( objbound + SCIPsetCutoffbounddelta(scip->set) != objbound ) /*lint !e777*/
1593 objbound += SCIPsetCutoffbounddelta(scip->set);
1594 /* if objbound is very large, adding the cutoffbounddelta may not change the number; in this case, we are using
1595 * SCIPnextafter to ensure that the cutoffbound is really larger than the best possible solution value
1596 */
1597 else
1598 objbound = SCIPnextafter(objbound, SCIP_REAL_MAX);
1599
1600 /* update cutoff bound */
1601 if( !SCIPsetIsInfinity(scip->set, objbound) && SCIPsetIsLT(scip->set, objbound, scip->primal->cutoffbound) )
1602 {
1603 /* adjust cutoff bound */
1604 SCIP_CALL( SCIPprimalSetCutoffbound(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1605 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, objbound, FALSE) );
1606 }
1607 }
1608
1609 /* switch stage to SOLVING */
1610 scip->set->stage = SCIP_STAGE_SOLVING;
1611
1612 return SCIP_OKAY;
1613}
1614
1615/** frees solution process data structures */
1616static
1618 SCIP* scip, /**< SCIP data structure */
1619 SCIP_Bool restart /**< was this free solve call triggered by a restart? */
1620 )
1621{
1622 assert(scip != NULL);
1623 assert(scip->mem != NULL);
1624 assert(scip->set != NULL);
1625 assert(scip->stat != NULL);
1626 assert(scip->set->stage == SCIP_STAGE_SOLVING || scip->set->stage == SCIP_STAGE_SOLVED);
1627
1628 /* mark that we are currently restarting */
1629 if( restart )
1630 {
1631 scip->stat->inrestart = TRUE;
1632
1633 /* copy the current dual bound into the problem data structure such that it can be used initialize the new search
1634 * tree
1635 */
1637 }
1638
1639 /* remove focus from the current focus node */
1640 if( SCIPtreeGetFocusNode(scip->tree) != NULL )
1641 {
1642 SCIP_NODE* node = NULL;
1643 SCIP_Bool cutoff;
1644
1645 SCIP_CALL( SCIPnodeFocus(&node, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
1646 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->conflict,
1647 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable, &cutoff, FALSE, TRUE) );
1648 assert(!cutoff);
1649 }
1650
1651 /* switch stage to EXITSOLVE */
1652 scip->set->stage = SCIP_STAGE_EXITSOLVE;
1653
1654 /* cleanup the conflict storage */
1655 SCIP_CALL( SCIPconflictstoreClean(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) );
1656
1657 /* inform plugins that the branch and bound process is finished */
1658 SCIP_CALL( SCIPsetExitsolPlugins(scip->set, scip->mem->probmem, scip->stat, restart) );
1659
1660 /* free the NLP, if there is one, and reset the flags indicating nonlinearity */
1661 if( scip->nlp != NULL )
1662 {
1663 SCIP_CALL( SCIPnlpFree(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1664 }
1665 scip->transprob->nlpenabled = FALSE;
1666
1667 /* clear the LP, and flush the changes to clear the LP of the solver */
1668 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1670
1671 /* resets the debug environment */
1672 SCIP_CALL( SCIPdebugReset(scip->set) ); /*lint !e506 !e774*/
1673
1674 /* clear all row references in internal data structures */
1675 SCIP_CALL( SCIPcutpoolClear(scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1676 SCIP_CALL( SCIPcutpoolClear(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1677
1678 /* we have to clear the tree prior to the problem deinitialization, because the rows stored in the forks and
1679 * subroots have to be released
1680 */
1681 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1682
1684
1685 /* deinitialize transformed problem */
1686 SCIP_CALL( SCIPprobExitSolve(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, restart) );
1687
1688 /* free solution process data structures */
1689 SCIP_CALL( SCIPcutpoolFree(&scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1690 SCIP_CALL( SCIPcutpoolFree(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1691 SCIP_CALL( SCIPsepastoreFree(&scip->sepastoreprobing, scip->mem->probmem) );
1692 SCIP_CALL( SCIPsepastoreFree(&scip->sepastore, scip->mem->probmem) );
1693 SCIP_CALL( SCIPpricestoreFree(&scip->pricestore) );
1694
1695 /* possibly close visualization output file */
1696 SCIPvisualExit(scip->stat->visual, scip->set, scip->messagehdlr);
1697
1698 /* reset statistics for current branch and bound run */
1699 if( scip->stat->status == SCIP_STATUS_INFEASIBLE || scip->stat->status == SCIP_STATUS_OPTIMAL || scip->stat->status == SCIP_STATUS_UNBOUNDED || scip->stat->status == SCIP_STATUS_INFORUNBD )
1700 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, TRUE);
1701 else
1702 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE);
1703
1704 /* switch stage to TRANSFORMED */
1705 scip->set->stage = SCIP_STAGE_TRANSFORMED;
1706
1707 /* restart finished */
1708 assert( ! restart || scip->stat->inrestart );
1709 scip->stat->inrestart = FALSE;
1710
1711 return SCIP_OKAY;
1712}
1713
1714/** frees solution process data structures when reoptimization is used
1715 *
1716 * in contrast to a freeSolve() this method will preserve the transformed problem such that another presolving round
1717 * after changing the problem (modifying the objective function) is not necessary.
1718 */
1719static
1721 SCIP* scip /**< SCIP data structure */
1722 )
1723{
1724 assert(scip != NULL);
1725 assert(scip->mem != NULL);
1726 assert(scip->set != NULL);
1727 assert(scip->stat != NULL);
1728 assert(scip->set->stage == SCIP_STAGE_SOLVING || scip->set->stage == SCIP_STAGE_SOLVED);
1729
1730 /* remove focus from the current focus node */
1731 if( SCIPtreeGetFocusNode(scip->tree) != NULL )
1732 {
1733 SCIP_NODE* node = NULL;
1734 SCIP_Bool cutoff;
1735
1736 SCIP_CALL( SCIPnodeFocus(&node, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
1737 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->conflict,
1738 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable, &cutoff, FALSE, TRUE) );
1739 assert(!cutoff);
1740 }
1741
1742 /* mark current stats, such that new solve begins with the var/col/row indices from the previous run */
1743 SCIPstatMark(scip->stat);
1744
1745 /* switch stage to EXITSOLVE */
1746 scip->set->stage = SCIP_STAGE_EXITSOLVE;
1747
1748 /* deinitialize conflict store */
1749 SCIP_CALL( SCIPconflictstoreClear(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) );
1750
1751 /* invalidate the dual bound */
1753
1754 /* inform plugins that the branch and bound process is finished */
1755 SCIP_CALL( SCIPsetExitsolPlugins(scip->set, scip->mem->probmem, scip->stat, FALSE) );
1756
1757 /* call exit methods of plugins */
1758 SCIP_CALL( SCIPsetExitPlugins(scip->set, scip->mem->probmem, scip->stat) );
1759
1760 /* free the NLP, if there is one, and reset the flags indicating nonlinearity */
1761 if( scip->nlp != NULL )
1762 {
1763 SCIP_CALL( SCIPnlpFree(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1764 }
1765 scip->transprob->nlpenabled = FALSE;
1766
1767 /* clear the LP, and flush the changes to clear the LP of the solver */
1768 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1770
1771 /* resets the debug environment */
1772 SCIP_CALL( SCIPdebugReset(scip->set) ); /*lint !e506 !e774*/
1773
1774 /* clear all row references in internal data structures */
1775 SCIP_CALL( SCIPcutpoolClear(scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1776 SCIP_CALL( SCIPcutpoolClear(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1777
1778 /* we have to clear the tree prior to the problem deinitialization, because the rows stored in the forks and
1779 * subroots have to be released
1780 */
1781 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1782
1783 /* deinitialize transformed problem */
1784 SCIP_CALL( SCIPprobExitSolve(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, FALSE) );
1785
1786 /* free solution process data structures */
1787 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
1788
1789 SCIP_CALL( SCIPcutpoolFree(&scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1790 SCIP_CALL( SCIPcutpoolFree(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1791 SCIP_CALL( SCIPsepastoreFree(&scip->sepastoreprobing, scip->mem->probmem) );
1792 SCIP_CALL( SCIPsepastoreFree(&scip->sepastore, scip->mem->probmem) );
1793 SCIP_CALL( SCIPpricestoreFree(&scip->pricestore) );
1794
1795 /* possibly close visualization output file */
1796 SCIPvisualExit(scip->stat->visual, scip->set, scip->messagehdlr);
1797
1798 /* reset statistics for current branch and bound run */
1799 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE);
1800
1801 /* switch stage to PRESOLVED */
1802 scip->set->stage = SCIP_STAGE_PRESOLVED;
1803
1804 /* restart finished */
1805 scip->stat->inrestart = FALSE;
1806
1807 /* reset solving specific paramters */
1808 if( scip->set->reopt_enable )
1809 {
1810 assert(scip->reopt != NULL);
1811 SCIP_CALL( SCIPreoptReset(scip->reopt, scip->set, scip->mem->probmem) );
1812 }
1813
1814 /* free the debug solution which might live in transformed primal data structure */
1815 SCIP_CALL( SCIPprimalClear(&scip->primal, scip->mem->probmem) );
1816
1817 if( scip->set->misc_resetstat )
1818 {
1819 /* reset statistics to the point before the problem was transformed */
1820 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
1821 }
1822 else
1823 {
1824 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
1826 }
1827
1828 /* reset objective limit */
1830
1831 return SCIP_OKAY;
1832}
1833
1834/** free transformed problem */
1835static
1837 SCIP* scip /**< SCIP data structure */
1838 )
1839{
1840 SCIP_Bool reducedfree;
1841
1842 assert(scip != NULL);
1843 assert(scip->mem != NULL);
1844 assert(scip->stat != NULL);
1845 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED || scip->set->stage == SCIP_STAGE_PRESOLVING ||
1846 (scip->set->stage == SCIP_STAGE_PRESOLVED && scip->set->reopt_enable));
1847
1848 /* If the following evaluates to true, SCIPfreeReoptSolve() has already called the exit-callbacks of the plugins.
1849 * We can skip calling some of the following methods. This can happen if a new objective function was
1850 * installed but the solve was not started.
1851 */
1852 reducedfree = (scip->set->stage == SCIP_STAGE_PRESOLVED && scip->set->reopt_enable);
1853
1854 if( !reducedfree )
1855 {
1856 /* call exit methods of plugins */
1857 SCIP_CALL( SCIPsetExitPlugins(scip->set, scip->mem->probmem, scip->stat) );
1858 }
1859
1860 /* copy best primal solutions to original solution candidate list but not for a benders decomposition
1861 * because their cost information would be incomplete
1862 */
1863 if( !scip->set->reopt_enable && scip->set->limit_maxorigsol > 0 && scip->set->misc_transsolsorig && scip->set->nactivebenders == 0 )
1864 {
1865 SCIP_Bool stored;
1866 SCIP_Bool hasinfval;
1867 int maxsols;
1868 int nsols;
1869 int s;
1870
1871 assert(scip->origprimal->nsols == 0);
1872
1873 nsols = scip->primal->nsols;
1874 maxsols = scip->set->limit_maxorigsol;
1875 stored = TRUE;
1876 s = 0;
1877
1878 /* iterate over all solutions as long as the original solution candidate store size limit is not reached */
1879 while( s < nsols && scip->origprimal->nsols < maxsols )
1880 {
1881 SCIP_SOL* sol;
1882
1883 sol = scip->primal->sols[s];
1884 assert(sol != NULL);
1885
1886 if( !SCIPsolIsOriginal(sol) )
1887 {
1888 /* retransform solution into the original problem space */
1889 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
1890 }
1891 else
1892 hasinfval = FALSE;
1893
1894 /* removing infinite fixings is turned off by the corresponding parameter */
1895 if( !scip->set->misc_finitesolstore )
1896 hasinfval = FALSE;
1897
1898 if( !hasinfval )
1899 {
1900 /* add solution to original candidate solution storage */
1901 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, &stored) );
1902 }
1903 else
1904 {
1905 SCIP_SOL* newsol;
1906 SCIP_Bool success;
1907
1908 SCIP_CALL( SCIPcreateFiniteSolCopy(scip, &newsol, sol, &success) );
1909
1910 /* infinite fixing could be removed */
1911 if( newsol != NULL )
1912 {
1913 /* add solution to original candidate solution storage; we must not use SCIPprimalAddOrigSolFree()
1914 * because we want to create a copy of the solution in the origprimal solution store, but newsol was
1915 * created in the (transformed) primal
1916 */
1917 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, newsol, &stored) );
1918
1919 /* free solution in (transformed) primal where it was created */
1920 SCIP_CALL( SCIPsolFree(&newsol, scip->mem->probmem, scip->primal) );
1921 }
1922 }
1923 ++s;
1924 }
1925
1926 if( scip->origprimal->nsols > 1 )
1927 {
1929 "stored the %d best primal solutions in the original solution candidate list\n", scip->origprimal->nsols);
1930 }
1931 else if( scip->origprimal->nsols == 1 )
1932 {
1934 "stored the best primal solution in the original solution candidate list\n");
1935 }
1936 }
1937
1938 /* switch stage to FREETRANS */
1939 scip->set->stage = SCIP_STAGE_FREETRANS;
1940
1941 /* reset solving specific paramters */
1942 assert(!scip->set->reopt_enable || scip->reopt != NULL);
1943 if( scip->set->reopt_enable && scip->reopt != NULL )
1944 {
1945 SCIP_CALL( SCIPreoptReset(scip->reopt, scip->set, scip->mem->probmem) );
1946 }
1947
1948 if( !reducedfree )
1949 {
1950 /* clear the conflict store
1951 *
1952 * since the conflict store can contain transformed constraints we need to remove them. the store will be finally
1953 * freed in SCIPfreeProb().
1954 */
1955 SCIP_CALL( SCIPconflictstoreClear(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) );
1956 }
1957
1958 /* free transformed problem data structures */
1959 SCIP_CALL( SCIPprobFree(&scip->transprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1960 SCIP_CALL( SCIPcliquetableFree(&scip->cliquetable, scip->mem->probmem) );
1961 SCIP_CALL( SCIPconflictFree(&scip->conflict, scip->mem->probmem) );
1962
1963 if( !reducedfree )
1964 {
1965 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
1966 }
1967 SCIP_CALL( SCIPtreeFree(&scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1968
1969 /* free the debug solution which might live in transformed primal data structure */
1970 SCIP_CALL( SCIPdebugFreeSol(scip->set) ); /*lint !e506 !e774*/
1971 SCIP_CALL( SCIPprimalFree(&scip->primal, scip->mem->probmem) );
1972
1973 SCIP_CALL( SCIPlpFree(&scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter) );
1974 SCIP_CALL( SCIPbranchcandFree(&scip->branchcand) );
1975 SCIP_CALL( SCIPeventfilterFree(&scip->eventfilter, scip->mem->probmem, scip->set) );
1976 SCIP_CALL( SCIPeventqueueFree(&scip->eventqueue) );
1977
1978 if( scip->set->misc_resetstat && !reducedfree )
1979 {
1980 /* reset statistics to the point before the problem was transformed */
1981 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
1982 }
1983 else
1984 {
1985 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
1987 }
1988
1989 /* switch stage to PROBLEM */
1990 scip->set->stage = SCIP_STAGE_PROBLEM;
1991
1992 /* reset objective limit */
1994
1995 /* reset original variable's local and global bounds to their original values */
1996 SCIP_CALL( SCIPprobResetBounds(scip->origprob, scip->mem->probmem, scip->set, scip->stat) );
1997
1998 return SCIP_OKAY;
1999}
2000
2001/** free transformed problem in case an error occurs during transformation and return to SCIP_STAGE_PROBLEM */
2002static
2004 SCIP* scip /**< SCIP data structure */
2005 )
2006{
2007 assert(scip != NULL);
2008 assert(scip->mem != NULL);
2009 assert(scip->stat != NULL);
2010 assert(scip->set->stage == SCIP_STAGE_TRANSFORMING);
2011
2012 /* switch stage to FREETRANS */
2013 scip->set->stage = SCIP_STAGE_FREETRANS;
2014
2015 /* free transformed problem data structures */
2016 SCIP_CALL( SCIPprobFree(&scip->transprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
2017 SCIP_CALL( SCIPcliquetableFree(&scip->cliquetable, scip->mem->probmem) );
2018 SCIP_CALL( SCIPconflictFree(&scip->conflict, scip->mem->probmem) );
2019 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
2020 SCIP_CALL( SCIPtreeFree(&scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
2021
2022 /* free the debug solution which might live in transformed primal data structure */
2023 SCIP_CALL( SCIPdebugFreeSol(scip->set) ); /*lint !e506 !e774*/
2024 SCIP_CALL( SCIPprimalFree(&scip->primal, scip->mem->probmem) );
2025
2026 SCIP_CALL( SCIPlpFree(&scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter) );
2027 SCIP_CALL( SCIPbranchcandFree(&scip->branchcand) );
2028 SCIP_CALL( SCIPeventfilterFree(&scip->eventfilter, scip->mem->probmem, scip->set) );
2029 SCIP_CALL( SCIPeventqueueFree(&scip->eventqueue) );
2030
2031 if( scip->set->misc_resetstat )
2032 {
2033 /* reset statistics to the point before the problem was transformed */
2034 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
2035 }
2036 else
2037 {
2038 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
2040 }
2041
2042 /* switch stage to PROBLEM */
2043 scip->set->stage = SCIP_STAGE_PROBLEM;
2044
2045 return SCIP_OKAY;
2046}
2047
2048/** displays most relevant statistics after problem was solved */
2049static
2051 SCIP* scip /**< SCIP data structure */
2052 )
2053{
2054 assert(scip != NULL);
2055
2056 /* display most relevant statistics */
2057 if( scip->set->disp_verblevel >= SCIP_VERBLEVEL_NORMAL && scip->set->disp_relevantstats )
2058 {
2059 SCIP_Bool objlimitreached = FALSE;
2060
2061 /* We output that the objective limit has been reached if the problem has been solved, no solution respecting the
2062 * objective limit has been found (nlimsolsfound == 0) and the primal bound is finite. Note that it still might be
2063 * that the original problem is infeasible, even without the objective limit, i.e., we cannot be sure that we
2064 * actually reached the objective limit. */
2065 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVED && scip->primal->nlimsolsfound == 0 && ! SCIPisInfinity(scip, SCIPgetPrimalbound(scip)) )
2066 objlimitreached = TRUE;
2067
2068 SCIPmessagePrintInfo(scip->messagehdlr, "\n");
2069 SCIPmessagePrintInfo(scip->messagehdlr, "SCIP Status : ");
2071 SCIPmessagePrintInfo(scip->messagehdlr, "\n");
2072 if( scip->set->reopt_enable )
2073 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Time (sec) : %.2f (over %d runs: %.2f)\n", SCIPclockGetTime(scip->stat->solvingtime), scip->stat->nreoptruns, SCIPclockGetTime(scip->stat->solvingtimeoverall));
2074 else
2075 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Time (sec) : %.2f\n", SCIPclockGetTime(scip->stat->solvingtime));
2076 if( scip->stat->nruns > 1 )
2077 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT " (total of %" SCIP_LONGINT_FORMAT " nodes in %d runs)\n",
2078 scip->stat->nnodes, scip->stat->ntotalnodes, scip->stat->nruns);
2079 else if( scip->set->reopt_enable )
2080 {
2081 SCIP_BRANCHRULE* branchrule;
2082
2083 branchrule = SCIPfindBranchrule(scip, "nodereopt");
2084 assert(branchrule != NULL);
2085
2086 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " reactivated)\n", scip->stat->nnodes, SCIPbranchruleGetNChildren(branchrule));
2087 }
2088 else
2089 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT "\n", scip->stat->nnodes);
2090 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED && scip->set->stage <= SCIP_STAGE_EXITSOLVE )
2091 {
2092 if( objlimitreached )
2093 {
2094 SCIPmessagePrintInfo(scip->messagehdlr, "Primal Bound : %+.14e (objective limit, %" SCIP_LONGINT_FORMAT " solutions",
2095 SCIPgetPrimalbound(scip), scip->primal->nsolsfound);
2096 if( scip->primal->nsolsfound > 0 )
2097 {
2098 SCIPmessagePrintInfo(scip->messagehdlr, ", best solution %+.14e", SCIPgetSolOrigObj(scip, SCIPgetBestSol(scip)));
2099 }
2100 SCIPmessagePrintInfo(scip->messagehdlr, ")\n");
2101 }
2102 else
2103 {
2104 char limsolstring[SCIP_MAXSTRLEN];
2105 if( scip->primal->nsolsfound != scip->primal->nlimsolsfound )
2106 (void) SCIPsnprintf(limsolstring, SCIP_MAXSTRLEN, ", %" SCIP_LONGINT_FORMAT " respecting the objective limit", scip->primal->nlimsolsfound);
2107 else
2108 (void) SCIPsnprintf(limsolstring, SCIP_MAXSTRLEN,"");
2109
2110 SCIPmessagePrintInfo(scip->messagehdlr, "Primal Bound : %+.14e (%" SCIP_LONGINT_FORMAT " solutions%s)\n",
2111 SCIPgetPrimalbound(scip), scip->primal->nsolsfound, limsolstring);
2112 }
2113 }
2114 if( scip->set->stage >= SCIP_STAGE_SOLVING && scip->set->stage <= SCIP_STAGE_SOLVED )
2115 {
2116 SCIPmessagePrintInfo(scip->messagehdlr, "Dual Bound : %+.14e\n", SCIPgetDualbound(scip));
2117
2118 SCIPmessagePrintInfo(scip->messagehdlr, "Gap : ");
2120 SCIPmessagePrintInfo(scip->messagehdlr, "infinite\n");
2121 else
2122 SCIPmessagePrintInfo(scip->messagehdlr, "%.2f %%\n", 100.0*SCIPgetGap(scip));
2123 }
2124
2125 /* check solution for feasibility in original problem */
2126 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED )
2127 {
2128 SCIP_SOL* sol;
2129
2130 sol = SCIPgetBestSol(scip);
2131 if( sol != NULL )
2132 {
2133 SCIP_Real checkfeastolfac;
2134 SCIP_Real oldfeastol;
2135 SCIP_Bool dispallviols;
2136 SCIP_Bool feasible;
2137
2138 oldfeastol = SCIPfeastol(scip);
2139 SCIP_CALL( SCIPgetRealParam(scip, "numerics/checkfeastolfac", &checkfeastolfac) );
2140 SCIP_CALL( SCIPgetBoolParam(scip, "display/allviols", &dispallviols) );
2141
2142 /* scale feasibility tolerance by set->num_checkfeastolfac */
2143 if( !SCIPisEQ(scip, checkfeastolfac, 1.0) )
2144 {
2145 SCIP_CALL( SCIPchgFeastol(scip, oldfeastol * checkfeastolfac) );
2146 }
2147
2148 SCIP_CALL( SCIPcheckSolOrig(scip, sol, &feasible, TRUE, dispallviols) );
2149
2150 /* restore old feasibilty tolerance */
2151 if( !SCIPisEQ(scip, checkfeastolfac, 1.0) )
2152 {
2153 SCIP_CALL( SCIPchgFeastol(scip, oldfeastol) );
2154 }
2155
2156 if( !feasible )
2157 {
2158 SCIPmessagePrintInfo(scip->messagehdlr, "best solution is not feasible in original problem\n");
2159 }
2160 }
2161 }
2162 }
2163
2164 return SCIP_OKAY;
2165}
2166
2167/** calls compression based on the reoptimization structure after the presolving */
2168static
2170 SCIP* scip /**< global SCIP settings */
2171 )
2172{
2173 SCIP_RESULT result;
2174 int c;
2175 int noldnodes;
2176 int nnewnodes;
2177
2178 result = SCIP_DIDNOTFIND;
2179
2180 noldnodes = SCIPreoptGetNNodes(scip->reopt, scip->tree->root);
2181
2182 /* do not run if there exists only the root node */
2183 if( noldnodes <= 1 )
2184 return SCIP_OKAY;
2185
2186 /* do not run a tree compression if the problem contains (implicit) integer variables */
2187 if( scip->transprob->nintvars > 0 || scip->transprob->nimplvars > 0 )
2188 return SCIP_OKAY;
2189
2190 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2191 "tree compression:\n");
2192 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2193 " given tree has %d nodes.\n", noldnodes);
2194
2195 /* sort compressions by priority */
2196 SCIPsetSortComprs(scip->set);
2197
2198 for(c = 0; c < scip->set->ncomprs; c++)
2199 {
2200 assert(result == SCIP_DIDNOTFIND || result == SCIP_DIDNOTRUN);
2201
2202 /* call tree compression technique */
2203 SCIP_CALL( SCIPcomprExec(scip->set->comprs[c], scip->set, scip->reopt, &result) );
2204
2205 if( result == SCIP_SUCCESS )
2206 {
2207 nnewnodes = SCIPreoptGetNNodes(scip->reopt, scip->tree->root);
2208 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2209 " <%s> compressed the search tree to %d nodes (rate %g).\n", SCIPcomprGetName(scip->set->comprs[c]),
2210 nnewnodes, ((SCIP_Real)nnewnodes)/noldnodes);
2211
2212 break;
2213 }
2214 }
2215
2216 if( result != SCIP_SUCCESS )
2217 {
2218 assert(result == SCIP_DIDNOTFIND || result == SCIP_DIDNOTRUN);
2219 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2220 " search tree could not be compressed.\n");
2221 }
2222
2223 return SCIP_OKAY;
2224}
2225
2226/* prepare all plugins and data structures for a reoptimization run */
2227static
2229 SCIP* scip /**< SCIP data structure */
2230 )
2231{
2232 SCIP_Bool reoptrestart;
2233
2234 assert(scip != NULL);
2235 assert(scip->set->reopt_enable);
2236
2237 /* @ todo: we could check if the problem is feasible, eg, by backtracking */
2238
2239 /* increase number of reopt_runs */
2240 ++scip->stat->nreoptruns;
2241
2242 /* inform the reoptimization plugin that a new iteration starts */
2243 SCIP_CALL( SCIPreoptAddRun(scip->reopt, scip->set, scip->mem->probmem, scip->origprob->vars,
2244 scip->origprob->nvars, scip->set->limit_maxsol) );
2245
2246 /* check whether we need to add globally valid constraints */
2247 if( scip->set->reopt_sepaglbinfsubtrees || scip->set->reopt_sepabestsol )
2248 {
2249 SCIP_CALL( SCIPreoptApplyGlbConss(scip, scip->reopt, scip->set, scip->stat, scip->mem->probmem) );
2250 }
2251
2252 /* after presolving the problem the first time we remember all global bounds and active constraints. bounds and
2253 * constraints will be restored within SCIPreoptInstallBounds() and SCIPreoptResetActiveConss().
2254 */
2255 if( scip->stat->nreoptruns == 1 )
2256 {
2257 assert(scip->set->stage == SCIP_STAGE_PRESOLVED || scip->set->stage == SCIP_STAGE_SOLVED);
2258
2259 SCIP_CALL( SCIPreoptSaveGlobalBounds(scip->reopt, scip->transprob, scip->mem->probmem) );
2260
2261 SCIP_CALL( SCIPreoptSaveActiveConss(scip->reopt, scip->set, scip->transprob, scip->mem->probmem) );
2262 }
2263 /* we are at least in the second run */
2264 else
2265 {
2266 assert(scip->transprob != NULL);
2267
2268 SCIP_CALL( SCIPreoptMergeVarHistory(scip->reopt, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) );
2269
2270 SCIP_CALL( SCIPrelaxationCreate(&scip->relaxation, scip->mem->probmem, scip->set, scip->stat, scip->primal,
2271 scip->tree) );
2272
2273 /* mark statistics before solving */
2274 SCIPstatMark(scip->stat);
2275
2276 SCIPbranchcandInvalidate(scip->branchcand);
2277
2278 SCIP_CALL( SCIPreoptResetActiveConss(scip->reopt, scip->set, scip->stat) );
2279
2280 /* check whether we want to restart the tree search */
2281 SCIP_CALL( SCIPreoptCheckRestart(scip->reopt, scip->set, scip->mem->probmem, NULL, scip->transprob->vars,
2282 scip->transprob->nvars, &reoptrestart) );
2283
2284 /* call initialization methods of plugins */
2285 SCIP_CALL( SCIPsetInitPlugins(scip->set, scip->mem->probmem, scip->stat) );
2286
2287 /* install globally valid lower and upper bounds */
2288 SCIP_CALL( SCIPreoptInstallBounds(scip->reopt, scip->set, scip->stat, scip->transprob, scip->lp, scip->branchcand,
2289 scip->eventqueue, scip->cliquetable, scip->mem->probmem) );
2290
2291 /* check, whether objective value is always integral by inspecting the problem, if it is the case adjust the
2292 * cutoff bound if primal solution is already known
2293 */
2294 SCIP_CALL( SCIPprobCheckObjIntegral(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat,
2295 scip->primal, scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
2296
2297 /* if possible, scale objective function such that it becomes integral with gcd 1 */
2298 SCIP_CALL( SCIPprobScaleObj(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
2299 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
2300
2302 }
2303
2304 /* try to compress the search tree */
2305 if( scip->set->compr_enable )
2306 {
2308 }
2309
2310 return SCIP_OKAY;
2311}
2312
2313/** transforms and presolves problem
2314 *
2315 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2316 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2317 *
2318 * @pre This method can be called if @p scip is in one of the following stages:
2319 * - \ref SCIP_STAGE_PROBLEM
2320 * - \ref SCIP_STAGE_TRANSFORMED
2321 * - \ref SCIP_STAGE_PRESOLVING
2322 * - \ref SCIP_STAGE_PRESOLVED
2323 * - \ref SCIP_STAGE_SOLVED
2324 *
2325 * @post After calling this method \SCIP reaches one of the following stages:
2326 * - \ref SCIP_STAGE_PRESOLVING if the presolving process was interrupted
2327 * - \ref SCIP_STAGE_PRESOLVED if the presolving process was finished and did not solve the problem
2328 * - \ref SCIP_STAGE_SOLVED if the problem was solved during presolving
2329 *
2330 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2331 */
2333 SCIP* scip /**< SCIP data structure */
2334 )
2335{
2336 SCIP_Bool unbounded;
2337 SCIP_Bool infeasible;
2338 SCIP_Bool vanished;
2339 SCIP_RETCODE retcode;
2340
2342
2343 /* start solving timer */
2344 SCIPclockStart(scip->stat->solvingtime, scip->set);
2345 SCIPclockStart(scip->stat->solvingtimeoverall, scip->set);
2346
2347 /* capture the CTRL-C interrupt */
2348 if( scip->set->misc_catchctrlc )
2349 SCIPinterruptCapture(scip->interrupt);
2350
2351 /* reset the user interrupt flag */
2352 scip->stat->userinterrupt = FALSE;
2354
2355 switch( scip->set->stage )
2356 {
2357 case SCIP_STAGE_PROBLEM:
2358 /* initialize solving data structures and transform problem */
2359 retcode = SCIPtransformProb(scip);
2360 if( retcode != SCIP_OKAY )
2361 {
2363 return retcode;
2364 }
2365
2366 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
2367
2368 /*lint -fallthrough*/
2369
2372 /* presolve problem */
2373 SCIP_CALL( presolve(scip, &unbounded, &infeasible, &vanished) );
2374 assert(scip->set->stage == SCIP_STAGE_PRESOLVED || scip->set->stage == SCIP_STAGE_PRESOLVING);
2375
2376 if( infeasible || unbounded || vanished )
2377 {
2378 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
2379
2380 /* initialize solving process data structures to be able to switch to SOLVED stage */
2382
2383 /* switch stage to SOLVED */
2384 scip->set->stage = SCIP_STAGE_SOLVED;
2385
2386 /* print solution message */
2387 switch( scip->stat->status )/*lint --e{788}*/
2388 {
2390 /* remove the root node from the tree, s.t. the lower bound is set to +infinity ???????????? (see initSolve())*/
2391 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
2392 break;
2393
2395 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2396 "presolving detected infeasibility\n");
2397 break;
2398
2400 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2401 "presolving detected unboundedness\n");
2402 break;
2403
2405 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2406 "presolving detected unboundedness (or infeasibility)\n");
2407 break;
2408
2409 default:
2410 /* note that this is in an internal SCIP error since the status is corrupted */
2411 SCIPerrorMessage("invalid SCIP status <%d>\n", scip->stat->status);
2412 SCIPABORT();
2413 return SCIP_ERROR; /*lint !e527*/
2414 }
2415 }
2416 else if( scip->set->stage == SCIP_STAGE_PRESOLVED )
2417 {
2418 int h;
2419
2420 /* print presolved problem statistics */
2421 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2422 "presolved problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
2423 scip->transprob->nvars, scip->transprob->nbinvars, scip->transprob->nintvars, scip->transprob->nimplvars,
2424 scip->transprob->ncontvars, scip->transprob->nconss);
2425
2426 for( h = 0; h < scip->set->nconshdlrs; ++h )
2427 {
2428 int nactiveconss;
2429
2430 nactiveconss = SCIPconshdlrGetNActiveConss(scip->set->conshdlrs[h]);
2431 if( nactiveconss > 0 )
2432 {
2433 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2434 "%7d constraints of type <%s>\n", nactiveconss, SCIPconshdlrGetName(scip->set->conshdlrs[h]));
2435 }
2436 }
2437
2438 if( SCIPprobIsObjIntegral(scip->transprob) )
2439 {
2440 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2441 "transformed objective value is always integral (scale: %.15g)\n", scip->transprob->objscale);
2442 }
2443 }
2444 else
2445 {
2446 assert(scip->set->stage == SCIP_STAGE_PRESOLVING);
2447 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "presolving was interrupted.\n");
2448 }
2449
2450 /* display timing statistics */
2451 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2452 "Presolving Time: %.2f\n", SCIPclockGetTime(scip->stat->presolvingtime));
2453 break;
2454
2456 case SCIP_STAGE_SOLVED:
2457 break;
2458
2459 default:
2460 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2461 return SCIP_INVALIDCALL;
2462 } /*lint !e788*/
2463
2464 /* release the CTRL-C interrupt */
2465 if( scip->set->misc_catchctrlc )
2466 SCIPinterruptRelease(scip->interrupt);
2467
2468 /* stop solving timer */
2469 SCIPclockStop(scip->stat->solvingtime, scip->set);
2470 SCIPclockStop(scip->stat->solvingtimeoverall, scip->set);
2471
2472 if( scip->set->stage == SCIP_STAGE_SOLVED )
2473 {
2474 /* display most relevant statistics */
2476 }
2477
2478 return SCIP_OKAY;
2479}
2480
2481/** transforms, presolves, and solves problem
2482 *
2483 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2484 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2485 *
2486 * @pre This method can be called if @p scip is in one of the following stages:
2487 * - \ref SCIP_STAGE_PROBLEM
2488 * - \ref SCIP_STAGE_TRANSFORMED
2489 * - \ref SCIP_STAGE_PRESOLVING
2490 * - \ref SCIP_STAGE_PRESOLVED
2491 * - \ref SCIP_STAGE_SOLVING
2492 * - \ref SCIP_STAGE_SOLVED
2493 *
2494 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2495 * process was interrupted:
2496 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2497 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2498 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2499 *
2500 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2501 */
2503 SCIP* scip /**< SCIP data structure */
2504 )
2505{
2506 SCIP_Longint cutpoolncutsfoundbeforerestart = 0;
2507 SCIP_Longint cutpoolncutsaddedbeforerestart = 0;
2508 SCIP_Longint cutpoolncallsbeforerestart = 0;
2509 SCIP_Longint cutpoolnrootcallsbeforerestart = 0;
2510 SCIP_Longint cutpoolmaxncutsbeforerestart = 0;
2511 SCIP_Real cutpooltimebeforerestart = 0;
2512 SCIP_Bool statsprinted = FALSE;
2513 SCIP_Bool restart;
2514 SCIP_Bool transferstatistics = FALSE;
2515
2517
2518 /* if the stage is already SCIP_STAGE_SOLVED do nothing */
2519 if( scip->set->stage == SCIP_STAGE_SOLVED )
2520 return SCIP_OKAY;
2521
2522 if( scip->stat->status == SCIP_STATUS_INFEASIBLE || scip->stat->status == SCIP_STATUS_OPTIMAL || scip->stat->status == SCIP_STATUS_UNBOUNDED || scip->stat->status == SCIP_STATUS_INFORUNBD )
2523 {
2524 SCIPwarningMessage(scip, "SCIPsolve() was called, but problem is already solved\n");
2525 return SCIP_OKAY;
2526 }
2527
2528 /* check, if a node selector exists */
2529 if( SCIPsetGetNodesel(scip->set, scip->stat) == NULL )
2530 {
2531 SCIPerrorMessage("no node selector available\n");
2532 return SCIP_PLUGINNOTFOUND;
2533 }
2534
2535 /* check, if an integrality constraint handler exists if there are integral variables */
2536 if( (SCIPgetNBinVars(scip) >= 0 || SCIPgetNIntVars(scip) >= 0) && SCIPfindConshdlr(scip, "integral") == NULL )
2537 {
2538 SCIPwarningMessage(scip, "integrality constraint handler not available\n");
2539 }
2540
2541 /* initialize presolving flag (may be modified in SCIPpresolve()) */
2542 scip->stat->performpresol = FALSE;
2543
2544 /* if a decomposition exists and Benders' decomposition has been enabled, then a decomposition is performed */
2545 if( scip->set->stage == SCIP_STAGE_PROBLEM && SCIPdecompstoreGetNOrigDecomps(scip->decompstore) > 0
2546 && scip->set->decomp_applybenders && SCIPgetNActiveBenders(scip) == 0 )
2547 {
2548 int decompindex = 0;
2549
2550 /* applying the Benders' decomposition */
2552 }
2553
2554 /* start solving timer */
2555 SCIPclockStart(scip->stat->solvingtime, scip->set);
2556 SCIPclockStart(scip->stat->solvingtimeoverall, scip->set);
2557
2558 /* capture the CTRL-C interrupt */
2559 if( scip->set->misc_catchctrlc )
2560 SCIPinterruptCapture(scip->interrupt);
2561
2562 /* reset the user interrupt flag */
2563 scip->stat->userinterrupt = FALSE;
2565
2566 /* automatic restarting loop */
2567 restart = scip->stat->userrestart;
2568
2569 do
2570 {
2571 if( restart )
2572 {
2573 transferstatistics = TRUE;
2574 cutpoolncutsfoundbeforerestart = SCIPcutpoolGetNCutsFound(scip->cutpool);
2575 cutpoolncutsaddedbeforerestart = SCIPcutpoolGetNCutsAdded(scip->cutpool);
2576 cutpooltimebeforerestart = SCIPcutpoolGetTime(scip->cutpool);
2577 cutpoolncallsbeforerestart = SCIPcutpoolGetNCalls(scip->cutpool);
2578 cutpoolnrootcallsbeforerestart = SCIPcutpoolGetNRootCalls(scip->cutpool);
2579 cutpoolmaxncutsbeforerestart = SCIPcutpoolGetMaxNCuts(scip->cutpool);
2580
2581 /* free the solving process data in order to restart */
2582 assert(scip->set->stage == SCIP_STAGE_SOLVING);
2583 if( scip->stat->userrestart )
2585 "(run %d, node %" SCIP_LONGINT_FORMAT ") performing user restart\n",
2586 scip->stat->nruns, scip->stat->nnodes);
2587 else
2589 "(run %d, node %" SCIP_LONGINT_FORMAT ") restarting after %d global fixings of integer variables\n",
2590 scip->stat->nruns, scip->stat->nnodes, scip->stat->nrootintfixingsrun);
2591 /* an extra blank line should be printed separately since the buffer message handler only handles up to one line
2592 * correctly */
2594 /* reset relaxation solution, so that the objective value is recomputed from scratch next time, using the new
2595 * fixings which may be produced during the presolving after the restart */
2597
2599 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
2600 }
2601 restart = FALSE;
2602 scip->stat->userrestart = FALSE;
2603
2604 switch( scip->set->stage )
2605 {
2606 case SCIP_STAGE_PROBLEM:
2609 /* initialize solving data structures, transform and problem */
2610
2612 /* remember that we already printed the relevant statistics */
2613 if( scip->set->stage == SCIP_STAGE_SOLVED )
2614 statsprinted = TRUE;
2615
2616 if( scip->set->stage == SCIP_STAGE_SOLVED || scip->set->stage == SCIP_STAGE_PRESOLVING )
2617 {
2618 if ( scip->set->reopt_enable )
2619 {
2621 }
2622 break;
2623 }
2624 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
2625
2626 /* abort if a node limit was reached */
2627 if( SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
2628 break;
2629 /*lint -fallthrough*/
2630
2632 /* check if reoptimization is enabled and global constraints are saved */
2633 if( scip->set->reopt_enable )
2634 {
2636 }
2637
2638 /* initialize solving process data structures */
2640 assert(scip->set->stage == SCIP_STAGE_SOLVING);
2641 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL, "\n");
2642
2643 /*lint -fallthrough*/
2644
2645 case SCIP_STAGE_SOLVING:
2646 /* reset display */
2648
2649 /* remember cutpool statistics after restart */
2650 if( transferstatistics )
2651 {
2652 SCIPcutpoolAddNCutsFound(scip->cutpool, cutpoolncutsfoundbeforerestart);
2653 SCIPcutpoolAddNCutsAdded(scip->cutpool, cutpoolncutsaddedbeforerestart);
2654 SCIPcutpoolSetTime(scip->cutpool, cutpooltimebeforerestart);
2655 SCIPcutpoolAddNCalls(scip->cutpool, cutpoolncallsbeforerestart);
2656 SCIPcutpoolAddNRootCalls(scip->cutpool, cutpoolnrootcallsbeforerestart);
2657 SCIPcutpoolAddMaxNCuts(scip->cutpool, cutpoolmaxncutsbeforerestart);
2658 }
2659
2660 /* continue solution process */
2661 SCIP_CALL( SCIPsolveCIP(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->mem, scip->origprob, scip->transprob,
2662 scip->primal, scip->tree, scip->reopt, scip->lp, scip->relaxation, scip->pricestore, scip->sepastore,
2663 scip->cutpool, scip->delayedcutpool, scip->branchcand, scip->conflict, scip->conflictstore,
2664 scip->eventfilter, scip->eventqueue, scip->cliquetable, &restart) );
2665
2666 /* detect, whether problem is solved */
2667 if( SCIPtreeGetNNodes(scip->tree) == 0 && SCIPtreeGetCurrentNode(scip->tree) == NULL )
2668 {
2669 assert(scip->stat->status == SCIP_STATUS_OPTIMAL
2670 || scip->stat->status == SCIP_STATUS_INFEASIBLE
2671 || scip->stat->status == SCIP_STATUS_UNBOUNDED
2672 || scip->stat->status == SCIP_STATUS_INFORUNBD);
2673 assert(!restart);
2674
2675 /* tree is empty, and no current node exists -> problem is solved */
2676 scip->set->stage = SCIP_STAGE_SOLVED;
2677 }
2678 break;
2679
2680 case SCIP_STAGE_SOLVED:
2681 assert(scip->stat->status == SCIP_STATUS_OPTIMAL
2682 || scip->stat->status == SCIP_STATUS_INFEASIBLE
2683 || scip->stat->status == SCIP_STATUS_UNBOUNDED
2684 || scip->stat->status == SCIP_STATUS_INFORUNBD);
2685
2686 break;
2687
2688 default:
2689 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2690 return SCIP_INVALIDCALL;
2691 } /*lint !e788*/
2692 }
2693 while( restart && !SCIPsolveIsStopped(scip->set, scip->stat, TRUE) );
2694
2695 /* we have to store all unprocessed nodes if reoptimization is enabled */
2696 if( scip->set->reopt_enable && scip->set->stage != SCIP_STAGE_PRESOLVING
2697 && SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
2698 {
2699 /* save unprocessed nodes */
2700 if( SCIPgetNNodesLeft(scip) > 0 )
2701 {
2702 SCIP_NODE** leaves;
2703 SCIP_NODE** children;
2704 SCIP_NODE** siblings;
2705 int nleaves;
2706 int nchildren;
2707 int nsiblings;
2708
2709 /* get all open leave nodes */
2710 SCIP_CALL( SCIPgetLeaves(scip, &leaves, &nleaves) );
2711
2712 /* get all open children nodes */
2713 SCIP_CALL( SCIPgetChildren(scip, &children, &nchildren) );
2714
2715 /* get all open sibling nodes */
2716 SCIP_CALL( SCIPgetSiblings(scip, &siblings, &nsiblings) );
2717
2718 /* add all open node to the reoptimization tree */
2719 SCIP_CALL( SCIPreoptSaveOpenNodes(scip->reopt, scip->set, scip->lp, scip->mem->probmem, leaves, nleaves,
2720 children, nchildren, siblings, nsiblings) );
2721 }
2722 }
2723
2724 /* release the CTRL-C interrupt */
2725 if( scip->set->misc_catchctrlc )
2726 SCIPinterruptRelease(scip->interrupt);
2727
2728 if( scip->set->reopt_enable )
2729 {
2730 /* save found solutions */
2731 int nsols;
2732 int s;
2733
2734 nsols = scip->set->reopt_savesols == -1 ? INT_MAX : MAX(scip->set->reopt_savesols, 1);
2735 nsols = MIN(scip->primal->nsols, nsols);
2736
2737 for( s = 0; s < nsols; s++ )
2738 {
2739 SCIP_SOL* sol;
2740 SCIP_Bool added;
2741
2742 sol = scip->primal->sols[s];
2743 assert(sol != NULL);
2744
2745 if( !SCIPsolIsOriginal(sol) )
2746 {
2747 SCIP_Bool hasinfval;
2748
2749 /* retransform solution into the original problem space */
2750 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
2751 }
2752
2753 if( SCIPsolGetNodenum(sol) > 0 || SCIPsolGetHeur(sol) != NULL || (s == 0 && scip->set->reopt_sepabestsol) )
2754 {
2755 /* if the best solution should be separated, we must not store it in the solution tree */
2756 if( s == 0 && scip->set->reopt_sepabestsol )
2757 {
2758 SCIP_CALL( SCIPreoptAddOptSol(scip->reopt, sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal,
2759 scip->origprob->vars, scip->origprob->nvars) );
2760 }
2761 /* add solution to solution tree */
2762 else
2763 {
2764 SCIPdebugMsg(scip, "try to add solution to the solution tree:\n");
2765 SCIPdebug( SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, \
2766 scip->transprob, NULL, FALSE, FALSE) ); );
2767
2768 SCIP_CALL( SCIPreoptAddSol(scip->reopt, scip->set, scip->stat, scip->origprimal, scip->mem->probmem,
2769 sol, s == 0, &added, scip->origprob->vars, scip->origprob->nvars, scip->stat->nreoptruns) );
2770 }
2771 }
2772 }
2773
2774 SCIPdebugMsg(scip, "-> saved %d solution.\n", nsols);
2775
2776 /* store variable history */
2777 if( scip->set->reopt_storevarhistory )
2778 {
2779 SCIP_CALL( SCIPreoptUpdateVarHistory(scip->reopt, scip->set, scip->stat, scip->mem->probmem,
2780 scip->origprob->vars, scip->origprob->nvars) );
2781 }
2782 }
2783
2784 /* stop solving timer */
2785 SCIPclockStop(scip->stat->solvingtime, scip->set);
2786 SCIPclockStop(scip->stat->solvingtimeoverall, scip->set);
2787
2788 /* decrease time limit during reoptimization */
2789 if( scip->set->reopt_enable && scip->set->reopt_commontimelimit )
2790 {
2791 SCIP_Real timelimit;
2792 SCIP_Real usedtime;
2793
2794 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
2795 usedtime = SCIPgetSolvingTime(scip);
2796 timelimit = timelimit - usedtime;
2797 timelimit = MAX(0, timelimit);
2798
2799 SCIP_CALL( SCIPsetRealParam(scip, "limits/time", timelimit) );
2800 }
2801
2802 if( !statsprinted )
2803 {
2804 /* display most relevant statistics */
2806 }
2807
2808 return SCIP_OKAY;
2809}
2810
2811/** transforms, presolves, and solves problem using the configured concurrent solvers
2812 *
2813 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2814 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2815 *
2816 * @pre This method can be called if @p scip is in one of the following stages:
2817 * - \ref SCIP_STAGE_PROBLEM
2818 * - \ref SCIP_STAGE_TRANSFORMED
2819 * - \ref SCIP_STAGE_PRESOLVING
2820 * - \ref SCIP_STAGE_PRESOLVED
2821 * - \ref SCIP_STAGE_SOLVING
2822 * - \ref SCIP_STAGE_SOLVED
2823 *
2824 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2825 * process was interrupted:
2826 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2827 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2828 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2829 *
2830 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2831 *
2832 * @deprecated Please use SCIPsolveConcurrent() instead.
2833 */
2835 SCIP* scip /**< SCIP data structure */
2836 )
2837{
2838 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveParallel", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2839
2840 return SCIPsolveConcurrent(scip);
2841}
2842
2843/** transforms, presolves, and solves problem using the configured concurrent solvers
2844 *
2845 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2846 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2847 *
2848 * @pre This method can be called if @p scip is in one of the following stages:
2849 * - \ref SCIP_STAGE_PROBLEM
2850 * - \ref SCIP_STAGE_TRANSFORMED
2851 * - \ref SCIP_STAGE_PRESOLVING
2852 * - \ref SCIP_STAGE_PRESOLVED
2853 * - \ref SCIP_STAGE_SOLVING
2854 * - \ref SCIP_STAGE_SOLVED
2855 *
2856 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2857 * process was interrupted:
2858 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2859 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2860 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2861 *
2862 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2863 */
2865 SCIP* scip /**< SCIP data structure */
2866 )
2867{
2868 SCIP_RETCODE retcode;
2869 int i;
2870 SCIP_RANDNUMGEN* rndgen;
2871 int minnthreads;
2872 int maxnthreads;
2873
2874 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveConcurrent", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2875
2876 if( !SCIPtpiIsAvailable() )
2877 {
2878 SCIPerrorMessage("SCIP was compiled without task processing interface. Concurrent solve not possible\n");
2879 return SCIP_PLUGINNOTFOUND;
2880 }
2881
2882 SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", (int)SCIP_CLOCKTYPE_WALL) );
2883
2884 minnthreads = scip->set->parallel_minnthreads;
2885 maxnthreads = scip->set->parallel_maxnthreads;
2886
2887 if( minnthreads > maxnthreads )
2888 {
2889 SCIPerrorMessage("minimum number of threads greater than maximum number of threads\n");
2890 return SCIP_INVALIDDATA;
2891 }
2892 if( scip->concurrent == NULL )
2893 {
2894 int nconcsolvertypes;
2895 SCIP_CONCSOLVERTYPE** concsolvertypes;
2896 int nthreads;
2897 SCIP_Real memorylimit;
2898 int* solvertypes;
2899 SCIP_Longint* weights;
2900 SCIP_Real* prios;
2901 int ncandsolvertypes;
2902 SCIP_Real prefpriosum;
2903
2904 /* check if concurrent solve is configured to presolve the problem
2905 * before setting up the concurrent solvers
2906 */
2907 if( scip->set->concurrent_presolvebefore )
2908 {
2909 /* if yes, then presolve the problem */
2912 return SCIP_OKAY;
2913 }
2914 else
2915 {
2916 SCIP_Bool infeas;
2917
2918 /* if not, transform the problem and switch stage to presolved */
2921 SCIP_CALL( exitPresolve(scip, TRUE, &infeas) );
2922 assert(!infeas);
2923 }
2924
2925 /* the presolving must have run into a limit, so we stop here */
2926 if( scip->set->stage < SCIP_STAGE_PRESOLVED )
2927 {
2929 return SCIP_OKAY;
2930 }
2931
2932 nthreads = INT_MAX;
2933 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
2934 memorylimit = scip->set->limit_memory;
2935 if( memorylimit < SCIP_MEM_NOLIMIT )
2936 {
2937 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
2938 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
2939 /* estimate maximum number of copies that be created based on memory limit */
2940 if( !scip->set->misc_avoidmemout )
2941 {
2942 nthreads = MAX(1, memorylimit / (4.0*SCIPgetMemExternEstim(scip)/1048576.0)); /*lint !e666 !e524*/
2943 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "estimated a maximum of %d threads based on memory limit\n", nthreads);
2944 }
2945 else
2946 {
2947 nthreads = minnthreads;
2948 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "ignoring memory limit; all threads can be created\n");
2949 }
2950 }
2951 nconcsolvertypes = SCIPgetNConcsolverTypes(scip);
2952 concsolvertypes = SCIPgetConcsolverTypes(scip);
2953
2954 if( minnthreads > nthreads )
2955 {
2957 scip->stat->status = SCIP_STATUS_MEMLIMIT;
2959 SCIPwarningMessage(scip, "requested minimum number of threads could not be satisfied with given memory limit\n");
2961 return SCIP_OKAY;
2962 }
2963
2964 if( nthreads == 1 )
2965 {
2966 SCIPwarningMessage(scip, "can only use 1 thread, doing sequential solve instead\n");
2968 return SCIPsolve(scip);
2969 }
2970 nthreads = MIN(nthreads, maxnthreads);
2971 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "using %d threads for concurrent solve\n", nthreads);
2972
2973 /* now set up nthreads many concurrent solvers that will be used for the concurrent solve
2974 * using the preferred priorities of each concurrent solver
2975 */
2976 prefpriosum = 0.0;
2977 for( i = 0; i < nconcsolvertypes; ++i )
2978 prefpriosum += SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]);
2979 assert(prefpriosum != 0.0);
2980
2981 ncandsolvertypes = 0;
2982 SCIP_CALL( SCIPallocBufferArray(scip, &solvertypes, nthreads + nconcsolvertypes) );
2983 SCIP_CALL( SCIPallocBufferArray(scip, &weights, nthreads + nconcsolvertypes) );
2984 SCIP_CALL( SCIPallocBufferArray(scip, &prios, nthreads + nconcsolvertypes) );
2985 for( i = 0; i < nconcsolvertypes; ++i )
2986 {
2987 int j;
2988 SCIP_Real prio;
2989 prio = nthreads * SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]) / prefpriosum;
2990 while( prio > 0.0 )
2991 {
2992 j = ncandsolvertypes++;
2993 assert(j < 2*nthreads);
2994 weights[j] = 1;
2995 solvertypes[j] = i;
2996 prios[j] = MIN(1.0, prio);
2997 prio = prio - 1.0;
2998 }
2999 }
3000 /* select nthreads many concurrent solver types to create instances
3001 * according to the preferred prioriteis the user has set
3002 * This basically corresponds to a knapsack problem
3003 * with unit weights and capacity nthreads, where the profits are
3004 * the unrounded fraction of the total number of threads to be used.
3005 */
3006 SCIPselectDownRealInt(prios, solvertypes, nthreads, ncandsolvertypes);
3007
3008 SCIP_CALL( SCIPcreateRandom(scip, &rndgen, (unsigned) scip->set->concurrent_initseed, TRUE) );
3009 for( i = 0; i < nthreads; ++i )
3010 {
3011 SCIP_CONCSOLVER* concsolver;
3012
3013 SCIP_CALL( SCIPconcsolverCreateInstance(scip->set, concsolvertypes[solvertypes[i]], &concsolver) );
3014 if( scip->set->concurrent_changeseeds && SCIPgetNConcurrentSolvers(scip) > 1 )
3015 SCIP_CALL( SCIPconcsolverInitSeeds(concsolver, (unsigned int)SCIPrandomGetInt(rndgen, 0, INT_MAX)) );
3016 }
3017 SCIPfreeRandom(scip, &rndgen);
3018 SCIPfreeBufferArray(scip, &prios);
3019 SCIPfreeBufferArray(scip, &weights);
3020 SCIPfreeBufferArray(scip, &solvertypes);
3021
3022 assert(SCIPgetNConcurrentSolvers(scip) == nthreads);
3023
3025 }
3026
3028 {
3029 /* switch stage to solving */
3031 }
3032
3033 SCIPclockStart(scip->stat->solvingtime, scip->set);
3034 retcode = SCIPconcurrentSolve(scip);
3035 SCIPclockStop(scip->stat->solvingtime, scip->set);
3037
3038 return retcode;
3039}
3040
3041/** include specific heuristics and branching rules for reoptimization
3042 *
3043 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3044 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3045 *
3046 * @pre This method can be called if @p scip is in one of the following stages:
3047 * - \ref SCIP_STAGE_PROBLEM
3048 */
3050 SCIP* scip, /**< SCIP data structure */
3051 SCIP_Bool enable /**< enable reoptimization (TRUE) or disable it (FALSE) */
3052 )
3053{
3054 assert(scip != NULL);
3055
3056 /* we want to skip if nothing has changed */
3057 if( (enable && scip->set->reopt_enable && scip->reopt != NULL)
3058 || (!enable && !scip->set->reopt_enable && scip->reopt == NULL) )
3059 return SCIP_OKAY;
3060
3061 /* check stage and throw an error if we try to disable reoptimization during the solving process.
3062 *
3063 * @note the case that we will disable the reoptimization and have already performed presolving can only happen if
3064 * we are try to solve a general MIP
3065 *
3066 * @note this fix is only for the bugfix release 3.2.1, in the next major release reoptimization can be used for
3067 * general MIPs, too.
3068 */
3069 if( scip->set->stage > SCIP_STAGE_PROBLEM && !(!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3070 {
3071 SCIPerrorMessage("Reoptimization cannot be %s after starting the (pre)solving process.\n", enable ? "enabled" : "disabled");
3072 return SCIP_INVALIDCALL;
3073 }
3074
3075 /* if the current stage is SCIP_STAGE_PROBLEM we have to include the heuristics and branching rule */
3076 if( scip->set->stage == SCIP_STAGE_PROBLEM || (!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3077 {
3078 /* initialize all reoptimization data structures */
3079 if( enable && scip->reopt == NULL )
3080 {
3081 /* set enable flag */
3082 scip->set->reopt_enable = enable;
3083
3084 SCIP_CALL( SCIPreoptCreate(&scip->reopt, scip->set, scip->mem->probmem) );
3085 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3086 }
3087 /* disable all reoptimization plugins and free the structure if necessary */
3088 else if( (!enable && scip->reopt != NULL) || (!enable && scip->set->reopt_enable && scip->reopt == NULL) )
3089 {
3090 /* set enable flag */
3091 scip->set->reopt_enable = enable;
3092
3093 if( scip->reopt != NULL )
3094 {
3095 SCIP_CALL( SCIPreoptFree(&(scip->reopt), scip->set, scip->origprimal, scip->mem->probmem) );
3096 assert(scip->reopt == NULL);
3097 }
3098 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3099 }
3100 }
3101 else
3102 {
3103 /* set enable flag */
3104 scip->set->reopt_enable = enable;
3105 }
3106
3107 return SCIP_OKAY;
3108}
3109
3110/** save bound change based on dual information in the reoptimization tree
3111 *
3112 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3113 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3114 *
3115 * @pre This method can be called if @p scip is in one of the following stages:
3116 * - \ref SCIP_STAGE_SOLVING
3117 * - \ref SCIP_STAGE_SOLVED
3118 */
3120 SCIP* scip, /**< SCIP data structure */
3121 SCIP_NODE* node, /**< node of the search tree */
3122 SCIP_VAR* var, /**< variable whose bound changed */
3123 SCIP_Real newbound, /**< new bound of the variable */
3124 SCIP_Real oldbound /**< old bound of the variable */
3125 )
3126{
3127 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddReoptDualBndchg", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3128
3129 assert(SCIPsetIsFeasLT(scip->set, newbound, oldbound) || SCIPsetIsFeasGT(scip->set, newbound, oldbound));
3130
3131 SCIP_CALL( SCIPreoptAddDualBndchg(scip->reopt, scip->set, scip->mem->probmem, node, var, newbound, oldbound) );
3132
3133 return SCIP_OKAY;
3134}
3135
3136/** returns the optimal solution of the last iteration or NULL of none exists */
3138 SCIP* scip /**< SCIP data structure */
3139 )
3140{
3141 SCIP_SOL* sol;
3142
3143 assert(scip != NULL);
3144
3145 sol = NULL;
3146
3147 if( scip->set->reopt_enable && scip->stat->nreoptruns > 1 )
3148 {
3149 sol = SCIPreoptGetLastBestSol(scip->reopt);
3150 }
3151
3152 return sol;
3153}
3154
3155/** returns the objective coefficent of a given variable in a previous iteration
3156 *
3157 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3158 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3159 *
3160 * @pre This method can be called if @p scip is in one of the following stages:
3161 * - \ref SCIP_STAGE_PRESOLVING
3162 * - \ref SCIP_STAGE_SOLVING
3163 */
3165 SCIP* scip, /**< SCIP data structure */
3166 SCIP_VAR* var, /**< variable */
3167 int run, /**< number of the run */
3168 SCIP_Real* objcoef /**< pointer to store the objective coefficient */
3169 )
3170{
3171 assert(scip != NULL);
3172 assert(var != NULL);
3173 assert(0 < run && run <= scip->stat->nreoptruns);
3174
3175 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetReoptOldObjCoef", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3176
3177 if( SCIPvarIsOriginal(var) )
3178 *objcoef = SCIPreoptGetOldObjCoef(scip->reopt, run, SCIPvarGetIndex(var));
3179 else
3180 {
3181 SCIP_VAR* origvar;
3182 SCIP_Real constant;
3183 SCIP_Real scalar;
3184
3185 assert(SCIPvarIsActive(var));
3186
3187 origvar = var;
3188 constant = 0.0;
3189 scalar = 1.0;
3190
3191 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
3192 assert(origvar != NULL);
3193 assert(SCIPvarIsOriginal(origvar));
3194
3195 *objcoef = SCIPreoptGetOldObjCoef(scip->reopt, run, SCIPvarGetIndex(origvar));
3196 }
3197 return SCIP_OKAY;
3198}
3199
3200/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3201 * preserved
3202 *
3203 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3204 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3205 *
3206 * @pre This method can be called if @p scip is in one of the following stages:
3207 * - \ref SCIP_STAGE_INIT
3208 * - \ref SCIP_STAGE_PROBLEM
3209 * - \ref SCIP_STAGE_TRANSFORMED
3210 * - \ref SCIP_STAGE_PRESOLVING
3211 * - \ref SCIP_STAGE_PRESOLVED
3212 * - \ref SCIP_STAGE_SOLVING
3213 * - \ref SCIP_STAGE_SOLVED
3214 *
3215 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT or \ref SCIP_STAGE_PROBLEM, the stage of
3216 * \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_TRANSFORMED
3217 *
3218 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3219 */
3221 SCIP* scip, /**< SCIP data structure */
3222 SCIP_Bool restart /**< should certain data be preserved for improved restarting? */
3223 )
3224{
3226
3227 switch( scip->set->stage )
3228 {
3229 case SCIP_STAGE_INIT:
3231 case SCIP_STAGE_PROBLEM:
3232 return SCIP_OKAY;
3233
3235 {
3236 SCIP_Bool infeasible;
3237
3238 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3239 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3240 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3241 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3242
3243 /* exit presolving */
3244 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3245 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3246 }
3247
3248 /*lint -fallthrough*/
3250 /* switch stage to TRANSFORMED */
3251 scip->set->stage = SCIP_STAGE_TRANSFORMED;
3252 return SCIP_OKAY;
3253
3254 case SCIP_STAGE_SOLVING:
3255 case SCIP_STAGE_SOLVED:
3256 /* free solution process data structures */
3257 SCIP_CALL( freeSolve(scip, restart) );
3258 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3259 return SCIP_OKAY;
3260
3261 default:
3262 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3263 return SCIP_INVALIDCALL;
3264 } /*lint !e788*/
3265}
3266
3267/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3268 * preserved
3269 *
3270 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3271 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3272 *
3273 * @pre This method can be called if @p scip is in one of the following stages:
3274 * - \ref SCIP_STAGE_INIT
3275 * - \ref SCIP_STAGE_PROBLEM
3276 * - \ref SCIP_STAGE_TRANSFORMED
3277 * - \ref SCIP_STAGE_PRESOLVING
3278 * - \ref SCIP_STAGE_PRESOLVED
3279 * - \ref SCIP_STAGE_SOLVING
3280 * - \ref SCIP_STAGE_SOLVED
3281 *
3282 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT, \ref SCIP_STAGE_TRANSFORMED or \ref SCIP_STAGE_PROBLEM,
3283 * the stage of \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_PRESOLVED.
3284 *
3285 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3286 */
3288 SCIP* scip /**< SCIP data structure */
3289 )
3290{
3291 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeReoptSolve", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3292
3293 switch( scip->set->stage )
3294 {
3295 case SCIP_STAGE_INIT:
3298 case SCIP_STAGE_PROBLEM:
3299 return SCIP_OKAY;
3300
3302 {
3303 SCIP_Bool infeasible;
3304
3305 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3306 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3307 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3308 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3309
3310 /* exit presolving */
3311 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3312 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3313
3314 return SCIP_OKAY;
3315 }
3316
3317 case SCIP_STAGE_SOLVING:
3318 case SCIP_STAGE_SOLVED:
3319 /* free solution process data structures */
3321 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3322 return SCIP_OKAY;
3323
3324 default:
3325 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3326 return SCIP_INVALIDCALL;
3327 } /*lint !e788*/
3328}
3329
3330/** frees all solution process data including presolving and transformed problem, only original problem is kept
3331 *
3332 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3333 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3334 *
3335 * @pre This method can be called if @p scip is in one of the following stages:
3336 * - \ref SCIP_STAGE_INIT
3337 * - \ref SCIP_STAGE_PROBLEM
3338 * - \ref SCIP_STAGE_TRANSFORMED
3339 * - \ref SCIP_STAGE_PRESOLVING
3340 * - \ref SCIP_STAGE_PRESOLVED
3341 * - \ref SCIP_STAGE_SOLVING
3342 * - \ref SCIP_STAGE_SOLVED
3343 *
3344 * @post After calling this method \SCIP reaches one of the following stages:
3345 * - \ref SCIP_STAGE_INIT if the method was called from \SCIP stage \ref SCIP_STAGE_INIT
3346 * - \ref SCIP_STAGE_PROBLEM if the method was called from any other of the allowed stages
3347 *
3348 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3349 */
3351 SCIP* scip /**< SCIP data structure */
3352 )
3353{
3354 assert(scip != NULL);
3355
3356 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeTransform", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3357
3358 /* release variables and constraints captured by reoptimization */
3359 if( scip->reopt != NULL )
3360 {
3361 SCIP_CALL( SCIPreoptReleaseData(scip->reopt, scip->set, scip->mem->probmem) );
3362 }
3363
3364 switch( scip->set->stage )
3365 {
3366 case SCIP_STAGE_INIT:
3367 case SCIP_STAGE_PROBLEM:
3368 return SCIP_OKAY;
3369
3371 {
3372 SCIP_Bool infeasible;
3373
3374 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3375 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3376 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3377 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3378
3379 /* exit presolving */
3380 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3381 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3382 }
3383
3384 /*lint -fallthrough*/
3386 case SCIP_STAGE_SOLVING:
3387 case SCIP_STAGE_SOLVED:
3388 /* the solve was already freed, we directly go to freeTransform() */
3389 if( !scip->set->reopt_enable || scip->set->stage != SCIP_STAGE_PRESOLVED )
3390 {
3391 /* free solution process data */
3393 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3394 }
3395 /*lint -fallthrough*/
3396
3398 /* free transformed problem data structures */
3400 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3401 return SCIP_OKAY;
3402
3404 assert(scip->set->stage == SCIP_STAGE_TRANSFORMING);
3406 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3407 return SCIP_OKAY;
3408
3409 default:
3410 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3411 return SCIP_INVALIDCALL;
3412 } /*lint !e788*/
3413}
3414
3415/** informs \SCIP that the solving process should be interrupted as soon as possible (e.g., after the current node has
3416 * been solved)
3417 *
3418 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3419 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3420 *
3421 * @pre This method can be called if @p scip is in one of the following stages:
3422 * - \ref SCIP_STAGE_PROBLEM
3423 * - \ref SCIP_STAGE_TRANSFORMING
3424 * - \ref SCIP_STAGE_TRANSFORMED
3425 * - \ref SCIP_STAGE_INITPRESOLVE
3426 * - \ref SCIP_STAGE_PRESOLVING
3427 * - \ref SCIP_STAGE_EXITPRESOLVE
3428 * - \ref SCIP_STAGE_PRESOLVED
3429 * - \ref SCIP_STAGE_SOLVING
3430 * - \ref SCIP_STAGE_SOLVED
3431 * - \ref SCIP_STAGE_EXITSOLVE
3432 * - \ref SCIP_STAGE_FREETRANS
3433 *
3434 * @note the \SCIP stage does not get changed
3435 */
3437 SCIP* scip /**< SCIP data structure */
3438 )
3439{
3440 SCIP_CALL( SCIPcheckStage(scip, "SCIPinterruptSolve", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3441
3442 /* set the userinterrupt flag */
3443 scip->stat->userinterrupt = TRUE;
3444
3445 return SCIP_OKAY;
3446}
3447
3448/** indicates whether \SCIP has been informed that the solving process should be interrupted as soon as possible
3449 *
3450 * This function returns whether SCIPinterruptSolve() has been called, which is different from SCIPinterrupted(),
3451 * which returns whether a SIGINT signal has been received by the SCIP signal handler.
3452 *
3453 * @pre This method can be called if @p scip is in one of the following stages:
3454 * - \ref SCIP_STAGE_PROBLEM
3455 * - \ref SCIP_STAGE_TRANSFORMING
3456 * - \ref SCIP_STAGE_TRANSFORMED
3457 * - \ref SCIP_STAGE_INITPRESOLVE
3458 * - \ref SCIP_STAGE_PRESOLVING
3459 * - \ref SCIP_STAGE_EXITPRESOLVE
3460 * - \ref SCIP_STAGE_PRESOLVED
3461 * - \ref SCIP_STAGE_SOLVING
3462 * - \ref SCIP_STAGE_SOLVED
3463 * - \ref SCIP_STAGE_EXITSOLVE
3464 * - \ref SCIP_STAGE_FREETRANS
3465 *
3466 * @note the \SCIP stage does not get changed
3467 */
3469 SCIP* scip /**< SCIP data structure */
3470 )
3471{
3472 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisSolveInterrupted", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3473
3474 return scip->stat->userinterrupt;
3475}
3476
3477/** informs SCIP that the solving process should be restarted as soon as possible (e.g., after the current node has
3478 * been solved)
3479 *
3480 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3481 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3482 *
3483 * @pre This method can be called if @p scip is in one of the following stages:
3484 * - \ref SCIP_STAGE_INITPRESOLVE
3485 * - \ref SCIP_STAGE_PRESOLVING
3486 * - \ref SCIP_STAGE_EXITPRESOLVE
3487 * - \ref SCIP_STAGE_SOLVING
3488 *
3489 * @note the \SCIP stage does not get changed
3490 */
3492 SCIP* scip /**< SCIP data structure */
3493 )
3494{
3496
3497 /* set the userrestart flag */
3498 scip->stat->userrestart = TRUE;
3499
3500 return SCIP_OKAY;
3501}
3502
3503/** returns whether reoptimization is enabled or not */
3505 SCIP* scip /**< SCIP data structure */
3506 )
3507{
3508 assert(scip != NULL);
3509
3510 return scip->set->reopt_enable;
3511}
3512
3513/** returns the stored solutions corresponding to a given run */
3515 SCIP* scip, /**< SCIP data structure */
3516 int run, /**< number of the run */
3517 SCIP_SOL** sols, /**< array to store solutions */
3518 int solssize, /**< size of the array */
3519 int* nsols /**< pointer to store number of solutions */
3520 )
3521{
3522 assert(scip != NULL);
3523 assert(sols != NULL);
3524 assert(solssize > 0);
3525
3526 if( scip->set->reopt_enable )
3527 {
3528 assert(run > 0 && run <= scip->stat->nreoptruns);
3529 SCIP_CALL( SCIPreoptGetSolsRun(scip->reopt, run, sols, solssize, nsols) );
3530 }
3531 else
3532 {
3533 *nsols = 0;
3534 }
3535
3536 return SCIP_OKAY;
3537}
3538
3539/** mark all stored solutions as not updated */
3541 SCIP* scip /**< SCIP data structure */
3542 )
3543{
3544 assert(scip != NULL);
3545 assert(scip->set->reopt_enable);
3546 assert(scip->reopt != NULL);
3547
3548 if( scip->set->reopt_enable )
3549 {
3550 assert(scip->reopt != NULL);
3552 }
3553}
3554
3555/** check if the reoptimization process should be restarted
3556 *
3557 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3558 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3559 *
3560 * @pre This method can be called if @p scip is in one of the following stages:
3561 * - \ref SCIP_STAGE_TRANSFORMED
3562 * - \ref SCIP_STAGE_SOLVING
3563 */
3565 SCIP* scip, /**< SCIP data structure */
3566 SCIP_NODE* node, /**< current node of the branch and bound tree (or NULL) */
3567 SCIP_Bool* restart /**< pointer to store of the reoptimitation process should be restarted */
3568 )
3569{
3570 assert(scip != NULL);
3571 assert(scip->set->reopt_enable);
3572 assert(scip->reopt != NULL);
3573
3574 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckReoptRestart", FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3575
3576 SCIP_CALL( SCIPreoptCheckRestart(scip->reopt, scip->set, scip->mem->probmem, node, scip->transprob->vars,
3577 scip->transprob->nvars, restart) );
3578
3579 return SCIP_OKAY;
3580}
3581
3582/** returns whether we are in the restarting phase
3583 *
3584 * @return TRUE, if we are in the restarting phase; FALSE, otherwise
3585 *
3586 * @pre This method can be called if @p scip is in one of the following stages:
3587 * - \ref SCIP_STAGE_INITPRESOLVE
3588 * - \ref SCIP_STAGE_PRESOLVING
3589 * - \ref SCIP_STAGE_EXITPRESOLVE
3590 * - \ref SCIP_STAGE_PRESOLVED
3591 * - \ref SCIP_STAGE_INITSOLVE
3592 * - \ref SCIP_STAGE_SOLVING
3593 * - \ref SCIP_STAGE_SOLVED
3594 * - \ref SCIP_STAGE_EXITSOLVE
3595 * - \ref SCIP_STAGE_FREETRANS
3596 */
3598 SCIP* scip /**< SCIP data structure */
3599 )
3600{
3602
3603 /* return the restart status */
3604 return scip->stat->inrestart;
3605}
SCIP_RETCODE SCIPbranchcandCreate(SCIP_BRANCHCAND **branchcand)
Definition: branch.c:143
void SCIPbranchcandInvalidate(SCIP_BRANCHCAND *branchcand)
Definition: branch.c:202
SCIP_RETCODE SCIPbranchcandFree(SCIP_BRANCHCAND **branchcand)
Definition: branch.c:183
internal methods for branching rules and branching candidate storage
SCIP_VAR * h
Definition: circlepacking.c:68
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:438
internal methods for clocks and timing issues
SCIP_RETCODE SCIPcomprExec(SCIP_COMPR *compr, SCIP_SET *set, SCIP_REOPT *reopt, SCIP_RESULT *result)
Definition: compr.c:299
internal methods for tree compressions
SCIP_RETCODE SCIPconcsolverCreateInstance(SCIP_SET *set, SCIP_CONCSOLVERTYPE *concsolvertype, SCIP_CONCSOLVER **concsolver)
Definition: concsolver.c:210
SCIP_RETCODE SCIPconcsolverInitSeeds(SCIP_CONCSOLVER *concsolver, unsigned int seed)
Definition: concsolver.c:310
SCIP_Real SCIPconcsolverTypeGetPrefPrio(SCIP_CONCSOLVERTYPE *concsolvertype)
Definition: concsolver.c:200
datastructures for concurrent solvers
SCIP_RETCODE SCIPconcurrentSolve(SCIP *scip)
Definition: concurrent.c:484
SCIP_RETCODE SCIPfreeConcurrent(SCIP *scip)
Definition: concurrent.c:152
int SCIPgetNConcurrentSolvers(SCIP *scip)
Definition: concurrent.c:117
helper functions for concurrent scip solvers
internal methods for conflict analysis
SCIP_RETCODE SCIPconflictCreate(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem, SCIP_SET *set)
SCIP_RETCODE SCIPconflictFree(SCIP_CONFLICT **conflict, BMS_BLKMEM *blkmem)
SCIP_RETCODE SCIPconflictstoreClear(SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_REOPT *reopt)
SCIP_RETCODE SCIPconflictstoreClean(SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_REOPT *reopt)
internal methods for storing conflicts
SCIP_RETCODE SCIPconsGetNVars(SCIP_CONS *cons, SCIP_SET *set, int *nvars, SCIP_Bool *success)
Definition: cons.c:6381
SCIP_RETCODE SCIPconshdlrPresolve(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRESOLTIMING timing, int nrounds, int *nfixedvars, int *naggrvars, int *nchgvartypes, int *nchgbds, int *naddholes, int *ndelconss, int *naddconss, int *nupgdconss, int *nchgcoefs, int *nchgsides, SCIP_RESULT *result)
Definition: cons.c:3993
internal methods for constraints and constraint handlers
void SCIPcutpoolAddNCutsFound(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsfound)
Definition: cutpool.c:1204
void SCIPcutpoolSetTime(SCIP_CUTPOOL *cutpool, SCIP_Real time)
Definition: cutpool.c:1168
SCIP_RETCODE SCIPcutpoolCreate(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, int agelimit, SCIP_Bool globalcutpool)
Definition: cutpool.c:427
SCIP_RETCODE SCIPcutpoolFree(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:468
void SCIPcutpoolAddNCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint ncalls)
Definition: cutpool.c:1180
void SCIPcutpoolAddMaxNCuts(SCIP_CUTPOOL *cutpool, SCIP_Longint ncuts)
Definition: cutpool.c:1156
void SCIPcutpoolAddNCutsAdded(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsadded)
Definition: cutpool.c:1216
void SCIPcutpoolAddNRootCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint nrootcalls)
Definition: cutpool.c:1192
SCIP_RETCODE SCIPcutpoolClear(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:494
internal methods for storing cuts in a cut pool
void SCIPexitSolveDecompstore(SCIP *scip)
Definition: dcmp.c:543
int SCIPdecompstoreGetNOrigDecomps(SCIP_DECOMPSTORE *decompstore)
Definition: dcmp.c:640
SCIP_RETCODE SCIPtransformDecompstore(SCIP *scip)
Definition: dcmp.c:649
internal methods for decompositions and the decomposition store
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition: debug.c:2208
methods for debugging
#define SCIPdebugFreeSol(set)
Definition: debug.h:279
#define SCIPdebugReset(set)
Definition: debug.h:280
#define NULL
Definition: def.h:266
#define SCIP_MAXSTRLEN
Definition: def.h:287
#define SCIP_Longint
Definition: def.h:157
#define SCIP_MEM_NOLIMIT
Definition: def.h:309
#define SCIP_REAL_MAX
Definition: def.h:173
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:242
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:238
#define SCIP_CALL_ABORT(x)
Definition: def.h:352
#define SCIP_LONGINT_FORMAT
Definition: def.h:164
#define SCIPABORT()
Definition: def.h:345
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:373
SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2200
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1846
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1821
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1574
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:1040
SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2184
internal methods for managing events
SCIP_RETCODE SCIPprintStage(SCIP *scip, FILE *file)
Definition: scip_general.c:412
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip_general.c:643
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:508
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:390
SCIP_RETCODE SCIPpermuteProb(SCIP *scip, unsigned int randseed, SCIP_Bool permuteconss, SCIP_Bool permutebinvars, SCIP_Bool permuteintvars, SCIP_Bool permuteimplvars, SCIP_Bool permutecontvars)
Definition: scip_prob.c:781
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2082
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition: scip_prob.c:1422
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3043
int SCIPgetNFixedVars(SCIP *scip)
Definition: scip_prob.c:2309
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2037
SCIP_VAR ** SCIPgetFixedVars(SCIP *scip)
Definition: scip_prob.c:2266
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_Real SCIPnextafter(SCIP_Real from, SCIP_Real to)
Definition: misc.c:9367
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:487
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:307
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip_param.c:603
int SCIPgetNActiveBenders(SCIP *scip)
Definition: scip_benders.c:532
SCIP_RETCODE SCIPapplyBendersDecomposition(SCIP *scip, int decompindex)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:297
SCIP_Longint SCIPbranchruleGetNChildren(SCIP_BRANCHRULE *branchrule)
Definition: branch.c:2163
const char * SCIPcomprGetName(SCIP_COMPR *compr)
Definition: compr.c:456
SCIP_CONCSOLVERTYPE ** SCIPgetConcsolverTypes(SCIP *scip)
int SCIPgetNConcsolverTypes(SCIP *scip)
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4656
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4613
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4670
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4593
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8413
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8275
SCIP_Longint SCIPcutpoolGetNRootCalls(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1125
SCIP_Longint SCIPcutpoolGetNCutsFound(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1135
SCIP_Real SCIPcutpoolGetTime(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1105
SCIP_Longint SCIPcutpoolGetMaxNCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1095
SCIP_Longint SCIPcutpoolGetNCalls(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1115
SCIP_Longint SCIPcutpoolGetNCutsAdded(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1145
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1453
SCIP_RETCODE SCIPinterruptLP(SCIP *scip, SCIP_Bool interrupt)
Definition: scip_lp.c:874
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition: scip_mem.c:126
BMS_BUFMEM * SCIPcleanbuffer(SCIP *scip)
Definition: scip_mem.c:86
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition: scip_mem.c:100
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition: scip_mem.c:72
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
int SCIPpresolGetPriority(SCIP_PRESOL *presol)
Definition: presol.c:619
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:599
int SCIPpropGetPresolPriority(SCIP_PROP *prop)
Definition: prop.c:971
const char * SCIPpropGetName(SCIP_PROP *prop)
Definition: prop.c:941
SCIP_SOL * SCIPgetReoptLastOptSol(SCIP *scip)
Definition: scip_solve.c:3137
void SCIPresetReoptSolMarks(SCIP *scip)
Definition: scip_solve.c:3540
SCIP_RETCODE SCIPgetReoptOldObjCoef(SCIP *scip, SCIP_VAR *var, int run, SCIP_Real *objcoef)
Definition: scip_solve.c:3164
SCIP_RETCODE SCIPcheckReoptRestart(SCIP *scip, SCIP_NODE *node, SCIP_Bool *restart)
Definition: scip_solve.c:3564
SCIP_RETCODE SCIPaddReoptDualBndchg(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound, SCIP_Real oldbound)
Definition: scip_solve.c:3119
SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
Definition: scip_solve.c:3504
SCIP_RETCODE SCIPenableReoptimization(SCIP *scip, SCIP_Bool enable)
Definition: scip_solve.c:3049
SCIP_RETCODE SCIPgetReoptSolsRun(SCIP *scip, int run, SCIP_SOL **sols, int solssize, int *nsols)
Definition: scip_solve.c:3514
SCIP_RETCODE SCIPfreeReoptSolve(SCIP *scip)
Definition: scip_solve.c:3287
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
Definition: scip_sol.c:3305
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2165
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:180
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2784
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2066
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2804
SCIP_RETCODE SCIPcreateFiniteSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol, SCIP_Bool *success)
Definition: scip_sol.c:701
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2721
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip_sol.c:2115
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:3046
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1296
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition: scip_solve.c:223
SCIP_RETCODE SCIPrestartSolve(SCIP *scip)
Definition: scip_solve.c:3491
SCIP_RETCODE SCIPsolveParallel(SCIP *scip)
Definition: scip_solve.c:2834
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip_solve.c:2332
SCIP_RETCODE SCIPsolveConcurrent(SCIP *scip)
Definition: scip_solve.c:2864
SCIP_Bool SCIPisSolveInterrupted(SCIP *scip)
Definition: scip_solve.c:3468
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
Definition: scip_solve.c:3350
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
Definition: scip_solve.c:3436
SCIP_RETCODE SCIPfreeSolve(SCIP *scip, SCIP_Bool restart)
Definition: scip_solve.c:3220
SCIP_Bool SCIPisInRestart(SCIP *scip)
Definition: scip_solve.c:3597
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2502
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Real SCIPgetGap(SCIP *scip)
SCIP_Real SCIPgetDualbound(SCIP *scip)
void SCIPstoreSolutionGap(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip_timing.c:378
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPchgFeastol(SCIP *scip, SCIP_Real feastol)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPgetChildren(SCIP *scip, SCIP_NODE ***children, int *nchildren)
Definition: scip_tree.c:164
int SCIPgetNNodesLeft(SCIP *scip)
Definition: scip_tree.c:646
SCIP_RETCODE SCIPgetLeaves(SCIP *scip, SCIP_NODE ***leaves, int *nleaves)
Definition: scip_tree.c:248
SCIP_RETCODE SCIPgetSiblings(SCIP *scip, SCIP_NODE ***siblings, int *nsiblings)
Definition: scip_tree.c:206
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12773
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17747
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17537
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17925
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17757
SCIP_Real SCIPvarGetWorstBoundGlobal(SCIP_VAR *var)
Definition: var.c:18120
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1693
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17857
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17845
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:17547
SCIP_RETCODE SCIPclearRelaxSolVals(SCIP *scip, SCIP_RELAX *relax)
Definition: scip_var.c:2364
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
Definition: misc.c:10111
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
void SCIPselectDownRealInt(SCIP_Real *realarray, int *intarray, int k, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10880
SCIP_RETCODE SCIPcliquetableFree(SCIP_CLIQUETABLE **cliquetable, BMS_BLKMEM *blkmem)
Definition: implics.c:1822
SCIP_RETCODE SCIPcliquetableCreate(SCIP_CLIQUETABLE **cliquetable, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: implics.c:1786
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3506
SCIP_RETCODE SCIPcliquetableCleanup(SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, int *nchgbds, SCIP_Bool *infeasible)
Definition: implics.c:2920
methods for implications, variable bounds, and cliques
void SCIPinterruptRelease(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:144
void SCIPinterruptCapture(SCIP_INTERRUPT *interrupt)
Definition: interrupt.c:114
methods for catching the user CTRL-C interrupt
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13202
SCIP_RETCODE SCIPlpFree(SCIP_LP **lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9370
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9078
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9415
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13191
internal methods for LP management
size_t BMSgetNUsedBufferMemory(BMS_BUFMEM *buffer)
Definition: memory.c:3129
memory allocation routines
#define BMSgarbagecollectBlockMemory(mem)
Definition: memory.h:472
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:594
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:678
SCIP_RETCODE SCIPnlpFree(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: nlp.c:3664
SCIP_RETCODE SCIPnlpAddVars(SCIP_NLP *nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, int nvars, SCIP_VAR **vars)
Definition: nlp.c:3835
SCIP_RETCODE SCIPnlpCreate(SCIP_NLP **nlp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int nvars_estimate)
Definition: nlp.c:3540
internal methods for NLP management
SCIP_RETCODE SCIPpresolExec(SCIP_PRESOL *presol, SCIP_SET *set, SCIP_PRESOLTIMING timing, int nrounds, int *nfixedvars, int *naggrvars, int *nchgvartypes, int *nchgbds, int *naddholes, int *ndelconss, int *naddconss, int *nupgdconss, int *nchgcoefs, int *nchgsides, SCIP_RESULT *result)
Definition: presol.c:388
internal methods for presolvers
SCIP_RETCODE SCIPpricestoreCreate(SCIP_PRICESTORE **pricestore)
Definition: pricestore.c:107
SCIP_RETCODE SCIPpricestoreFree(SCIP_PRICESTORE **pricestore)
Definition: pricestore.c:136
internal methods for storing priced variables
SCIP_RETCODE SCIPprimalClear(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:203
SCIP_RETCODE SCIPprimalFree(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:160
SCIP_RETCODE SCIPprimalAddOrigSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1336
SCIP_RETCODE SCIPprimalCreate(SCIP_PRIMAL **primal)
Definition: primal.c:130
SCIP_RETCODE SCIPprimalTransformSol(SCIP_PRIMAL *primal, SCIP_SOL *sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real *solvals, SCIP_Bool *solvalset, int solvalssize, SCIP_Bool *added)
Definition: primal.c:1808
SCIP_RETCODE SCIPprimalUpdateObjlimit(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:448
SCIP_RETCODE SCIPprimalAddSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1213
SCIP_RETCODE SCIPprimalSetCutoffbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound, SCIP_Bool useforobjlimit)
Definition: primal.c:307
SCIP_RETCODE SCIPprimalRetransformSolutions(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:1759
internal methods for collecting primal CIP solutions and primal informations
SCIP_RETCODE SCIPprobScaleObj(SCIP_PROB *transprob, SCIP_PROB *origprob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue)
Definition: prob.c:1646
SCIP_RETCODE SCIPprobExitPresolve(SCIP_PROB *prob, SCIP_SET *set)
Definition: prob.c:1903
void SCIPprobInvalidateDualbound(SCIP_PROB *prob)
Definition: prob.c:1636
const char * SCIPprobGetName(SCIP_PROB *prob)
Definition: prob.c:2384
SCIP_RETCODE SCIPprobPerformVarDeletions(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand)
Definition: prob.c:1104
void SCIPprobUpdateDualbound(SCIP_PROB *prob, SCIP_Real newbound)
Definition: prob.c:1609
SCIP_RETCODE SCIPprobInitSolve(SCIP_PROB *prob, SCIP_SET *set)
Definition: prob.c:1912
void SCIPprobMarkNConss(SCIP_PROB *prob)
Definition: prob.c:1455
SCIP_RETCODE SCIPprobTransform(SCIP_PROB *source, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CONFLICTSTORE *conflictstore, SCIP_PROB **target)
Definition: prob.c:536
SCIP_RETCODE SCIPprobCheckObjIntegral(SCIP_PROB *transprob, SCIP_PROB *origprob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue)
Definition: prob.c:1528
SCIP_RETCODE SCIPprobExitSolve(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Bool restart)
Definition: prob.c:1947
SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
Definition: prob.c:2338
void SCIPprobResortVars(SCIP_PROB *prob)
Definition: prob.c:663
SCIP_RETCODE SCIPprobFree(SCIP_PROB **prob, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: prob.c:417
SCIP_RETCODE SCIPprobResetBounds(SCIP_PROB *prob, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: prob.c:637
SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2179
internal methods for storing and manipulating the main problem
SCIP_RETCODE SCIPpropPresol(SCIP_PROP *prop, SCIP_SET *set, SCIP_PRESOLTIMING timing, int nrounds, int *nfixedvars, int *naggrvars, int *nchgvartypes, int *nchgbds, int *naddholes, int *ndelconss, int *naddconss, int *nupgdconss, int *nchgcoefs, int *nchgsides, SCIP_RESULT *result)
Definition: prop.c:519
internal methods for propagators
public methods for branching rules
public methods for tree compressions
public methods for managing constraints
public methods for primal heuristics
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebug(x)
Definition: pub_message.h:93
public data structures and miscellaneous methods
methods for selecting (weighted) k-medians
public methods for presolvers
public methods for propagators
public methods for primal CIP solutions
public methods for problem variables
SCIP_RETCODE SCIPrelaxationFree(SCIP_RELAXATION **relaxation)
Definition: relax.c:762
SCIP_RETCODE SCIPrelaxationCreate(SCIP_RELAXATION **relaxation, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree)
Definition: relax.c:734
internal methods for relaxators
SCIP_RETCODE SCIPreoptUpdateVarHistory(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem, SCIP_VAR **vars, int nvars)
Definition: reopt.c:6623
SCIP_RETCODE SCIPreoptSaveActiveConss(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_PROB *transprob, BMS_BLKMEM *blkmem)
Definition: reopt.c:8180
SCIP_RETCODE SCIPreoptAddRun(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **origvars, int norigvars, int size)
Definition: reopt.c:5389
SCIP_RETCODE SCIPreoptAddSol(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *origprimal, BMS_BLKMEM *blkmem, SCIP_SOL *sol, SCIP_Bool bestsol, SCIP_Bool *added, SCIP_VAR **vars, int nvars, int run)
Definition: reopt.c:5301
SCIP_SOL * SCIPreoptGetLastBestSol(SCIP_REOPT *reopt)
Definition: reopt.c:5670
SCIP_RETCODE SCIPreoptGetSolsRun(SCIP_REOPT *reopt, int run, SCIP_SOL **sols, int solssize, int *nsols)
Definition: reopt.c:5497
SCIP_RETCODE SCIPreoptReleaseData(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: reopt.c:5124
void SCIPreoptResetSolMarks(SCIP_REOPT *reopt)
Definition: reopt.c:5760
SCIP_Real SCIPreoptGetOldObjCoef(SCIP_REOPT *reopt, int run, int idx)
Definition: reopt.c:5698
SCIP_RETCODE SCIPreoptFree(SCIP_REOPT **reopt, SCIP_SET *set, SCIP_PRIMAL *origprimal, BMS_BLKMEM *blkmem)
Definition: reopt.c:5151
SCIP_RETCODE SCIPreoptAddOptSol(SCIP_REOPT *reopt, SCIP_SOL *sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *origprimal, SCIP_VAR **vars, int nvars)
Definition: reopt.c:5354
int SCIPreoptGetNNodes(SCIP_REOPT *reopt, SCIP_NODE *node)
Definition: reopt.c:5781
SCIP_RETCODE SCIPreoptResetActiveConss(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat)
Definition: reopt.c:8269
SCIP_RETCODE SCIPreoptCreate(SCIP_REOPT **reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: reopt.c:5043
SCIP_RETCODE SCIPreoptAddDualBndchg(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newval, SCIP_Real oldval)
Definition: reopt.c:6257
SCIP_RETCODE SCIPreoptMergeVarHistory(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **vars, int nvars)
Definition: reopt.c:6531
SCIP_RETCODE SCIPreoptSaveGlobalBounds(SCIP_REOPT *reopt, SCIP_PROB *transprob, BMS_BLKMEM *blkmem)
Definition: reopt.c:8143
SCIP_RETCODE SCIPreoptCheckRestart(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_NODE *node, SCIP_VAR **transvars, int ntransvars, SCIP_Bool *restart)
Definition: reopt.c:5564
SCIP_RETCODE SCIPreoptInstallBounds(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, BMS_BLKMEM *blkmem)
Definition: reopt.c:8220
SCIP_RETCODE SCIPreoptApplyGlbConss(SCIP *scip, SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: reopt.c:7608
SCIP_RETCODE SCIPreoptReset(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: reopt.c:5726
SCIP_RETCODE SCIPreoptSaveOpenNodes(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_NODE **leaves, int nleaves, SCIP_NODE **childs, int nchilds, SCIP_NODE **siblings, int nsiblings)
Definition: reopt.c:6481
data structures and methods for collecting reoptimization information
public methods for Benders decomposition
public methods for branching rule plugins and branching
public methods for concurrent solving mode
public methods for constraint handler plugins and constraints
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for random numbers
public methods for solutions
static SCIP_RETCODE prepareReoptimization(SCIP *scip)
Definition: scip_solve.c:2228
static SCIP_RETCODE freeTransforming(SCIP *scip)
Definition: scip_solve.c:2003
static SCIP_RETCODE freeReoptSolve(SCIP *scip)
Definition: scip_solve.c:1720
static SCIP_RETCODE displayRelevantStats(SCIP *scip)
Definition: scip_solve.c:2050
static SCIP_RETCODE initSolve(SCIP *scip, SCIP_Bool solved)
Definition: scip_solve.c:1476
static SCIP_RETCODE exitPresolve(SCIP *scip, SCIP_Bool solved, SCIP_Bool *infeasible)
Definition: scip_solve.c:511
static SCIP_RETCODE freeTransform(SCIP *scip)
Definition: scip_solve.c:1836
static SCIP_RETCODE calcNonZeros(SCIP *scip, SCIP_Longint *nchecknonzeros, SCIP_Longint *nactivenonzeros, SCIP_Bool *approxchecknonzeros, SCIP_Bool *approxactivenonzeros)
Definition: scip_solve.c:119
static SCIP_RETCODE initPresolve(SCIP *scip)
Definition: scip_solve.c:436
static SCIP_RETCODE freeSolve(SCIP *scip, SCIP_Bool restart)
Definition: scip_solve.c:1617
static SCIP_RETCODE compressReoptTree(SCIP *scip)
Definition: scip_solve.c:2169
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
Definition: scip_solve.c:1114
static SCIP_RETCODE transformSols(SCIP *scip)
Definition: scip_solve.c:1401
static SCIP_RETCODE presolveRound(SCIP *scip, SCIP_PRESOLTIMING *timing, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool lastround, int *presolstart, int presolend, int *propstart, int propend, int *consstart, int consend)
Definition: scip_solve.c:656
public solving methods
public methods for querying solving statistics
public methods for timing
public methods for the branch-and-bound tree
public methods for SCIP variables
SCIP_RETCODE SCIPsepastoreCreate(SCIP_SEPASTORE **sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: sepastore.c:87
SCIP_RETCODE SCIPsepastoreFree(SCIP_SEPASTORE **sepastore, BMS_BLKMEM *blkmem)
Definition: sepastore.c:115
internal methods for storing separated cuts
void SCIPsetSortPresols(SCIP_SET *set)
Definition: set.c:4122
SCIP_RETCODE SCIPsetInitsolPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition: set.c:5554
SCIP_RETCODE SCIPsetInitPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition: set.c:5245
SCIP_RETCODE SCIPsetSetReoptimizationParams(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: set.c:737
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6663
void SCIPsetSortPropsPresol(SCIP_SET *set)
Definition: set.c:4420
void SCIPsetSortComprs(SCIP_SET *set)
Definition: set.c:4699
SCIP_RETCODE SCIPsetExitprePlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition: set.c:5516
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6619
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6064
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6239
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6199
SCIP_RETCODE SCIPsetExitsolPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_Bool restart)
Definition: set.c:5663
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6311
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition: set.c:6164
SCIP_RETCODE SCIPsetExitPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition: set.c:5366
SCIP_RETCODE SCIPsetInitprePlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition: set.c:5478
SCIP_NODESEL * SCIPsetGetNodesel(SCIP_SET *set, SCIP_STAT *stat)
Definition: set.c:4823
internal methods for global SCIP settings
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:801
void SCIPsolRecomputeObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob)
Definition: sol.c:2186
SCIP_RETCODE SCIPsolRetransform(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_Bool *hasinfval)
Definition: sol.c:2059
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1571
SCIP_RETCODE SCIPsolPrint(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PROB *transprob, FILE *file, SCIP_Bool mipstart, SCIP_Bool printzeros)
Definition: sol.c:2286
SCIP_RETCODE SCIPsolCheckOrig(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool checkmodifiable, SCIP_Bool *feasible)
Definition: sol.c:1671
internal methods for storing primal CIP solutions
SCIP_RETCODE SCIPsolveCIP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *restart)
Definition: solve.c:4947
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:102
SCIP_RETCODE SCIPprimalHeuristics(SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_NODE *nextnode, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible, SCIP_Bool *foundsol, SCIP_Bool *unbounded)
Definition: solve.c:218
internal methods for main solving loop and node processing
void SCIPstatUpdatePrimalDualIntegrals(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_Real upperbound, SCIP_Real lowerbound)
Definition: stat.c:459
void SCIPstatMark(SCIP_STAT *stat)
Definition: stat.c:176
void SCIPstatResetDisplay(SCIP_STAT *stat)
Definition: stat.c:676
void SCIPstatResetPrimalDualIntegrals(SCIP_STAT *stat, SCIP_SET *set, SCIP_Bool partialreset)
Definition: stat.c:391
void SCIPstatResetPresolving(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: stat.c:363
void SCIPstatReset(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: stat.c:188
void SCIPstatEnforceLPUpdates(SCIP_STAT *stat)
Definition: stat.c:687
void SCIPstatResetCurrentRun(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_Bool solved)
Definition: stat.c:615
internal methods for problem statistics
datastructures for managing events
datastructures for block memory pools and memory buffers
datastructures for collecting primal CIP solutions and primal informations
datastructures for storing and manipulating the main problem
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
data structures for branch and bound tree
Definition: heur_padm.c:135
void SCIPsyncstoreSetSolveIsStopped(SCIP_SYNCSTORE *syncstore, SCIP_Bool stopped)
Definition: syncstore.c:259
SCIP_RETCODE SCIPsyncstoreInit(SCIP *scip)
Definition: syncstore.c:138
the function declarations for the synchronization store
the type definitions for the SCIP parallel interface
SCIP_Bool SCIPtpiIsAvailable(void)
Definition: tpi_none.c:225
SCIP_NODE * SCIPtreeGetFocusNode(SCIP_TREE *tree)
Definition: tree.c:8410
SCIP_RETCODE SCIPtreeFree(SCIP_TREE **tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: tree.c:4944
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8485
SCIP_RETCODE SCIPtreeCreatePresolvingRoot(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:5100
int SCIPtreeGetNNodes(SCIP_TREE *tree)
Definition: tree.c:8357
SCIP_RETCODE SCIPtreeClear(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: tree.c:4993
SCIP_RETCODE SCIPnodeFocus(SCIP_NODE **node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff, SCIP_Bool postponed, SCIP_Bool exitsolve)
Definition: tree.c:4408
SCIP_RETCODE SCIPtreeCreate(SCIP_TREE **tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_NODESEL *nodesel)
Definition: tree.c:4863
SCIP_RETCODE SCIPtreeCreateRoot(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: tree.c:5054
SCIP_RETCODE SCIPtreeFreePresolvingRoot(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTFILTER *eventfilter, SCIP_EVENTQUEUE *eventqueue, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:5141
internal methods for branch and bound tree
@ SCIP_CLOCKTYPE_WALL
Definition: type_clock.h:45
#define SCIP_EVENTTYPE_PRESOLVEROUND
Definition: type_event.h:89
@ SCIP_VERBLEVEL_HIGH
Definition: type_message.h:56
@ SCIP_VERBLEVEL_NORMAL
Definition: type_message.h:55
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:57
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_CUTOFF
Definition: type_result.h:48
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_UNBOUNDED
Definition: type_result.h:47
@ SCIP_SUCCESS
Definition: type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition: type_set.h:48
@ SCIP_STAGE_SOLVED
Definition: type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition: type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition: type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition: type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition: type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition: type_set.h:55
@ SCIP_STAGE_INIT
Definition: type_set.h:44
@ SCIP_STAGE_FREETRANS
Definition: type_set.h:56
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition: type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_STATUS_OPTIMAL
Definition: type_stat.h:61
@ SCIP_STATUS_UNBOUNDED
Definition: type_stat.h:63
@ SCIP_STATUS_UNKNOWN
Definition: type_stat.h:42
@ SCIP_STATUS_INFORUNBD
Definition: type_stat.h:64
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:62
@ SCIP_STATUS_MEMLIMIT
Definition: type_stat.h:52
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:90
#define SCIP_PRESOLTIMING_FINAL
Definition: type_timing.h:55
#define SCIP_PRESOLTIMING_MEDIUM
Definition: type_timing.h:53
unsigned int SCIP_PRESOLTIMING
Definition: type_timing.h:61
#define SCIP_HEURTIMING_DURINGPRESOLLOOP
Definition: type_timing.h:91
#define SCIP_PRESOLTIMING_FAST
Definition: type_timing.h:52
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:54
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
SCIP_RETCODE SCIPvarFlattenAggregationGraph(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: var.c:4424
internal methods for problem variables
SCIP_RETCODE SCIPvisualInit(SCIP_VISUAL *visual, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: visual.c:120
void SCIPvisualExit(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: visual.c:189
methods for creating output for visualization tools (VBC, BAK)