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