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 usesymmetry;
2946 int i;
2947
2948 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveConcurrent", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2949
2950 if( !SCIPtpiIsAvailable() )
2951 {
2952 SCIPerrorMessage("SCIP was compiled without task processing interface. Concurrent solve not possible.\n");
2953 return SCIP_PLUGINNOTFOUND;
2954 }
2955
2956 /* as long as no exact copy functionality is available, concurrent solving is not possible */
2957 if( SCIPisExact(scip) )
2958 {
2959 SCIPerrorMessage("Concurrent solve not implemented for exact solving mode.\n");
2960 return SCIP_NOTIMPLEMENTED;
2961 }
2962
2963 /* concurrent solvers do not support reoptimization */
2964 if( scip->set->reopt_enable )
2965 {
2966 SCIPerrorMessage("Concurrent solve not implemented for reoptimization mode.\n");
2967 return SCIP_NOTIMPLEMENTED;
2968 }
2969
2970 SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", (int)SCIP_CLOCKTYPE_WALL) );
2971
2972 minnthreads = scip->set->parallel_minnthreads;
2973 maxnthreads = scip->set->parallel_maxnthreads;
2974
2975 if( minnthreads > maxnthreads )
2976 {
2977 SCIPerrorMessage("minimum number of threads greater than maximum number of threads\n");
2978 return SCIP_INVALIDDATA;
2979 }
2980
2981 /* capture the CTRL-C interrupt */
2982 if( scip->set->misc_catchctrlc )
2983 SCIPinterruptCapture(scip->interrupt);
2984
2985 if( scip->concurrent == NULL )
2986 {
2987 SCIP_CONCSOLVERTYPE** concsolvertypes;
2988 SCIP_Longint* weights;
2989 SCIP_Real* prios;
2990 SCIP_Real memorylimit;
2991 SCIP_Real prefpriosum;
2992 int* solvertypes;
2993 int nconcsolvertypes;
2994 int ncandsolvertypes;
2995 int nthreads = INT_MAX;
2996
2997 /* temporarily disable symmetry if symmetrybefore is FALSE */
2998 if( scip->set->concurrent_symmetrybefore )
2999 usesymmetry = -1;
3000 else
3001 {
3002 usesymmetry = scip->set->misc_usesymmetry;
3003 scip->set->misc_usesymmetry = 0;
3004 }
3005
3006 /* check whether concurrent solve is configured to presolve the problem before setting up the concurrent solvers */
3007 if( scip->set->concurrent_presolvebefore )
3008 {
3009 /* if yes, then presolve the problem */
3012 {
3013 retcode = SCIP_OKAY;
3014 goto TERMINATE;
3015 }
3016 }
3017 else
3018 {
3019 SCIP_Bool infeas;
3020
3021 /* if not, transform the problem and switch stage to presolved */
3023
3025 SCIP_CALL( exitPresolve(scip, TRUE, &infeas) );
3026 assert(!infeas);
3027 }
3028
3029 /* restore symmetry setting for concurrent solvers */
3030 if( usesymmetry >= 0 )
3031 scip->set->misc_usesymmetry = usesymmetry;
3032
3033 /* if presolving has run into a limit, we stop here */
3034 if( scip->set->stage < SCIP_STAGE_PRESOLVED )
3035 {
3037 retcode = SCIP_OKAY;
3038 goto TERMINATE;
3039 }
3040
3041 /* estimate memory */
3042 memorylimit = scip->set->limit_memory;
3043 if( memorylimit < SCIP_MEM_NOLIMIT )
3044 {
3045 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
3046 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
3047 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
3048
3049 /* estimate maximum number of copies that be created based on memory limit */
3050 if( !scip->set->misc_avoidmemout )
3051 {
3052 nthreads = MAX(1, memorylimit / (4.0*SCIPgetMemExternEstim(scip)/1048576.0)); /*lint !e666 !e524*/
3053 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "Estimated a maximum of %d threads based on memory limit.\n", nthreads);
3054 }
3055 else
3056 {
3057 nthreads = minnthreads;
3058 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "Ignoring memory limit; all threads can be created.\n");
3059 }
3060 }
3061 nconcsolvertypes = SCIPgetNConcsolverTypes(scip);
3062 concsolvertypes = SCIPgetConcsolverTypes(scip);
3063
3064 if( minnthreads > nthreads )
3065 {
3067 scip->stat->status = SCIP_STATUS_MEMLIMIT;
3069 SCIPwarningMessage(scip, "Requested minimum number of threads could not be satisfied with given memory limit.\n");
3071 retcode = SCIP_OKAY;
3072 goto TERMINATE;
3073 }
3074
3075 if( nthreads == 1 )
3076 {
3077 SCIPwarningMessage(scip, "Can only use 1 thread, performing sequential solve instead.\n");
3079 retcode = SCIPsolve(scip);
3080 goto TERMINATE;
3081 }
3082 nthreads = MIN(nthreads, maxnthreads);
3083 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Using %d threads for concurrent solve.\n", nthreads);
3084
3085 /* now set up nthreads many concurrent solvers that will be used for the concurrent solve
3086 * using the preferred priorities of each concurrent solver
3087 */
3088 prefpriosum = 0.0;
3089 for( i = 0; i < nconcsolvertypes; ++i )
3090 prefpriosum += SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]);
3091 assert(prefpriosum != 0.0);
3092
3093 ncandsolvertypes = 0;
3094 SCIP_CALL( SCIPallocBufferArray(scip, &solvertypes, nthreads + nconcsolvertypes) );
3095 SCIP_CALL( SCIPallocBufferArray(scip, &weights, nthreads + nconcsolvertypes) );
3096 SCIP_CALL( SCIPallocBufferArray(scip, &prios, nthreads + nconcsolvertypes) );
3097 for( i = 0; i < nconcsolvertypes; ++i )
3098 {
3099 SCIP_Real prio;
3100 int j;
3101
3102 prio = nthreads * SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]) / prefpriosum;
3103 while( prio > 0.0 )
3104 {
3105 j = ncandsolvertypes++;
3106 assert(j < 2*nthreads);
3107 weights[j] = 1;
3108 solvertypes[j] = i;
3109 prios[j] = MIN(1.0, prio);
3110 prio = prio - 1.0;
3111 }
3112 }
3113
3114 /* Select nthreads many concurrent solver types to create instances according to the preferred priorities the user
3115 * has set. This basically corresponds to a knapsack problem with unit weights and capacity nthreads, where the
3116 * profits are the unrounded fraction of the total number of threads to be used.
3117 */
3118 SCIPselectDownRealInt(prios, solvertypes, nthreads, ncandsolvertypes);
3119
3120 SCIP_CALL( SCIPcreateRandom(scip, &rndgen, (unsigned) scip->set->concurrent_initseed, TRUE) );
3121 for( i = 0; i < nthreads; ++i )
3122 {
3123 SCIP_CONCSOLVER* concsolver;
3124
3125 SCIP_CALL( SCIPconcsolverCreateInstance(scip->set, concsolvertypes[solvertypes[i]], &concsolver) );
3126 if( scip->set->concurrent_changeseeds && SCIPgetNConcurrentSolvers(scip) > 1 )
3127 SCIP_CALL( SCIPconcsolverInitSeeds(concsolver, (unsigned int)SCIPrandomGetInt(rndgen, 0, INT_MAX)) );
3128 }
3129 SCIPfreeRandom(scip, &rndgen);
3130 SCIPfreeBufferArray(scip, &prios);
3131 SCIPfreeBufferArray(scip, &weights);
3132 SCIPfreeBufferArray(scip, &solvertypes);
3133
3135
3137 }
3138
3140 {
3141 /* switch stage to solving */
3143 }
3144
3145 SCIPclockStart(scip->stat->solvingtime, scip->set);
3146 retcode = SCIPconcurrentSolve(scip);
3147 SCIPclockStop(scip->stat->solvingtime, scip->set);
3149
3150TERMINATE:
3151 /* release the CTRL-C interrupt */
3152 if( scip->set->misc_catchctrlc )
3153 SCIPinterruptRelease(scip->interrupt);
3154
3155 return retcode;
3156}
3157
3158/** include specific heuristics and branching rules for reoptimization
3159 *
3160 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3161 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3162 *
3163 * @pre This method can be called if @p scip is in one of the following stages:
3164 * - \ref SCIP_STAGE_PROBLEM
3165 */
3167 SCIP* scip, /**< SCIP data structure */
3168 SCIP_Bool enable /**< enable reoptimization (TRUE) or disable it (FALSE) */
3169 )
3170{
3171 assert(scip != NULL);
3172
3173 /* we want to skip if nothing has changed */
3174 if( (enable && scip->set->reopt_enable && scip->reopt != NULL)
3175 || (!enable && !scip->set->reopt_enable && scip->reopt == NULL) )
3176 return SCIP_OKAY;
3177
3178 /* check stage and throw an error if we try to disable reoptimization during the solving process.
3179 *
3180 * @note the case that we will disable the reoptimization and have already performed presolving can only happen if
3181 * we are try to solve a general MIP
3182 *
3183 * @note this fix is only for the bugfix release 3.2.1, in the next major release reoptimization can be used for
3184 * general MIPs, too.
3185 */
3186 if( scip->set->stage > SCIP_STAGE_PROBLEM && !(!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3187 {
3188 SCIPerrorMessage("Reoptimization cannot be %s after starting the (pre)solving process.\n", enable ? "enabled" : "disabled");
3189 return SCIP_INVALIDCALL;
3190 }
3191
3192 /* reoptimization in combination with exact solving has not been implemented */
3193 if( scip->set->exact_enable )
3194 {
3195 SCIPerrorMessage("Reoptimization cannot (yet) be started in exact solving mode.\n");
3196 return SCIP_INVALIDCALL;
3197 }
3198
3199 /* if the current stage is SCIP_STAGE_PROBLEM we have to include the heuristics and branching rule */
3200 if( scip->set->stage == SCIP_STAGE_PROBLEM || (!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3201 {
3202 /* initialize all reoptimization data structures */
3203 if( enable && scip->reopt == NULL )
3204 {
3205 /* set enable flag */
3206 scip->set->reopt_enable = enable;
3207
3208 SCIP_CALL( SCIPreoptCreate(&scip->reopt, scip->set, scip->mem->probmem) );
3209 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3210 }
3211 /* disable all reoptimization plugins and free the structure if necessary */
3212 else if( (!enable && scip->reopt != NULL) || (!enable && scip->set->reopt_enable && scip->reopt == NULL) )
3213 {
3214 /* set enable flag */
3215 scip->set->reopt_enable = enable;
3216
3217 if( scip->reopt != NULL )
3218 {
3219 SCIP_CALL( SCIPreoptFree(&(scip->reopt), scip->set, scip->origprimal, scip->mem->probmem) );
3220 assert(scip->reopt == NULL);
3221 }
3222 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3223 }
3224 }
3225 else
3226 {
3227 /* set enable flag */
3228 scip->set->reopt_enable = enable;
3229 }
3230
3231 return SCIP_OKAY;
3232}
3233
3234/** save bound change based on dual information in the reoptimization tree
3235 *
3236 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3237 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3238 *
3239 * @pre This method can be called if @p scip is in one of the following stages:
3240 * - \ref SCIP_STAGE_SOLVING
3241 * - \ref SCIP_STAGE_SOLVED
3242 */
3244 SCIP* scip, /**< SCIP data structure */
3245 SCIP_NODE* node, /**< node of the search tree */
3246 SCIP_VAR* var, /**< variable whose bound changed */
3247 SCIP_Real newbound, /**< new bound of the variable */
3248 SCIP_Real oldbound /**< old bound of the variable */
3249 )
3250{
3251 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddReoptDualBndchg", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3252
3253 assert(SCIPsetIsFeasLT(scip->set, newbound, oldbound) || SCIPsetIsFeasGT(scip->set, newbound, oldbound));
3254
3255 SCIP_CALL( SCIPreoptAddDualBndchg(scip->reopt, scip->set, scip->mem->probmem, node, var, newbound, oldbound) );
3256
3257 return SCIP_OKAY;
3258}
3259
3260/** returns the optimal solution of the last iteration or NULL of none exists */
3262 SCIP* scip /**< SCIP data structure */
3263 )
3264{
3265 SCIP_SOL* sol;
3266
3267 assert(scip != NULL);
3268
3269 sol = NULL;
3270
3271 if( scip->set->reopt_enable && scip->stat->nreoptruns > 1 )
3272 {
3274 }
3275
3276 return sol;
3277}
3278
3279/** returns the objective coefficent of a given variable in a previous iteration
3280 *
3281 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3282 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3283 *
3284 * @pre This method can be called if @p scip is in one of the following stages:
3285 * - \ref SCIP_STAGE_PRESOLVING
3286 * - \ref SCIP_STAGE_SOLVING
3287 */
3289 SCIP* scip, /**< SCIP data structure */
3290 SCIP_VAR* var, /**< variable */
3291 int run, /**< number of the run */
3292 SCIP_Real* objcoef /**< pointer to store the objective coefficient */
3293 )
3294{
3295 assert(scip != NULL);
3296 assert(var != NULL);
3297 assert(0 < run && run <= scip->stat->nreoptruns);
3298
3299 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetReoptOldObjCoef", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3300
3301 if( SCIPvarIsOriginal(var) )
3302 *objcoef = SCIPreoptGetOldObjCoef(scip->reopt, run, SCIPvarGetIndex(var));
3303 else
3304 {
3305 SCIP_VAR* origvar;
3306 SCIP_Real constant;
3307 SCIP_Real scalar;
3308
3310
3311 origvar = var;
3312 constant = 0.0;
3313 scalar = 1.0;
3314
3315 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
3316 assert(origvar != NULL);
3317 assert(SCIPvarIsOriginal(origvar));
3318
3319 *objcoef = SCIPreoptGetOldObjCoef(scip->reopt, run, SCIPvarGetIndex(origvar));
3320 }
3321 return SCIP_OKAY;
3322}
3323
3324/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3325 * preserved
3326 *
3327 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3328 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3329 *
3330 * @pre This method can be called if @p scip is in one of the following stages:
3331 * - \ref SCIP_STAGE_INIT
3332 * - \ref SCIP_STAGE_PROBLEM
3333 * - \ref SCIP_STAGE_TRANSFORMED
3334 * - \ref SCIP_STAGE_PRESOLVING
3335 * - \ref SCIP_STAGE_PRESOLVED
3336 * - \ref SCIP_STAGE_SOLVING
3337 * - \ref SCIP_STAGE_SOLVED
3338 *
3339 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT or \ref SCIP_STAGE_PROBLEM, the stage of
3340 * \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_TRANSFORMED
3341 *
3342 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3343 */
3345 SCIP* scip, /**< SCIP data structure */
3346 SCIP_Bool restart /**< should certain data be preserved for improved restarting? */
3347 )
3348{
3350
3351 switch( scip->set->stage )
3352 {
3353 case SCIP_STAGE_INIT:
3355 case SCIP_STAGE_PROBLEM:
3356 return SCIP_OKAY;
3357
3359 {
3360 SCIP_Bool infeasible;
3361
3362 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3363 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3364 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3365 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3366
3367 /* exit presolving */
3368 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3369 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3370 }
3371
3372 /*lint -fallthrough*/
3374 /* switch stage to TRANSFORMED */
3375 scip->set->stage = SCIP_STAGE_TRANSFORMED;
3377 return SCIP_OKAY;
3378
3379 case SCIP_STAGE_SOLVING:
3380 case SCIP_STAGE_SOLVED:
3381 /* free solution process data structures */
3382 SCIP_CALL( freeSolve(scip, restart) );
3383 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3384 return SCIP_OKAY;
3385
3386 default:
3387 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3388 return SCIP_INVALIDCALL;
3389 } /*lint !e788*/
3390}
3391
3392/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3393 * preserved
3394 *
3395 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3396 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3397 *
3398 * @pre This method can be called if @p scip is in one of the following stages:
3399 * - \ref SCIP_STAGE_INIT
3400 * - \ref SCIP_STAGE_PROBLEM
3401 * - \ref SCIP_STAGE_TRANSFORMED
3402 * - \ref SCIP_STAGE_PRESOLVING
3403 * - \ref SCIP_STAGE_PRESOLVED
3404 * - \ref SCIP_STAGE_SOLVING
3405 * - \ref SCIP_STAGE_SOLVED
3406 *
3407 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT, \ref SCIP_STAGE_TRANSFORMED or \ref SCIP_STAGE_PROBLEM,
3408 * the stage of \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_PRESOLVED.
3409 *
3410 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3411 */
3413 SCIP* scip /**< SCIP data structure */
3414 )
3415{
3416 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeReoptSolve", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3417
3418 switch( scip->set->stage )
3419 {
3420 case SCIP_STAGE_INIT:
3423 case SCIP_STAGE_PROBLEM:
3424 return SCIP_OKAY;
3425
3427 {
3428 SCIP_Bool infeasible;
3429
3430 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3431 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3432 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3433 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3434
3435 /* exit presolving */
3436 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3437 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3438
3439 return SCIP_OKAY;
3440 }
3441
3442 case SCIP_STAGE_SOLVING:
3443 case SCIP_STAGE_SOLVED:
3444 /* free solution process data structures */
3446 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3447 return SCIP_OKAY;
3448
3449 default:
3450 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3451 return SCIP_INVALIDCALL;
3452 } /*lint !e788*/
3453}
3454
3455/** frees all solution process data including presolving and transformed problem, only original problem is kept
3456 *
3457 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3458 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3459 *
3460 * @pre This method can be called if @p scip is in one of the following stages:
3461 * - \ref SCIP_STAGE_INIT
3462 * - \ref SCIP_STAGE_PROBLEM
3463 * - \ref SCIP_STAGE_TRANSFORMED
3464 * - \ref SCIP_STAGE_PRESOLVING
3465 * - \ref SCIP_STAGE_PRESOLVED
3466 * - \ref SCIP_STAGE_SOLVING
3467 * - \ref SCIP_STAGE_SOLVED
3468 *
3469 * @post After calling this method \SCIP reaches one of the following stages:
3470 * - \ref SCIP_STAGE_INIT if the method was called from \SCIP stage \ref SCIP_STAGE_INIT
3471 * - \ref SCIP_STAGE_PROBLEM if the method was called from any other of the allowed stages
3472 *
3473 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3474 */
3476 SCIP* scip /**< SCIP data structure */
3477 )
3478{
3479 assert(scip != NULL);
3480
3481 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeTransform", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3482
3483 /* release variables and constraints captured by reoptimization */
3484 if( scip->reopt != NULL )
3485 {
3486 SCIP_CALL( SCIPreoptReleaseData(scip->reopt, scip->set, scip->mem->probmem) );
3487 }
3488
3489 switch( scip->set->stage )
3490 {
3491 case SCIP_STAGE_INIT:
3492 case SCIP_STAGE_PROBLEM:
3493 return SCIP_OKAY;
3494
3496 {
3497 SCIP_Bool infeasible;
3498
3499 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3500 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3501 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3502 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3503
3504 /* exit presolving */
3505 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3506 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3507 }
3508
3509 /*lint -fallthrough*/
3511 case SCIP_STAGE_SOLVING:
3512 case SCIP_STAGE_SOLVED:
3513 /* the solve was already freed, we directly go to freeTransform() */
3514 if( !scip->set->reopt_enable || scip->set->stage != SCIP_STAGE_PRESOLVED )
3515 {
3516 /* free solution process data */
3518 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3519 }
3520 /*lint -fallthrough*/
3521
3523 /* free transformed problem data structures */
3525 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3526 return SCIP_OKAY;
3527
3529 assert(scip->set->stage == SCIP_STAGE_TRANSFORMING);
3531 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3532 return SCIP_OKAY;
3533
3534 default:
3535 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3536 return SCIP_INVALIDCALL;
3537 } /*lint !e788*/
3538}
3539
3540/** informs \SCIP that the solving process should be interrupted as soon as possible (e.g., after the current node has
3541 * been solved)
3542 *
3543 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3544 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3545 *
3546 * @pre This method can be called if @p scip is in one of the following stages:
3547 * - \ref SCIP_STAGE_PROBLEM
3548 * - \ref SCIP_STAGE_TRANSFORMING
3549 * - \ref SCIP_STAGE_TRANSFORMED
3550 * - \ref SCIP_STAGE_INITPRESOLVE
3551 * - \ref SCIP_STAGE_PRESOLVING
3552 * - \ref SCIP_STAGE_EXITPRESOLVE
3553 * - \ref SCIP_STAGE_PRESOLVED
3554 * - \ref SCIP_STAGE_SOLVING
3555 * - \ref SCIP_STAGE_SOLVED
3556 * - \ref SCIP_STAGE_EXITSOLVE
3557 * - \ref SCIP_STAGE_FREETRANS
3558 *
3559 * @note the \SCIP stage does not get changed
3560 */
3562 SCIP* scip /**< SCIP data structure */
3563 )
3564{
3565 SCIP_CALL( SCIPcheckStage(scip, "SCIPinterruptSolve", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3566
3567 /* set the userinterrupt flag */
3568 scip->stat->userinterrupt = TRUE;
3569
3570 return SCIP_OKAY;
3571}
3572
3573/** indicates whether \SCIP has been informed that the solving process should be interrupted as soon as possible
3574 *
3575 * This function returns whether SCIPinterruptSolve() has been called, which is different from SCIPinterrupted(),
3576 * which returns whether a SIGINT signal has been received by the SCIP signal handler.
3577 *
3578 * @pre This method can be called if @p scip is in one of the following stages:
3579 * - \ref SCIP_STAGE_PROBLEM
3580 * - \ref SCIP_STAGE_TRANSFORMING
3581 * - \ref SCIP_STAGE_TRANSFORMED
3582 * - \ref SCIP_STAGE_INITPRESOLVE
3583 * - \ref SCIP_STAGE_PRESOLVING
3584 * - \ref SCIP_STAGE_EXITPRESOLVE
3585 * - \ref SCIP_STAGE_PRESOLVED
3586 * - \ref SCIP_STAGE_SOLVING
3587 * - \ref SCIP_STAGE_SOLVED
3588 * - \ref SCIP_STAGE_EXITSOLVE
3589 * - \ref SCIP_STAGE_FREETRANS
3590 *
3591 * @note the \SCIP stage does not get changed
3592 */
3594 SCIP* scip /**< SCIP data structure */
3595 )
3596{
3597 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisSolveInterrupted", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3598
3599 return scip->stat->userinterrupt;
3600}
3601
3602/** informs SCIP that the solving process should be restarted as soon as possible (e.g., after the current node has
3603 * been solved)
3604 *
3605 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3606 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3607 *
3608 * @pre This method can be called if @p scip is in one of the following stages:
3609 * - \ref SCIP_STAGE_INITPRESOLVE
3610 * - \ref SCIP_STAGE_PRESOLVING
3611 * - \ref SCIP_STAGE_EXITPRESOLVE
3612 * - \ref SCIP_STAGE_SOLVING
3613 *
3614 * @note the \SCIP stage does not get changed
3615 */
3617 SCIP* scip /**< SCIP data structure */
3618 )
3619{
3621
3622 /* set the userrestart flag */
3623 scip->stat->userrestart = TRUE;
3624
3625 return SCIP_OKAY;
3626}
3627
3628/** returns whether reoptimization is enabled or not */
3630 SCIP* scip /**< SCIP data structure */
3631 )
3632{
3633 assert(scip != NULL);
3634
3635 return scip->set->reopt_enable;
3636}
3637
3638/** returns the stored solutions corresponding to a given run */
3640 SCIP* scip, /**< SCIP data structure */
3641 int run, /**< number of the run */
3642 SCIP_SOL** sols, /**< array to store solutions */
3643 int solssize, /**< size of the array */
3644 int* nsols /**< pointer to store number of solutions */
3645 )
3646{
3647 assert(scip != NULL);
3648 assert(sols != NULL);
3649 assert(solssize > 0);
3650
3651 if( scip->set->reopt_enable )
3652 {
3653 assert(run > 0 && run <= scip->stat->nreoptruns);
3654 SCIP_CALL( SCIPreoptGetSolsRun(scip->reopt, run, sols, solssize, nsols) );
3655 }
3656 else
3657 {
3658 *nsols = 0;
3659 }
3660
3661 return SCIP_OKAY;
3662}
3663
3664/** mark all stored solutions as not updated */
3666 SCIP* scip /**< SCIP data structure */
3667 )
3668{
3669 assert(scip != NULL);
3670 assert(scip->set->reopt_enable);
3671 assert(scip->reopt != NULL);
3672
3673 if( scip->set->reopt_enable )
3674 {
3675 assert(scip->reopt != NULL);
3677 }
3678}
3679
3680/** check if the reoptimization process should be restarted
3681 *
3682 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3683 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3684 *
3685 * @pre This method can be called if @p scip is in one of the following stages:
3686 * - \ref SCIP_STAGE_TRANSFORMED
3687 * - \ref SCIP_STAGE_SOLVING
3688 */
3690 SCIP* scip, /**< SCIP data structure */
3691 SCIP_NODE* node, /**< current node of the branch and bound tree (or NULL) */
3692 SCIP_Bool* restart /**< pointer to store of the reoptimitation process should be restarted */
3693 )
3694{
3695 assert(scip != NULL);
3696 assert(scip->set->reopt_enable);
3697 assert(scip->reopt != NULL);
3698
3699 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckReoptRestart", FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3700
3701 SCIP_CALL( SCIPreoptCheckRestart(scip->reopt, scip->set, scip->mem->probmem, node, scip->transprob->vars,
3702 scip->transprob->nvars, restart) );
3703
3704 return SCIP_OKAY;
3705}
3706
3707/** returns whether we are in the restarting phase
3708 *
3709 * @return TRUE, if we are in the restarting phase; FALSE, otherwise
3710 *
3711 * @pre This method can be called if @p scip is in one of the following stages:
3712 * - \ref SCIP_STAGE_INITPRESOLVE
3713 * - \ref SCIP_STAGE_PRESOLVING
3714 * - \ref SCIP_STAGE_EXITPRESOLVE
3715 * - \ref SCIP_STAGE_PRESOLVED
3716 * - \ref SCIP_STAGE_INITSOLVE
3717 * - \ref SCIP_STAGE_SOLVING
3718 * - \ref SCIP_STAGE_SOLVED
3719 * - \ref SCIP_STAGE_EXITSOLVE
3720 * - \ref SCIP_STAGE_FREETRANS
3721 */
3723 SCIP* scip /**< SCIP data structure */
3724 )
3725{
3727
3728 /* return the restart status */
3729 return scip->stat->inrestart;
3730}
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:292
#define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
Definition debug.h:365
#define SCIPdebugReset(set)
Definition debug.h:293
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Longint
Definition def.h:150
#define SCIP_MEM_NOLIMIT
Definition def.h:300
#define SCIP_REAL_MAX
Definition def.h:167
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define SCIPABORT()
Definition def.h:336
#define REALABS(x)
Definition def.h:191
#define SCIP_CALL(x)
Definition def.h:364
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:4385
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
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:4525
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition sol.c:4254
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
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:1114
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition sol.c:4155
SCIP_RETCODE SCIPrecomputeSolObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:2075
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition scip_sol.c:2936
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:4114
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1890
SCIP_RETCODE SCIPcreateSolExact(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:564
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:18365
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
int SCIPvarGetIndex(SCIP_VAR *var)
Definition var.c:23684
SCIP_Real SCIPvarGetWorstBoundGlobal(SCIP_VAR *var)
Definition var.c:24236
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:23838
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:23826
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition var.c:23449
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 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:6589
SCIP_RETCODE SCIPreoptSaveActiveConss(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_PROB *transprob, BMS_BLKMEM *blkmem)
Definition reopt.c:8142
SCIP_RETCODE SCIPreoptAddRun(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_VAR **origvars, int norigvars, int size)
Definition reopt.c:5353
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:5266
SCIP_SOL * SCIPreoptGetLastBestSol(SCIP_REOPT *reopt)
Definition reopt.c:5634
SCIP_RETCODE SCIPreoptGetSolsRun(SCIP_REOPT *reopt, int run, SCIP_SOL **sols, int solssize, int *nsols)
Definition reopt.c:5461
SCIP_RETCODE SCIPreoptReleaseData(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition reopt.c:5089
void SCIPreoptResetSolMarks(SCIP_REOPT *reopt)
Definition reopt.c:5724
SCIP_Real SCIPreoptGetOldObjCoef(SCIP_REOPT *reopt, int run, int idx)
Definition reopt.c:5662
SCIP_RETCODE SCIPreoptFree(SCIP_REOPT **reopt, SCIP_SET *set, SCIP_PRIMAL *origprimal, BMS_BLKMEM *blkmem)
Definition reopt.c:5116
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:5319
int SCIPreoptGetNNodes(SCIP_REOPT *reopt, SCIP_NODE *node)
Definition reopt.c:5745
SCIP_RETCODE SCIPreoptResetActiveConss(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat)
Definition reopt.c:8234
SCIP_RETCODE SCIPreoptCreate(SCIP_REOPT **reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition reopt.c:5008
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:6221
SCIP_RETCODE SCIPreoptMergeVarHistory(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **vars, int nvars)
Definition reopt.c:6497
SCIP_RETCODE SCIPreoptSaveGlobalBounds(SCIP_REOPT *reopt, SCIP_PROB *transprob, BMS_BLKMEM *blkmem)
Definition reopt.c:8102
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:5528
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:8182
SCIP_RETCODE SCIPreoptApplyGlbConss(SCIP *scip, SCIP_REOPT *reopt, SCIP_SET *set, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition reopt.c:7566
SCIP_RETCODE SCIPreoptReset(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition reopt.c:5690
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:6447
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:4387
SCIP_RETCODE SCIPsetInitsolPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition set.c:5876
SCIP_RETCODE SCIPsetInitPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition set.c:5567
SCIP_RETCODE SCIPsetSetReoptimizationParams(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition set.c:808
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:7023
void SCIPsetSortPropsPresol(SCIP_SET *set)
Definition set.c:4685
SCIP_RETCODE SCIPsetCheckParamValuePtrUnique(SCIP_SET *set)
Definition set.c:3800
void SCIPsetSortComprs(SCIP_SET *set)
Definition set.c:4964
SCIP_RETCODE SCIPsetExitprePlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition set.c:5838
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6975
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition set.c:6386
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition set.c:6563
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition set.c:6521
SCIP_RETCODE SCIPsetExitsolPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_Bool restart)
Definition set.c:5985
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition set.c:6643
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition set.c:6486
SCIP_RETCODE SCIPsetExitPlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition set.c:5688
SCIP_RETCODE SCIPsetInitprePlugins(SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_STAT *stat)
Definition set.c:5800
SCIP_NODESEL * SCIPsetGetNodesel(SCIP_SET *set, SCIP_STAT *stat)
Definition set.c:5088
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:5155
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:5983
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)