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