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