Scippy

SCIP

Solving Constraint Integer Programs

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