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