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