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
1207 /* abort if time limit was reached or user interrupted */
1208 stopped = SCIPsolveIsStopped(scip->set, scip->stat, FALSE);
1209
1210 /* perform presolving rounds */
1211 while( !finished && !stopped )
1212 {
1213 /* store current number of reductions */
1214 scip->stat->lastnpresolfixedvars = scip->stat->npresolfixedvars;
1215 scip->stat->lastnpresolaggrvars = scip->stat->npresolaggrvars;
1216 scip->stat->lastnpresolchgvartypes = scip->stat->npresolchgvartypes;
1217 scip->stat->lastnpresolchgbds = scip->stat->npresolchgbds;
1218 scip->stat->lastnpresoladdholes = scip->stat->npresoladdholes;
1219 scip->stat->lastnpresoldelconss = scip->stat->npresoldelconss;
1220 scip->stat->lastnpresoladdconss = scip->stat->npresoladdconss;
1221 scip->stat->lastnpresolupgdconss = scip->stat->npresolupgdconss;
1222 scip->stat->lastnpresolchgcoefs = scip->stat->npresolchgcoefs;
1223 scip->stat->lastnpresolchgsides = scip->stat->npresolchgsides;
1224#ifdef SCIP_DISABLED_CODE
1225 scip->stat->lastnpresolimplications = scip->stat->nimplications;
1226 scip->stat->lastnpresolcliques = SCIPcliquetableGetNCliques(scip->cliquetable);
1227#endif
1228
1229 /* set presolving flag */
1230 scip->stat->performpresol = TRUE;
1231
1232 /* sort propagators */
1234
1235 /* sort presolvers by priority */
1237
1238 /* check if this will be the last presolving round (in that case, we want to run all presolvers) */
1239 lastround = (scip->set->presol_maxrounds == -1 ? FALSE : (scip->stat->npresolrounds + 1 >= scip->set->presol_maxrounds));
1240
1241 presoltiming = SCIP_PRESOLTIMING_FAST;
1242
1243 /* perform the presolving round by calling the presolvers, propagators, and constraint handlers */
1244 assert(!(*unbounded));
1245 assert(!(*infeasible));
1246 SCIP_CALL( presolveRound(scip, &presoltiming, unbounded, infeasible, lastround,
1247 &presolstart, scip->set->npresols, &propstart, scip->set->nprops, &consstart, scip->set->nconshdlrs) );
1248
1249 /* check, if we should abort presolving due to not enough changes in the last round */
1251
1252 SCIPdebugMsg(scip, "presolving round %d returned with unbounded = %u, infeasible = %u, finished = %u\n", scip->stat->npresolrounds, *unbounded, *infeasible, finished);
1253
1254 /* check whether problem is infeasible or unbounded or vanished */
1255 *vanished = scip->transprob->nvars == 0 && scip->transprob->nconss == 0 && scip->set->nactivepricers == 0;
1256 finished = finished || *unbounded || *infeasible || *vanished;
1257
1258 /* increase round number */
1259 scip->stat->npresolrounds++;
1260
1261 if( !finished )
1262 {
1263 /* print presolving statistics */
1264 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
1265 "(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",
1266 scip->stat->npresolrounds, ( presoltiming == SCIP_PRESOLTIMING_FAST ? "fast)" :
1267 (presoltiming == SCIP_PRESOLTIMING_MEDIUM ? "medium)" :
1268 (presoltiming == SCIP_PRESOLTIMING_EXHAUSTIVE ?"exhaustive)" :
1269 "final)")) ),
1270 scip->stat->npresolfixedvars + scip->stat->npresolaggrvars,
1271 scip->stat->npresoldelconss, scip->stat->npresoladdconss,
1272 scip->stat->npresolchgbds, scip->stat->npresolchgsides,
1273 scip->stat->npresolchgcoefs, scip->stat->npresolupgdconss,
1274 scip->stat->nimplications, SCIPcliquetableGetNCliques(scip->cliquetable));
1275 }
1276
1277 /* abort if time limit was reached or user interrupted */
1278 stopped = SCIPsolveIsStopped(scip->set, scip->stat, FALSE);
1279 }
1280
1281 /* first change status of scip, so that all plugins in their exitpre callbacks can ask SCIP for the correct status */
1282 if( *infeasible )
1283 {
1284 /* switch status to OPTIMAL */
1285 if( scip->primal->nlimsolsfound > 0 )
1286 {
1287 scip->stat->status = SCIP_STATUS_OPTIMAL;
1288 }
1289 else /* switch status to INFEASIBLE */
1290 scip->stat->status = SCIP_STATUS_INFEASIBLE;
1291 }
1292 else if( *unbounded )
1293 {
1294 if( scip->primal->nsols >= 1 ) /* switch status to UNBOUNDED */
1295 scip->stat->status = SCIP_STATUS_UNBOUNDED;
1296 else /* switch status to INFORUNBD */
1297 scip->stat->status = SCIP_STATUS_INFORUNBD;
1298 }
1299 /* if no variables and constraints are present, we try to add the empty solution (constraint handlers with needscons
1300 * flag FALSE could theoretically reject it); if no active pricers could create variables later, we conclude
1301 * optimality or infeasibility */
1302 else if( scip->transprob->nvars == 0 && scip->transprob->nconss == 0 )
1303 {
1304 SCIP_SOL* sol;
1305 SCIP_Bool stored;
1306
1309
1310 if( scip->set->nactivepricers == 0 )
1311 {
1312 assert(*vanished);
1313
1314 if( scip->primal->nlimsolsfound > 0 )
1315 scip->stat->status = SCIP_STATUS_OPTIMAL;
1316 else
1317 scip->stat->status = SCIP_STATUS_INFEASIBLE;
1318 }
1319 }
1320
1321 /* deinitialize presolving */
1322 if( finished && (!stopped || *unbounded || *infeasible || *vanished) )
1323 {
1324 SCIP_Real maxnonzeros;
1325 SCIP_Longint nchecknonzeros;
1326 SCIP_Longint nactivenonzeros;
1327 SCIP_Bool approxchecknonzeros;
1328 SCIP_Bool approxactivenonzeros;
1329 SCIP_Bool infeas;
1330
1331 SCIP_CALL( exitPresolve(scip, *unbounded || *infeasible || *vanished, &infeas) );
1332 *infeasible = *infeasible || infeas;
1333
1334 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
1335
1336 /* resort variables if we are not already done (unless variable permutation was explicitly activated) */
1337 if( !scip->set->random_permutevars && !(*infeasible) && !(*unbounded) && !(*vanished) )
1338 {
1339 /* (Re)Sort the variables, which appear in the four categories (binary, integer, implicit, continuous) after
1340 * presolve with respect to their original index (within their categories). Adjust the problem index afterwards
1341 * which is supposed to reflect the position in the variable array. This additional (re)sorting is supposed to
1342 * get more robust against the order presolving fixed variables. (We also reobtain a possible block structure
1343 * induced by the user model)
1344 */
1345 SCIPprobResortVars(scip->transprob);
1346 }
1347
1348 /* determine number of non-zeros */
1349 maxnonzeros = (SCIP_Real)SCIPgetNConss(scip) * SCIPgetNVars(scip);
1350 maxnonzeros = MAX(maxnonzeros, 1.0);
1352 scip->stat->nnz = nactivenonzeros;
1353
1354 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
1355 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
1356 "presolved problem has %s%" SCIP_LONGINT_FORMAT " active (%g%%) nonzeros and %s%" SCIP_LONGINT_FORMAT " (%g%%) check nonzeros\n",
1357 approxactivenonzeros ? "more than " : "", nactivenonzeros, nactivenonzeros/maxnonzeros * 100,
1358 approxchecknonzeros ? "more than " : "", nchecknonzeros, nchecknonzeros/maxnonzeros * 100);
1359 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, "\n");
1360 }
1363
1364 /* stop presolving time */
1365 SCIPclockStop(scip->stat->presolvingtime, scip->set);
1366 SCIPclockStop(scip->stat->presolvingtimeoverall, scip->set);
1367
1368 /* print presolving statistics */
1369 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1370 "presolving (%d rounds: %d fast, %d medium, %d exhaustive):\n", scip->stat->npresolrounds,
1371 scip->stat->npresolroundsfast, scip->stat->npresolroundsmed, scip->stat->npresolroundsext);
1372 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1373 " %d deleted vars, %d deleted constraints, %d added constraints, %d tightened bounds, %d added holes, %d changed sides, %d changed coefficients\n",
1374 scip->stat->npresolfixedvars + scip->stat->npresolaggrvars, scip->stat->npresoldelconss, scip->stat->npresoladdconss,
1375 scip->stat->npresolchgbds, scip->stat->npresoladdholes, scip->stat->npresolchgsides, scip->stat->npresolchgcoefs);
1376 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
1377 " %d implications, %d cliques\n", scip->stat->nimplications, SCIPcliquetableGetNCliques(scip->cliquetable));
1378
1379 /* remember number of constraints */
1380 SCIPprobMarkNConss(scip->transprob);
1381
1382 return SCIP_OKAY;
1383}
1384
1385/** tries to transform original solutions to the transformed problem space */
1386static
1388 SCIP* scip /**< SCIP data structure */
1389 )
1390{
1391 SCIP_SOL** sols;
1393 SCIP_SOL* sol;
1394 SCIP_Real* solvals;
1395 SCIP_Bool* solvalset;
1396 SCIP_Bool added;
1397 SCIP_Longint oldnsolsfound;
1398 int nsols;
1399 int ntransvars;
1400 int naddedsols;
1401 int s;
1402
1403 nsols = SCIPgetNSols(scip);
1404 oldnsolsfound = scip->primal->nsolsfound;
1405
1406 /* no solution to transform */
1407 if( nsols == 0 )
1408 return SCIP_OKAY;
1409
1410 SCIPdebugMsg(scip, "try to transfer %d original solutions into the transformed problem space\n", nsols);
1411
1412 ntransvars = scip->transprob->nvars;
1413 naddedsols = 0;
1414
1415 /* It might happen, that the added transferred solution does not equal the corresponding original one, which might
1416 * result in the array of solutions being changed. Thus we temporarily copy the array and traverse it in reverse
1417 * order to ensure that the regarded solution in the copied array was not already freed when new solutions were added
1418 * and the worst solutions were freed.
1419 */
1422 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, ntransvars) );
1423 SCIP_CALL( SCIPallocBufferArray(scip, &solvalset, ntransvars) );
1424
1425 for( s = nsols-1; s >= 0; --s )
1426 {
1427 sol = sols[s];
1428
1429 /* it might happen that a transferred original solution has a better objective than its original counterpart
1430 * (e.g., because multi-aggregated variables get another value, but the solution is still feasible);
1431 * in this case, it might happen that the solution is not an original one and we just skip this solution
1432 */
1433 if( !SCIPsolIsOriginal(sol) )
1434 continue;
1435
1436 SCIP_CALL( SCIPprimalTransformSol(scip->primal, sol, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
1437 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, solvals,
1438 solvalset, ntransvars, &added) );
1439
1440 if( added )
1441 ++naddedsols;
1442 }
1443
1444 if( naddedsols > 0 )
1445 {
1447 "transformed %d/%d original solutions to the transformed problem space\n",
1448 naddedsols, nsols);
1449
1450 scip->stat->nexternalsolsfound += scip->primal->nsolsfound - oldnsolsfound;
1451 }
1452
1454 SCIPfreeBufferArray(scip, &solvals);
1455 SCIPfreeBufferArray(scip, &sols);
1456
1457 return SCIP_OKAY;
1458}
1459
1460/** initializes solution process data structures */
1461static
1463 SCIP* scip, /**< SCIP data structure */
1464 SCIP_Bool solved /**< is problem already solved? */
1465 )
1466{
1467 assert(scip != NULL);
1468 assert(scip->mem != NULL);
1469 assert(scip->set != NULL);
1470 assert(scip->stat != NULL);
1471 assert(scip->nlp == NULL);
1472 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
1473
1474 /**@todo check whether other methodscan be skipped if problem has been solved */
1475 /* if problem has been solved, several time consuming tasks must not be performed */
1476 if( !solved )
1477 {
1478 /* reset statistics for current branch and bound run */
1479 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, solved);
1481
1482 /* LP is empty anyway; mark empty LP to be solved and update validsollp counter */
1483 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1484
1485 /* update upper bound and cutoff bound due to objective limit in primal data */
1486 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1487 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1488 }
1489
1490 /* switch stage to INITSOLVE */
1491 scip->set->stage = SCIP_STAGE_INITSOLVE;
1492
1493 /* initialize NLP if there are nonlinearities */
1494 if( scip->transprob->nlpenabled && !scip->set->nlp_disable )
1495 {
1496 SCIPdebugMsg(scip, "constructing empty NLP\n");
1497
1498 SCIP_CALL( SCIPnlpCreate(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, SCIPprobGetName(scip->transprob), scip->transprob->nvars) );
1499 assert(scip->nlp != NULL);
1500
1501 SCIP_CALL( SCIPnlpAddVars(scip->nlp, scip->mem->probmem, scip->set, scip->transprob->nvars, scip->transprob->vars) );
1502
1503 /* Adjust estimation of external memory: SCIPtransformProb() estimated the memory used for the LP-solver. As a
1504 * very crude approximation just double this number. Only do this once in the first run. */
1505 if( scip->set->misc_estimexternmem && scip->stat->nruns <= 1 )
1506 {
1507 scip->stat->externmemestim *= 2;
1508 SCIPdebugMsg(scip, "external memory usage estimated to %" SCIP_LONGINT_FORMAT " byte\n", scip->stat->externmemestim);
1509 }
1510 }
1511
1512 /* possibly create visualization output file */
1513 SCIP_CALL( SCIPvisualInit(scip->stat->visual, scip->mem->probmem, scip->set, scip->messagehdlr) );
1514
1515 /* initialize solution process data structures */
1516 SCIP_CALL( SCIPpricestoreCreate(&scip->pricestore) );
1517 SCIP_CALL( SCIPsepastoreCreate(&scip->sepastore, scip->mem->probmem, scip->set) );
1518 SCIP_CALL( SCIPsepastoreCreate(&scip->sepastoreprobing, scip->mem->probmem, scip->set) );
1519 SCIP_CALL( SCIPcutpoolCreate(&scip->cutpool, scip->mem->probmem, scip->set, scip->set->sepa_cutagelimit, TRUE) );
1520 SCIP_CALL( SCIPcutpoolCreate(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->set->sepa_cutagelimit, FALSE) );
1521 SCIP_CALL( SCIPtreeCreateRoot(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue,
1522 scip->lp) );
1523
1524 /* update dual bound of the root node if a valid dual bound is at hand */
1525 if( scip->transprob->dualbound < SCIP_INVALID )
1526 {
1527 SCIP_Real internobjval = SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, scip->transprob->dualbound);
1528
1529 scip->stat->lastlowerbound = internobjval;
1530
1531 SCIPnodeUpdateLowerbound(SCIPtreeGetRootNode(scip->tree), scip->stat, scip->set, scip->tree, scip->transprob,
1532 scip->origprob, internobjval);
1533 }
1534
1535 /* try to transform original solutions to the transformed problem space */
1536 if( scip->set->misc_transorigsols )
1537 {
1539 }
1540
1541 /* inform the transformed problem that the branch and bound process starts now */
1542 SCIP_CALL( SCIPprobInitSolve(scip->transprob, scip->set) );
1543
1544 /* transform the decomposition storage */
1546
1547 /* inform plugins that the branch and bound process starts now */
1548 SCIP_CALL( SCIPsetInitsolPlugins(scip->set, scip->mem->probmem, scip->stat) );
1549
1550 /* remember number of constraints */
1551 SCIPprobMarkNConss(scip->transprob);
1552
1553 /* if all variables are known, calculate a trivial primal bound by setting all variables to their worst bound */
1554 if( scip->set->nactivepricers == 0 )
1555 {
1556 SCIP_VAR* var;
1557 SCIP_Real obj;
1558 SCIP_Real objbound;
1559 SCIP_Real bd;
1560 int v;
1561
1562 objbound = 0.0;
1563 for( v = 0; v < scip->transprob->nvars && !SCIPsetIsInfinity(scip->set, objbound); ++v )
1564 {
1565 var = scip->transprob->vars[v];
1567 if( !SCIPsetIsZero(scip->set, obj) )
1568 {
1570 if( SCIPsetIsInfinity(scip->set, REALABS(bd)) )
1571 objbound = SCIPsetInfinity(scip->set);
1572 else
1573 objbound += obj * bd;
1574 }
1575 }
1576
1577 /* adjust primal bound, such that solution with worst bound may be found */
1578 if( objbound + SCIPsetCutoffbounddelta(scip->set) != objbound ) /*lint !e777*/
1579 objbound += SCIPsetCutoffbounddelta(scip->set);
1580 /* if objbound is very large, adding the cutoffbounddelta may not change the number; in this case, we are using
1581 * SCIPnextafter to ensure that the cutoffbound is really larger than the best possible solution value
1582 */
1583 else
1584 objbound = SCIPnextafter(objbound, SCIP_REAL_MAX);
1585
1586 /* update cutoff bound */
1587 if( !SCIPsetIsInfinity(scip->set, objbound) && SCIPsetIsLT(scip->set, objbound, scip->primal->cutoffbound) )
1588 {
1589 /* adjust cutoff bound */
1590 SCIP_CALL( SCIPprimalSetCutoffbound(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1591 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, objbound, FALSE) );
1592 }
1593 }
1594
1595 /* switch stage to SOLVING */
1596 scip->set->stage = SCIP_STAGE_SOLVING;
1597
1598 return SCIP_OKAY;
1599}
1600
1601/** frees solution process data structures */
1602static
1604 SCIP* scip, /**< SCIP data structure */
1605 SCIP_Bool restart /**< was this free solve call triggered by a restart? */
1606 )
1607{
1608 assert(scip != NULL);
1609 assert(scip->mem != NULL);
1610 assert(scip->set != NULL);
1611 assert(scip->stat != NULL);
1612 assert(scip->set->stage == SCIP_STAGE_SOLVING || scip->set->stage == SCIP_STAGE_SOLVED);
1613
1614 /* mark that we are currently restarting */
1615 if( restart )
1616 {
1617 scip->stat->inrestart = TRUE;
1618
1619 /* copy the current dual bound into the problem data structure such that it can be used initialize the new search
1620 * tree
1621 */
1623 }
1624
1625 /* remove focus from the current focus node */
1626 if( SCIPtreeGetFocusNode(scip->tree) != NULL )
1627 {
1628 SCIP_NODE* node = NULL;
1629 SCIP_Bool cutoff;
1630
1631 SCIP_CALL( SCIPnodeFocus(&node, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
1632 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->conflict,
1633 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable, &cutoff, FALSE, TRUE) );
1634 assert(!cutoff);
1635 }
1636
1637 /* switch stage to EXITSOLVE */
1638 scip->set->stage = SCIP_STAGE_EXITSOLVE;
1639
1640 /* cleanup the conflict storage */
1641 SCIP_CALL( SCIPconflictstoreClean(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) );
1642
1643 /* inform plugins that the branch and bound process is finished */
1644 SCIP_CALL( SCIPsetExitsolPlugins(scip->set, scip->mem->probmem, scip->stat, restart) );
1645
1646 /* free the NLP, if there is one, and reset the flags indicating nonlinearity */
1647 if( scip->nlp != NULL )
1648 {
1649 SCIP_CALL( SCIPnlpFree(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1650 }
1651 scip->transprob->nlpenabled = FALSE;
1652
1653 /* clear the LP, and flush the changes to clear the LP of the solver */
1654 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1656
1657 /* resets the debug environment */
1658 SCIP_CALL( SCIPdebugReset(scip->set) ); /*lint !e506 !e774*/
1659
1660 /* clear all row references in internal data structures */
1661 SCIP_CALL( SCIPcutpoolClear(scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1662 SCIP_CALL( SCIPcutpoolClear(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1663
1664 /* we have to clear the tree prior to the problem deinitialization, because the rows stored in the forks and
1665 * subroots have to be released
1666 */
1667 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1668
1670
1671 /* deinitialize transformed problem */
1672 SCIP_CALL( SCIPprobExitSolve(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, restart) );
1673
1674 /* free solution process data structures */
1675 SCIP_CALL( SCIPcutpoolFree(&scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1676 SCIP_CALL( SCIPcutpoolFree(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1677 SCIP_CALL( SCIPsepastoreFree(&scip->sepastoreprobing, scip->mem->probmem) );
1678 SCIP_CALL( SCIPsepastoreFree(&scip->sepastore, scip->mem->probmem) );
1679 SCIP_CALL( SCIPpricestoreFree(&scip->pricestore) );
1680
1681 /* possibly close visualization output file */
1682 SCIPvisualExit(scip->stat->visual, scip->set, scip->messagehdlr);
1683
1684 /* reset statistics for current branch and bound run */
1685 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 )
1686 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, TRUE);
1687 else
1688 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE);
1689
1690 /* switch stage to TRANSFORMED */
1691 scip->set->stage = SCIP_STAGE_TRANSFORMED;
1692
1693 /* restart finished */
1694 assert( ! restart || scip->stat->inrestart );
1695 scip->stat->inrestart = FALSE;
1696
1697 return SCIP_OKAY;
1698}
1699
1700/** frees solution process data structures when reoptimization is used
1701 *
1702 * in contrast to a freeSolve() this method will preserve the transformed problem such that another presolving round
1703 * after changing the problem (modifying the objective function) is not necessary.
1704 */
1705static
1707 SCIP* scip /**< SCIP data structure */
1708 )
1709{
1710 assert(scip != NULL);
1711 assert(scip->mem != NULL);
1712 assert(scip->set != NULL);
1713 assert(scip->stat != NULL);
1714 assert(scip->set->stage == SCIP_STAGE_SOLVING || scip->set->stage == SCIP_STAGE_SOLVED);
1715
1716 /* remove focus from the current focus node */
1717 if( SCIPtreeGetFocusNode(scip->tree) != NULL )
1718 {
1719 SCIP_NODE* node = NULL;
1720 SCIP_Bool cutoff;
1721
1722 SCIP_CALL( SCIPnodeFocus(&node, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
1723 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->conflict,
1724 scip->conflictstore, scip->eventfilter, scip->eventqueue, scip->cliquetable, &cutoff, FALSE, TRUE) );
1725 assert(!cutoff);
1726 }
1727
1728 /* mark current stats, such that new solve begins with the var/col/row indices from the previous run */
1729 SCIPstatMark(scip->stat);
1730
1731 /* switch stage to EXITSOLVE */
1732 scip->set->stage = SCIP_STAGE_EXITSOLVE;
1733
1734 /* deinitialize conflict store */
1735 SCIP_CALL( SCIPconflictstoreClear(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) );
1736
1737 /* invalidate the dual bound */
1739
1740 /* inform plugins that the branch and bound process is finished */
1741 SCIP_CALL( SCIPsetExitsolPlugins(scip->set, scip->mem->probmem, scip->stat, FALSE) );
1742
1743 /* call exit methods of plugins */
1744 SCIP_CALL( SCIPsetExitPlugins(scip->set, scip->mem->probmem, scip->stat) );
1745
1746 /* free the NLP, if there is one, and reset the flags indicating nonlinearity */
1747 if( scip->nlp != NULL )
1748 {
1749 SCIP_CALL( SCIPnlpFree(&scip->nlp, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1750 }
1751 scip->transprob->nlpenabled = FALSE;
1752
1753 /* clear the LP, and flush the changes to clear the LP of the solver */
1754 SCIP_CALL( SCIPlpReset(scip->lp, scip->mem->probmem, scip->set, scip->transprob, scip->stat, scip->eventqueue, scip->eventfilter) );
1756
1757 /* resets the debug environment */
1758 SCIP_CALL( SCIPdebugReset(scip->set) ); /*lint !e506 !e774*/
1759
1760 /* clear all row references in internal data structures */
1761 SCIP_CALL( SCIPcutpoolClear(scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1762 SCIP_CALL( SCIPcutpoolClear(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1763
1764 /* we have to clear the tree prior to the problem deinitialization, because the rows stored in the forks and
1765 * subroots have to be released
1766 */
1767 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1768
1769 /* deinitialize transformed problem */
1770 SCIP_CALL( SCIPprobExitSolve(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, FALSE) );
1771
1772 /* free solution process data structures */
1773 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
1774
1775 SCIP_CALL( SCIPcutpoolFree(&scip->cutpool, scip->mem->probmem, scip->set, scip->lp) );
1776 SCIP_CALL( SCIPcutpoolFree(&scip->delayedcutpool, scip->mem->probmem, scip->set, scip->lp) );
1777 SCIP_CALL( SCIPsepastoreFree(&scip->sepastoreprobing, scip->mem->probmem) );
1778 SCIP_CALL( SCIPsepastoreFree(&scip->sepastore, scip->mem->probmem) );
1779 SCIP_CALL( SCIPpricestoreFree(&scip->pricestore) );
1780
1781 /* possibly close visualization output file */
1782 SCIPvisualExit(scip->stat->visual, scip->set, scip->messagehdlr);
1783
1784 /* reset statistics for current branch and bound run */
1785 SCIPstatResetCurrentRun(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE);
1786
1787 /* switch stage to PRESOLVED */
1788 scip->set->stage = SCIP_STAGE_PRESOLVED;
1789
1790 /* restart finished */
1791 scip->stat->inrestart = FALSE;
1792
1793 /* reset solving specific paramters */
1794 if( scip->set->reopt_enable )
1795 {
1796 assert(scip->reopt != NULL);
1797 SCIP_CALL( SCIPreoptReset(scip->reopt, scip->set, scip->mem->probmem) );
1798 }
1799
1800 /* free the debug solution which might live in transformed primal data structure */
1801 SCIP_CALL( SCIPprimalClear(&scip->primal, scip->mem->probmem) );
1802
1803 if( scip->set->misc_resetstat )
1804 {
1805 /* reset statistics to the point before the problem was transformed */
1806 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
1807 }
1808 else
1809 {
1810 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
1812 }
1813
1814 /* reset objective limit */
1816
1817 return SCIP_OKAY;
1818}
1819
1820/** free transformed problem */
1821static
1823 SCIP* scip /**< SCIP data structure */
1824 )
1825{
1826 SCIP_Bool reducedfree;
1827
1828 assert(scip != NULL);
1829 assert(scip->mem != NULL);
1830 assert(scip->stat != NULL);
1831 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED || scip->set->stage == SCIP_STAGE_PRESOLVING ||
1832 (scip->set->stage == SCIP_STAGE_PRESOLVED && scip->set->reopt_enable));
1833
1834 /* If the following evaluates to true, SCIPfreeReoptSolve() has already called the exit-callbacks of the plugins.
1835 * We can skip calling some of the following methods. This can happen if a new objective function was
1836 * installed but the solve was not started.
1837 */
1838 reducedfree = (scip->set->stage == SCIP_STAGE_PRESOLVED && scip->set->reopt_enable);
1839
1840 if( !reducedfree )
1841 {
1842 /* call exit methods of plugins */
1843 SCIP_CALL( SCIPsetExitPlugins(scip->set, scip->mem->probmem, scip->stat) );
1844 }
1845
1846 /* copy best primal solutions to original solution candidate list but not for a benders decomposition
1847 * because their cost information would be incomplete
1848 */
1849 if( !scip->set->reopt_enable && scip->set->limit_maxorigsol > 0 && scip->set->misc_transsolsorig && scip->set->nactivebenders == 0 )
1850 {
1851 SCIP_Bool stored;
1852 SCIP_Bool hasinfval;
1853 int maxsols;
1854 int nsols;
1855 int s;
1856
1857 assert(scip->origprimal->nsols == 0);
1858
1859 nsols = scip->primal->nsols;
1860 maxsols = scip->set->limit_maxorigsol;
1861 stored = TRUE;
1862 s = 0;
1863
1864 /* iterate over all solutions as long as the original solution candidate store size limit is not reached */
1865 while( s < nsols && scip->origprimal->nsols < maxsols )
1866 {
1867 SCIP_SOL* sol;
1868
1869 sol = scip->primal->sols[s];
1870 assert(sol != NULL);
1871
1872 if( !SCIPsolIsOriginal(sol) )
1873 {
1874 /* retransform solution into the original problem space */
1875 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
1876 }
1877 else
1878 hasinfval = FALSE;
1879
1880 /* removing infinite fixings is turned off by the corresponding parameter */
1881 if( !scip->set->misc_finitesolstore )
1882 hasinfval = FALSE;
1883
1884 if( !hasinfval )
1885 {
1886 /* add solution to original candidate solution storage */
1887 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, &stored) );
1888 }
1889 else
1890 {
1892 SCIP_Bool success;
1893
1895
1896 /* infinite fixing could be removed */
1897 if( newsol != NULL )
1898 {
1899 /* add solution to original candidate solution storage; we must not use SCIPprimalAddOrigSolFree()
1900 * because we want to create a copy of the solution in the origprimal solution store, but newsol was
1901 * created in the (transformed) primal
1902 */
1903 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, newsol, &stored) );
1904
1905 /* free solution in (transformed) primal where it was created */
1906 SCIP_CALL( SCIPsolFree(&newsol, scip->mem->probmem, scip->primal) );
1907 }
1908 }
1909 ++s;
1910 }
1911
1912 if( scip->origprimal->nsols > 1 )
1913 {
1915 "stored the %d best primal solutions in the original solution candidate list\n", scip->origprimal->nsols);
1916 }
1917 else if( scip->origprimal->nsols == 1 )
1918 {
1920 "stored the best primal solution in the original solution candidate list\n");
1921 }
1922 }
1923
1924 /* switch stage to FREETRANS */
1925 scip->set->stage = SCIP_STAGE_FREETRANS;
1926
1927 /* reset solving specific paramters */
1928 assert(!scip->set->reopt_enable || scip->reopt != NULL);
1929 if( scip->set->reopt_enable && scip->reopt != NULL )
1930 {
1931 SCIP_CALL( SCIPreoptReset(scip->reopt, scip->set, scip->mem->probmem) );
1932 }
1933
1934 if( !reducedfree )
1935 {
1936 /* clear the conflict store
1937 *
1938 * since the conflict store can contain transformed constraints we need to remove them. the store will be finally
1939 * freed in SCIPfreeProb().
1940 */
1941 SCIP_CALL( SCIPconflictstoreClear(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) );
1942 }
1943
1944 /* free transformed problem data structures */
1945 SCIP_CALL( SCIPprobFree(&scip->transprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
1946 SCIP_CALL( SCIPcliquetableFree(&scip->cliquetable, scip->mem->probmem) );
1947 SCIP_CALL( SCIPconflictFree(&scip->conflict, scip->mem->probmem) );
1948
1949 if( !reducedfree )
1950 {
1951 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
1952 }
1953 SCIP_CALL( SCIPtreeFree(&scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
1954
1955 /* free the debug solution which might live in transformed primal data structure */
1956 SCIP_CALL( SCIPdebugFreeSol(scip->set) ); /*lint !e506 !e774*/
1957 SCIP_CALL( SCIPprimalFree(&scip->primal, scip->mem->probmem) );
1958
1959 SCIP_CALL( SCIPlpFree(&scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter) );
1960 SCIP_CALL( SCIPbranchcandFree(&scip->branchcand) );
1961 SCIP_CALL( SCIPeventfilterFree(&scip->eventfilter, scip->mem->probmem, scip->set) );
1962 SCIP_CALL( SCIPeventqueueFree(&scip->eventqueue) );
1963
1964 if( scip->set->misc_resetstat && !reducedfree )
1965 {
1966 /* reset statistics to the point before the problem was transformed */
1967 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
1968 }
1969 else
1970 {
1971 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
1973 }
1974
1975 /* switch stage to PROBLEM */
1976 scip->set->stage = SCIP_STAGE_PROBLEM;
1977
1978 /* reset objective limit */
1980
1981 /* reset original variable's local and global bounds to their original values */
1982 SCIP_CALL( SCIPprobResetBounds(scip->origprob, scip->mem->probmem, scip->set, scip->stat) );
1983
1984 return SCIP_OKAY;
1985}
1986
1987/** free transformed problem in case an error occurs during transformation and return to SCIP_STAGE_PROBLEM */
1988static
1990 SCIP* scip /**< SCIP data structure */
1991 )
1992{
1993 assert(scip != NULL);
1994 assert(scip->mem != NULL);
1995 assert(scip->stat != NULL);
1996 assert(scip->set->stage == SCIP_STAGE_TRANSFORMING);
1997
1998 /* switch stage to FREETRANS */
1999 scip->set->stage = SCIP_STAGE_FREETRANS;
2000
2001 /* free transformed problem data structures */
2002 SCIP_CALL( SCIPprobFree(&scip->transprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
2003 SCIP_CALL( SCIPcliquetableFree(&scip->cliquetable, scip->mem->probmem) );
2004 SCIP_CALL( SCIPconflictFree(&scip->conflict, scip->mem->probmem) );
2005 SCIP_CALL( SCIPrelaxationFree(&scip->relaxation) );
2006 SCIP_CALL( SCIPtreeFree(&scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
2007
2008 /* free the debug solution which might live in transformed primal data structure */
2009 SCIP_CALL( SCIPdebugFreeSol(scip->set) ); /*lint !e506 !e774*/
2010 SCIP_CALL( SCIPprimalFree(&scip->primal, scip->mem->probmem) );
2011
2012 SCIP_CALL( SCIPlpFree(&scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter) );
2013 SCIP_CALL( SCIPbranchcandFree(&scip->branchcand) );
2014 SCIP_CALL( SCIPeventfilterFree(&scip->eventfilter, scip->mem->probmem, scip->set) );
2015 SCIP_CALL( SCIPeventqueueFree(&scip->eventqueue) );
2016
2017 if( scip->set->misc_resetstat )
2018 {
2019 /* reset statistics to the point before the problem was transformed */
2020 SCIPstatReset(scip->stat, scip->set, scip->transprob, scip->origprob);
2021 }
2022 else
2023 {
2024 /* even if statistics are not completely reset, a partial reset of the primal-dual integral is necessary */
2026 }
2027
2028 /* switch stage to PROBLEM */
2029 scip->set->stage = SCIP_STAGE_PROBLEM;
2030
2031 return SCIP_OKAY;
2032}
2033
2034/** displays most relevant statistics after problem was solved */
2035static
2037 SCIP* scip /**< SCIP data structure */
2038 )
2039{
2040 assert(scip != NULL);
2041
2042 /* display most relevant statistics */
2043 if( scip->set->disp_verblevel >= SCIP_VERBLEVEL_NORMAL && scip->set->disp_relevantstats )
2044 {
2045 SCIP_Bool objlimitreached = FALSE;
2046
2047 /* We output that the objective limit has been reached if the problem has been solved, no solution respecting the
2048 * objective limit has been found (nlimsolsfound == 0) and the primal bound is finite. Note that it still might be
2049 * that the original problem is infeasible, even without the objective limit, i.e., we cannot be sure that we
2050 * actually reached the objective limit. */
2051 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVED && scip->primal->nlimsolsfound == 0 && ! SCIPisInfinity(scip, SCIPgetPrimalbound(scip)) )
2053
2054 SCIPmessagePrintInfo(scip->messagehdlr, "\n");
2055 SCIPmessagePrintInfo(scip->messagehdlr, "SCIP Status : ");
2057 SCIPmessagePrintInfo(scip->messagehdlr, "\n");
2058 if( scip->set->reopt_enable )
2059 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Time (sec) : %.2f (over %d runs: %.2f)\n", SCIPclockGetTime(scip->stat->solvingtime), scip->stat->nreoptruns, SCIPclockGetTime(scip->stat->solvingtimeoverall));
2060 else
2061 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Time (sec) : %.2f\n", SCIPclockGetTime(scip->stat->solvingtime));
2062 if( scip->stat->nruns > 1 )
2063 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT " (total of %" SCIP_LONGINT_FORMAT " nodes in %d runs)\n",
2064 scip->stat->nnodes, scip->stat->ntotalnodes, scip->stat->nruns);
2065 else if( scip->set->reopt_enable )
2066 {
2068
2069 branchrule = SCIPfindBranchrule(scip, "nodereopt");
2071
2072 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " reactivated)\n", scip->stat->nnodes, SCIPbranchruleGetNChildren(branchrule));
2073 }
2074 else
2075 SCIPmessagePrintInfo(scip->messagehdlr, "Solving Nodes : %" SCIP_LONGINT_FORMAT "\n", scip->stat->nnodes);
2076 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED && scip->set->stage <= SCIP_STAGE_EXITSOLVE )
2077 {
2078 if( objlimitreached )
2079 {
2080 SCIPmessagePrintInfo(scip->messagehdlr, "Primal Bound : %+.14e (objective limit, %" SCIP_LONGINT_FORMAT " solutions",
2081 SCIPgetPrimalbound(scip), scip->primal->nsolsfound);
2082 if( scip->primal->nsolsfound > 0 )
2083 {
2084 SCIPmessagePrintInfo(scip->messagehdlr, ", best solution %+.14e", SCIPgetSolOrigObj(scip, SCIPgetBestSol(scip)));
2085 }
2086 SCIPmessagePrintInfo(scip->messagehdlr, ")\n");
2087 }
2088 else
2089 {
2091 if( scip->primal->nsolsfound != scip->primal->nlimsolsfound )
2092 (void) SCIPsnprintf(limsolstring, SCIP_MAXSTRLEN, ", %" SCIP_LONGINT_FORMAT " respecting the objective limit", scip->primal->nlimsolsfound);
2093 else
2095
2096 SCIPmessagePrintInfo(scip->messagehdlr, "Primal Bound : %+.14e (%" SCIP_LONGINT_FORMAT " solutions%s)\n",
2097 SCIPgetPrimalbound(scip), scip->primal->nsolsfound, limsolstring);
2098 }
2099 }
2100 if( scip->set->stage >= SCIP_STAGE_SOLVING && scip->set->stage <= SCIP_STAGE_SOLVED )
2101 {
2102 SCIPmessagePrintInfo(scip->messagehdlr, "Dual Bound : %+.14e\n", SCIPgetDualbound(scip));
2103
2104 SCIPmessagePrintInfo(scip->messagehdlr, "Gap : ");
2106 SCIPmessagePrintInfo(scip->messagehdlr, "infinite\n");
2107 else
2108 SCIPmessagePrintInfo(scip->messagehdlr, "%.2f %%\n", 100.0*SCIPgetGap(scip));
2109 }
2110
2111 /* check solution for feasibility in original problem */
2112 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED )
2113 {
2114 SCIP_SOL* sol;
2115
2117 if( sol != NULL )
2118 {
2119 SCIP_Real checkfeastolfac;
2120 SCIP_Real oldfeastol;
2121 SCIP_Bool dispallviols;
2122 SCIP_Bool feasible;
2123
2125 SCIP_CALL( SCIPgetRealParam(scip, "numerics/checkfeastolfac", &checkfeastolfac) );
2126 SCIP_CALL( SCIPgetBoolParam(scip, "display/allviols", &dispallviols) );
2127
2128 /* scale feasibility tolerance by set->num_checkfeastolfac */
2129 if( !SCIPisEQ(scip, checkfeastolfac, 1.0) )
2130 {
2132 }
2133
2135
2136 /* restore old feasibilty tolerance */
2137 if( !SCIPisEQ(scip, checkfeastolfac, 1.0) )
2138 {
2140 }
2141
2142 if( !feasible )
2143 {
2144 SCIPmessagePrintInfo(scip->messagehdlr, "best solution is not feasible in original problem\n");
2145 }
2146 }
2147 }
2148 }
2149
2150 return SCIP_OKAY;
2151}
2152
2153/** calls compression based on the reoptimization structure after the presolving */
2154static
2156 SCIP* scip /**< global SCIP settings */
2157 )
2158{
2160 int c;
2161 int noldnodes;
2162 int nnewnodes;
2163
2165
2166 noldnodes = SCIPreoptGetNNodes(scip->reopt, scip->tree->root);
2167
2168 /* do not run if there exists only the root node */
2169 if( noldnodes <= 1 )
2170 return SCIP_OKAY;
2171
2172 /* do not run a tree compression if the problem contains (implicit) integer variables */
2173 if( scip->transprob->nintvars > 0 || scip->transprob->nimplvars > 0 )
2174 return SCIP_OKAY;
2175
2176 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2177 "tree compression:\n");
2178 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2179 " given tree has %d nodes.\n", noldnodes);
2180
2181 /* sort compressions by priority */
2182 SCIPsetSortComprs(scip->set);
2183
2184 for(c = 0; c < scip->set->ncomprs; c++)
2185 {
2187
2188 /* call tree compression technique */
2189 SCIP_CALL( SCIPcomprExec(scip->set->comprs[c], scip->set, scip->reopt, &result) );
2190
2191 if( result == SCIP_SUCCESS )
2192 {
2193 nnewnodes = SCIPreoptGetNNodes(scip->reopt, scip->tree->root);
2194 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2195 " <%s> compressed the search tree to %d nodes (rate %g).\n", SCIPcomprGetName(scip->set->comprs[c]),
2196 nnewnodes, ((SCIP_Real)nnewnodes)/noldnodes);
2197
2198 break;
2199 }
2200 }
2201
2202 if( result != SCIP_SUCCESS )
2203 {
2205 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2206 " search tree could not be compressed.\n");
2207 }
2208
2209 return SCIP_OKAY;
2210}
2211
2212/* prepare all plugins and data structures for a reoptimization run */
2213static
2215 SCIP* scip /**< SCIP data structure */
2216 )
2217{
2218 SCIP_Bool reoptrestart;
2219
2220 assert(scip != NULL);
2221 assert(scip->set->reopt_enable);
2222
2223 /* @ todo: we could check if the problem is feasible, eg, by backtracking */
2224
2225 /* increase number of reopt_runs */
2226 ++scip->stat->nreoptruns;
2227
2228 /* inform the reoptimization plugin that a new iteration starts */
2229 SCIP_CALL( SCIPreoptAddRun(scip->reopt, scip->set, scip->mem->probmem, scip->origprob->vars,
2230 scip->origprob->nvars, scip->set->limit_maxsol) );
2231
2232 /* check whether we need to add globally valid constraints */
2233 if( scip->set->reopt_sepaglbinfsubtrees || scip->set->reopt_sepabestsol )
2234 {
2235 SCIP_CALL( SCIPreoptApplyGlbConss(scip, scip->reopt, scip->set, scip->stat, scip->mem->probmem) );
2236 }
2237
2238 /* after presolving the problem the first time we remember all global bounds and active constraints. bounds and
2239 * constraints will be restored within SCIPreoptInstallBounds() and SCIPreoptResetActiveConss().
2240 */
2241 if( scip->stat->nreoptruns == 1 )
2242 {
2243 assert(scip->set->stage == SCIP_STAGE_PRESOLVED || scip->set->stage == SCIP_STAGE_SOLVED);
2244
2245 SCIP_CALL( SCIPreoptSaveGlobalBounds(scip->reopt, scip->transprob, scip->mem->probmem) );
2246
2247 SCIP_CALL( SCIPreoptSaveActiveConss(scip->reopt, scip->set, scip->transprob, scip->mem->probmem) );
2248 }
2249 /* we are at least in the second run */
2250 else
2251 {
2252 assert(scip->transprob != NULL);
2253
2254 SCIP_CALL( SCIPreoptMergeVarHistory(scip->reopt, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) );
2255
2256 SCIP_CALL( SCIPrelaxationCreate(&scip->relaxation, scip->mem->probmem, scip->set, scip->stat, scip->primal,
2257 scip->tree) );
2258
2259 /* mark statistics before solving */
2260 SCIPstatMark(scip->stat);
2261
2262 SCIPbranchcandInvalidate(scip->branchcand);
2263
2264 SCIP_CALL( SCIPreoptResetActiveConss(scip->reopt, scip->set, scip->stat) );
2265
2266 /* check whether we want to restart the tree search */
2267 SCIP_CALL( SCIPreoptCheckRestart(scip->reopt, scip->set, scip->mem->probmem, NULL, scip->transprob->vars,
2268 scip->transprob->nvars, &reoptrestart) );
2269
2270 /* call initialization methods of plugins */
2271 SCIP_CALL( SCIPsetInitPlugins(scip->set, scip->mem->probmem, scip->stat) );
2272
2273 /* install globally valid lower and upper bounds */
2274 SCIP_CALL( SCIPreoptInstallBounds(scip->reopt, scip->set, scip->stat, scip->transprob, scip->lp, scip->branchcand,
2275 scip->eventqueue, scip->cliquetable, scip->mem->probmem) );
2276
2277 /* check, whether objective value is always integral by inspecting the problem, if it is the case adjust the
2278 * cutoff bound if primal solution is already known
2279 */
2280 SCIP_CALL( SCIPprobCheckObjIntegral(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat,
2281 scip->primal, scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
2282
2283 /* if possible, scale objective function such that it becomes integral with gcd 1 */
2284 SCIP_CALL( SCIPprobScaleObj(scip->transprob, scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->primal,
2285 scip->tree, scip->reopt, scip->lp, scip->eventfilter, scip->eventqueue) );
2286
2288 }
2289
2290 /* try to compress the search tree */
2291 if( scip->set->compr_enable )
2292 {
2294 }
2295
2296 return SCIP_OKAY;
2297}
2298
2299/** transforms and presolves problem
2300 *
2301 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2302 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2303 *
2304 * @pre This method can be called if @p scip is in one of the following stages:
2305 * - \ref SCIP_STAGE_PROBLEM
2306 * - \ref SCIP_STAGE_TRANSFORMED
2307 * - \ref SCIP_STAGE_PRESOLVING
2308 * - \ref SCIP_STAGE_PRESOLVED
2309 * - \ref SCIP_STAGE_SOLVED
2310 *
2311 * @post After calling this method \SCIP reaches one of the following stages:
2312 * - \ref SCIP_STAGE_PRESOLVING if the presolving process was interrupted
2313 * - \ref SCIP_STAGE_PRESOLVED if the presolving process was finished and did not solve the problem
2314 * - \ref SCIP_STAGE_SOLVED if the problem was solved during presolving
2315 *
2316 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2317 */
2319 SCIP* scip /**< SCIP data structure */
2320 )
2321{
2322 SCIP_Bool unbounded;
2323 SCIP_Bool infeasible;
2324 SCIP_Bool vanished;
2325 SCIP_RETCODE retcode;
2326
2328
2329 /* start solving timer */
2330 SCIPclockStart(scip->stat->solvingtime, scip->set);
2331 SCIPclockStart(scip->stat->solvingtimeoverall, scip->set);
2332
2333 /* capture the CTRL-C interrupt */
2334 if( scip->set->misc_catchctrlc )
2335 SCIPinterruptCapture(scip->interrupt);
2336
2337 /* reset the user interrupt flag */
2338 scip->stat->userinterrupt = FALSE;
2340
2341 switch( scip->set->stage )
2342 {
2343 case SCIP_STAGE_PROBLEM:
2344 /* initialize solving data structures and transform problem */
2345 retcode = SCIPtransformProb(scip);
2346 if( retcode != SCIP_OKAY )
2347 {
2349 return retcode;
2350 }
2351
2352 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
2353
2354 /*lint -fallthrough*/
2355
2358 /* presolve problem */
2359 SCIP_CALL( presolve(scip, &unbounded, &infeasible, &vanished) );
2360 assert(scip->set->stage == SCIP_STAGE_PRESOLVED || scip->set->stage == SCIP_STAGE_PRESOLVING);
2361
2362 if( infeasible || unbounded || vanished )
2363 {
2364 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
2365
2366 /* initialize solving process data structures to be able to switch to SOLVED stage */
2368
2369 /* switch stage to SOLVED */
2370 scip->set->stage = SCIP_STAGE_SOLVED;
2371
2372 /* print solution message */
2373 switch( scip->stat->status )/*lint --e{788}*/
2374 {
2376 /* remove the root node from the tree, s.t. the lower bound is set to +infinity ???????????? (see initSolve())*/
2377 SCIP_CALL( SCIPtreeClear(scip->tree, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, scip->eventqueue, scip->lp) );
2378 break;
2379
2381 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2382 "presolving detected infeasibility\n");
2383 break;
2384
2386 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2387 "presolving detected unboundedness\n");
2388 break;
2389
2391 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2392 "presolving detected unboundedness (or infeasibility)\n");
2393 break;
2394
2395 default:
2396 /* note that this is in an internal SCIP error since the status is corrupted */
2397 SCIPerrorMessage("invalid SCIP status <%d>\n", scip->stat->status);
2398 SCIPABORT();
2399 return SCIP_ERROR; /*lint !e527*/
2400 }
2401 }
2402 else if( scip->set->stage == SCIP_STAGE_PRESOLVED )
2403 {
2404 int h;
2405
2406 /* print presolved problem statistics */
2407 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
2408 "presolved problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
2409 scip->transprob->nvars, scip->transprob->nbinvars, scip->transprob->nintvars, scip->transprob->nimplvars,
2410 scip->transprob->ncontvars, scip->transprob->nconss);
2411
2412 for( h = 0; h < scip->set->nconshdlrs; ++h )
2413 {
2414 int nactiveconss;
2415
2416 nactiveconss = SCIPconshdlrGetNActiveConss(scip->set->conshdlrs[h]);
2417 if( nactiveconss > 0 )
2418 {
2419 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2420 "%7d constraints of type <%s>\n", nactiveconss, SCIPconshdlrGetName(scip->set->conshdlrs[h]));
2421 }
2422 }
2423
2424 if( SCIPprobIsObjIntegral(scip->transprob) )
2425 {
2426 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2427 "transformed objective value is always integral (scale: %.15g)\n", scip->transprob->objscale);
2428 }
2429 }
2430 else
2431 {
2432 assert(scip->set->stage == SCIP_STAGE_PRESOLVING);
2433 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "presolving was interrupted.\n");
2434 }
2435
2436 /* display timing statistics */
2437 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
2438 "Presolving Time: %.2f\n", SCIPclockGetTime(scip->stat->presolvingtime));
2439 break;
2440
2442 case SCIP_STAGE_SOLVED:
2443 break;
2444
2445 default:
2446 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2447 return SCIP_INVALIDCALL;
2448 } /*lint !e788*/
2449
2450 /* release the CTRL-C interrupt */
2451 if( scip->set->misc_catchctrlc )
2452 SCIPinterruptRelease(scip->interrupt);
2453
2454 /* stop solving timer */
2455 SCIPclockStop(scip->stat->solvingtime, scip->set);
2456 SCIPclockStop(scip->stat->solvingtimeoverall, scip->set);
2457
2458 if( scip->set->stage == SCIP_STAGE_SOLVED )
2459 {
2460 /* display most relevant statistics */
2462 }
2463
2464 return SCIP_OKAY;
2465}
2466
2467/** transforms, presolves, and solves problem
2468 *
2469 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2470 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2471 *
2472 * @pre This method can be called if @p scip is in one of the following stages:
2473 * - \ref SCIP_STAGE_PROBLEM
2474 * - \ref SCIP_STAGE_TRANSFORMED
2475 * - \ref SCIP_STAGE_PRESOLVING
2476 * - \ref SCIP_STAGE_PRESOLVED
2477 * - \ref SCIP_STAGE_SOLVING
2478 * - \ref SCIP_STAGE_SOLVED
2479 *
2480 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2481 * process was interrupted:
2482 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2483 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2484 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2485 *
2486 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2487 */
2489 SCIP* scip /**< SCIP data structure */
2490 )
2491{
2492 SCIP_Longint cutpoolncutsfoundbeforerestart = 0;
2493 SCIP_Longint cutpoolncutsaddedbeforerestart = 0;
2494 SCIP_Longint cutpoolncallsbeforerestart = 0;
2495 SCIP_Longint cutpoolnrootcallsbeforerestart = 0;
2496 SCIP_Longint cutpoolmaxncutsbeforerestart = 0;
2497 SCIP_Real cutpooltimebeforerestart = 0;
2498 SCIP_Bool statsprinted = FALSE;
2499 SCIP_Bool restart;
2500 SCIP_Bool transferstatistics = FALSE;
2501
2503
2504 /* if the stage is already SCIP_STAGE_SOLVED do nothing */
2505 if( scip->set->stage == SCIP_STAGE_SOLVED )
2506 return SCIP_OKAY;
2507
2508 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 )
2509 {
2510 SCIPwarningMessage(scip, "SCIPsolve() was called, but problem is already solved\n");
2511 return SCIP_OKAY;
2512 }
2513
2514 /* check, if a node selector exists */
2515 if( SCIPsetGetNodesel(scip->set, scip->stat) == NULL )
2516 {
2517 SCIPerrorMessage("no node selector available\n");
2518 return SCIP_PLUGINNOTFOUND;
2519 }
2520
2521 /* check, if an integrality constraint handler exists if there are integral variables */
2522 if( (SCIPgetNBinVars(scip) >= 0 || SCIPgetNIntVars(scip) >= 0) && SCIPfindConshdlr(scip, "integral") == NULL )
2523 {
2524 SCIPwarningMessage(scip, "integrality constraint handler not available\n");
2525 }
2526
2527 /* initialize presolving flag (may be modified in SCIPpresolve()) */
2528 scip->stat->performpresol = FALSE;
2529
2530 /* if a decomposition exists and Benders' decomposition has been enabled, then a decomposition is performed */
2531 if( scip->set->stage == SCIP_STAGE_PROBLEM && SCIPdecompstoreGetNOrigDecomps(scip->decompstore) > 0
2532 && scip->set->decomp_applybenders && SCIPgetNActiveBenders(scip) == 0 )
2533 {
2534 int decompindex = 0;
2535
2536 /* applying the Benders' decomposition */
2538 }
2539
2540 /* start solving timer */
2541 SCIPclockStart(scip->stat->solvingtime, scip->set);
2542 SCIPclockStart(scip->stat->solvingtimeoverall, scip->set);
2543
2544 /* capture the CTRL-C interrupt */
2545 if( scip->set->misc_catchctrlc )
2546 SCIPinterruptCapture(scip->interrupt);
2547
2548 /* reset the user interrupt flag */
2549 scip->stat->userinterrupt = FALSE;
2551
2552 /* automatic restarting loop */
2553 restart = scip->stat->userrestart;
2554
2555 do
2556 {
2557 if( restart )
2558 {
2566
2567 /* free the solving process data in order to restart */
2568 assert(scip->set->stage == SCIP_STAGE_SOLVING);
2569 if( scip->stat->userrestart )
2571 "(run %d, node %" SCIP_LONGINT_FORMAT ") performing user restart\n",
2572 scip->stat->nruns, scip->stat->nnodes);
2573 else
2575 "(run %d, node %" SCIP_LONGINT_FORMAT ") restarting after %d global fixings of integer variables\n",
2576 scip->stat->nruns, scip->stat->nnodes, scip->stat->nrootintfixingsrun);
2577 /* an extra blank line should be printed separately since the buffer message handler only handles up to one line
2578 * correctly */
2580 /* reset relaxation solution, so that the objective value is recomputed from scratch next time, using the new
2581 * fixings which may be produced during the presolving after the restart */
2583
2585 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
2586 }
2587 restart = FALSE;
2588 scip->stat->userrestart = FALSE;
2589
2590 switch( scip->set->stage )
2591 {
2592 case SCIP_STAGE_PROBLEM:
2595 /* initialize solving data structures, transform and problem */
2596
2598 /* remember that we already printed the relevant statistics */
2599 if( scip->set->stage == SCIP_STAGE_SOLVED )
2601
2602 if( scip->set->stage == SCIP_STAGE_SOLVED || scip->set->stage == SCIP_STAGE_PRESOLVING )
2603 {
2604 if ( scip->set->reopt_enable )
2605 {
2607 }
2608 break;
2609 }
2610 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
2611
2612 /* abort if a node limit was reached */
2613 if( SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
2614 break;
2615 /*lint -fallthrough*/
2616
2618 /* check if reoptimization is enabled and global constraints are saved */
2619 if( scip->set->reopt_enable )
2620 {
2622 }
2623
2624 /* initialize solving process data structures */
2626 assert(scip->set->stage == SCIP_STAGE_SOLVING);
2627 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL, "\n");
2628
2629 /*lint -fallthrough*/
2630
2631 case SCIP_STAGE_SOLVING:
2632 /* reset display */
2634
2635 /* remember cutpool statistics after restart */
2636 if( transferstatistics )
2637 {
2644 }
2645
2646 /* continue solution process */
2647 SCIP_CALL( SCIPsolveCIP(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->mem, scip->origprob, scip->transprob,
2648 scip->primal, scip->tree, scip->reopt, scip->lp, scip->relaxation, scip->pricestore, scip->sepastore,
2649 scip->cutpool, scip->delayedcutpool, scip->branchcand, scip->conflict, scip->conflictstore,
2650 scip->eventfilter, scip->eventqueue, scip->cliquetable, &restart) );
2651
2652 /* detect, whether problem is solved */
2653 if( SCIPtreeGetNNodes(scip->tree) == 0 && SCIPtreeGetCurrentNode(scip->tree) == NULL )
2654 {
2655 assert(scip->stat->status == SCIP_STATUS_OPTIMAL
2656 || scip->stat->status == SCIP_STATUS_INFEASIBLE
2657 || scip->stat->status == SCIP_STATUS_UNBOUNDED
2658 || scip->stat->status == SCIP_STATUS_INFORUNBD);
2659 assert(!restart);
2660
2661 /* tree is empty, and no current node exists -> problem is solved */
2662 scip->set->stage = SCIP_STAGE_SOLVED;
2663 }
2664 break;
2665
2666 case SCIP_STAGE_SOLVED:
2667 assert(scip->stat->status == SCIP_STATUS_OPTIMAL
2668 || scip->stat->status == SCIP_STATUS_INFEASIBLE
2669 || scip->stat->status == SCIP_STATUS_UNBOUNDED
2670 || scip->stat->status == SCIP_STATUS_INFORUNBD);
2671
2672 break;
2673
2674 default:
2675 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2676 return SCIP_INVALIDCALL;
2677 } /*lint !e788*/
2678 }
2679 while( restart && !SCIPsolveIsStopped(scip->set, scip->stat, TRUE) );
2680
2681 /* we have to store all unprocessed nodes if reoptimization is enabled */
2682 if( scip->set->reopt_enable && scip->set->stage != SCIP_STAGE_PRESOLVING
2683 && SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
2684 {
2685 /* save unprocessed nodes */
2686 if( SCIPgetNNodesLeft(scip) > 0 )
2687 {
2688 SCIP_NODE** leaves;
2689 SCIP_NODE** children;
2690 SCIP_NODE** siblings;
2691 int nleaves;
2692 int nchildren;
2693 int nsiblings;
2694
2695 /* get all open leave nodes */
2696 SCIP_CALL( SCIPgetLeaves(scip, &leaves, &nleaves) );
2697
2698 /* get all open children nodes */
2699 SCIP_CALL( SCIPgetChildren(scip, &children, &nchildren) );
2700
2701 /* get all open sibling nodes */
2702 SCIP_CALL( SCIPgetSiblings(scip, &siblings, &nsiblings) );
2703
2704 /* add all open node to the reoptimization tree */
2705 SCIP_CALL( SCIPreoptSaveOpenNodes(scip->reopt, scip->set, scip->lp, scip->mem->probmem, leaves, nleaves,
2706 children, nchildren, siblings, nsiblings) );
2707 }
2708 }
2709
2710 /* release the CTRL-C interrupt */
2711 if( scip->set->misc_catchctrlc )
2712 SCIPinterruptRelease(scip->interrupt);
2713
2714 if( scip->set->reopt_enable )
2715 {
2716 /* save found solutions */
2717 int nsols;
2718 int s;
2719
2720 nsols = scip->set->reopt_savesols == -1 ? INT_MAX : MAX(scip->set->reopt_savesols, 1);
2721 nsols = MIN(scip->primal->nsols, nsols);
2722
2723 for( s = 0; s < nsols; s++ )
2724 {
2725 SCIP_SOL* sol;
2726 SCIP_Bool added;
2727
2728 sol = scip->primal->sols[s];
2729 assert(sol != NULL);
2730
2731 if( !SCIPsolIsOriginal(sol) )
2732 {
2733 SCIP_Bool hasinfval;
2734
2735 /* retransform solution into the original problem space */
2736 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
2737 }
2738
2739 if( SCIPsolGetNodenum(sol) > 0 || SCIPsolGetHeur(sol) != NULL || (s == 0 && scip->set->reopt_sepabestsol) )
2740 {
2741 /* if the best solution should be separated, we must not store it in the solution tree */
2742 if( s == 0 && scip->set->reopt_sepabestsol )
2743 {
2744 SCIP_CALL( SCIPreoptAddOptSol(scip->reopt, sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal,
2745 scip->origprob->vars, scip->origprob->nvars) );
2746 }
2747 /* add solution to solution tree */
2748 else
2749 {
2750 SCIPdebugMsg(scip, "try to add solution to the solution tree:\n");
2751 SCIPdebug( SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, \
2752 scip->transprob, NULL, FALSE, FALSE) ); );
2753
2754 SCIP_CALL( SCIPreoptAddSol(scip->reopt, scip->set, scip->stat, scip->origprimal, scip->mem->probmem,
2755 sol, s == 0, &added, scip->origprob->vars, scip->origprob->nvars, scip->stat->nreoptruns) );
2756 }
2757 }
2758 }
2759
2760 SCIPdebugMsg(scip, "-> saved %d solution.\n", nsols);
2761
2762 /* store variable history */
2763 if( scip->set->reopt_storevarhistory )
2764 {
2765 SCIP_CALL( SCIPreoptUpdateVarHistory(scip->reopt, scip->set, scip->stat, scip->mem->probmem,
2766 scip->origprob->vars, scip->origprob->nvars) );
2767 }
2768 }
2769
2770 /* stop solving timer */
2771 SCIPclockStop(scip->stat->solvingtime, scip->set);
2772 SCIPclockStop(scip->stat->solvingtimeoverall, scip->set);
2773
2774 /* decrease time limit during reoptimization */
2775 if( scip->set->reopt_enable && scip->set->reopt_commontimelimit )
2776 {
2777 SCIP_Real timelimit;
2778 SCIP_Real usedtime;
2779
2780 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
2782 timelimit = timelimit - usedtime;
2783 timelimit = MAX(0, timelimit);
2784
2785 SCIP_CALL( SCIPsetRealParam(scip, "limits/time", timelimit) );
2786 }
2787
2788 if( !statsprinted )
2789 {
2790 /* display most relevant statistics */
2792 }
2793
2794 return SCIP_OKAY;
2795}
2796
2797/** transforms, presolves, and solves problem using the configured concurrent solvers
2798 *
2799 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2800 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2801 *
2802 * @pre This method can be called if @p scip is in one of the following stages:
2803 * - \ref SCIP_STAGE_PROBLEM
2804 * - \ref SCIP_STAGE_TRANSFORMED
2805 * - \ref SCIP_STAGE_PRESOLVING
2806 * - \ref SCIP_STAGE_PRESOLVED
2807 * - \ref SCIP_STAGE_SOLVING
2808 * - \ref SCIP_STAGE_SOLVED
2809 *
2810 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2811 * process was interrupted:
2812 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2813 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2814 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2815 *
2816 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2817 *
2818 * @deprecated Please use SCIPsolveConcurrent() instead.
2819 */
2821 SCIP* scip /**< SCIP data structure */
2822 )
2823{
2824 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveParallel", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2825
2826 return SCIPsolveConcurrent(scip);
2827}
2828
2829/** transforms, presolves, and solves problem using the configured concurrent solvers
2830 *
2831 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2832 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2833 *
2834 * @pre This method can be called if @p scip is in one of the following stages:
2835 * - \ref SCIP_STAGE_PROBLEM
2836 * - \ref SCIP_STAGE_TRANSFORMED
2837 * - \ref SCIP_STAGE_PRESOLVING
2838 * - \ref SCIP_STAGE_PRESOLVED
2839 * - \ref SCIP_STAGE_SOLVING
2840 * - \ref SCIP_STAGE_SOLVED
2841 *
2842 * @post After calling this method \SCIP reaches one of the following stages depending on if and when the solution
2843 * process was interrupted:
2844 * - \ref SCIP_STAGE_PRESOLVING if the solution process was interrupted during presolving
2845 * - \ref SCIP_STAGE_SOLVING if the solution process was interrupted during the tree search
2846 * - \ref SCIP_STAGE_SOLVED if the solving process was not interrupted
2847 *
2848 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
2849 */
2851 SCIP* scip /**< SCIP data structure */
2852 )
2853{
2854#ifdef TPI_NONE
2855 SCIPinfoMessage(scip, NULL, "SCIP was compiled without task processing interface. Parallel solve not possible\n");
2856 return SCIP_OKAY;
2857#else
2858 SCIP_RETCODE retcode;
2859 int i;
2861 int minnthreads;
2862 int maxnthreads;
2863
2864 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveConcurrent", FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2865
2866 SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", SCIP_CLOCKTYPE_WALL) );
2867
2868 minnthreads = scip->set->parallel_minnthreads;
2869 maxnthreads = scip->set->parallel_maxnthreads;
2870
2871 if( minnthreads > maxnthreads )
2872 {
2873 SCIPerrorMessage("minimum number of threads greater than maximum number of threads\n");
2874 return SCIP_INVALIDDATA;
2875 }
2876 if( scip->concurrent == NULL )
2877 {
2878 int nconcsolvertypes;
2879 SCIP_CONCSOLVERTYPE** concsolvertypes;
2880 SCIP_Longint nthreads;
2881 SCIP_Real memorylimit;
2882 int* solvertypes;
2883 SCIP_Longint* weights;
2884 SCIP_Real* prios;
2885 int ncandsolvertypes;
2886 SCIP_Real prefpriosum;
2887
2888 /* check if concurrent solve is configured to presolve the problem
2889 * before setting up the concurrent solvers
2890 */
2891 if( scip->set->concurrent_presolvebefore )
2892 {
2893 /* if yes, then presolve the problem */
2896 return SCIP_OKAY;
2897 }
2898 else
2899 {
2900 SCIP_Bool infeas;
2901
2902 /* if not, transform the problem and switch stage to presolved */
2906 assert(!infeas);
2907 }
2908
2909 /* the presolving must have run into a limit, so we stop here */
2910 if( scip->set->stage < SCIP_STAGE_PRESOLVED )
2911 {
2913 return SCIP_OKAY;
2914 }
2915
2916 nthreads = INT_MAX;
2917 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
2918 memorylimit = scip->set->limit_memory;
2919 if( memorylimit < SCIP_MEM_NOLIMIT )
2920 {
2921 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
2922 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
2923 /* estimate maximum number of copies that be created based on memory limit */
2924 if( !scip->set->misc_avoidmemout )
2925 {
2926 nthreads = MAX(1, memorylimit / (4.0*SCIPgetMemExternEstim(scip)/1048576.0));
2927 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "estimated a maximum of %lli threads based on memory limit\n", nthreads);
2928 }
2929 else
2930 {
2931 nthreads = minnthreads;
2932 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "ignoring memory limit; all threads can be created\n");
2933 }
2934 }
2935 nconcsolvertypes = SCIPgetNConcsolverTypes(scip);
2936 concsolvertypes = SCIPgetConcsolverTypes(scip);
2937
2938 if( minnthreads > nthreads )
2939 {
2941 scip->stat->status = SCIP_STATUS_MEMLIMIT;
2943 SCIPwarningMessage(scip, "requested minimum number of threads could not be satisfied with given memory limit\n");
2945 return SCIP_OKAY;
2946 }
2947
2948 if( nthreads == 1 )
2949 {
2950 SCIPwarningMessage(scip, "can only use 1 thread, doing sequential solve instead\n");
2952 return SCIPsolve(scip);
2953 }
2954 nthreads = MIN(nthreads, maxnthreads);
2955 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "using %lli threads for concurrent solve\n", nthreads);
2956
2957 /* now set up nthreads many concurrent solvers that will be used for the concurrent solve
2958 * using the preferred priorities of each concurrent solver
2959 */
2960 prefpriosum = 0.0;
2961 for( i = 0; i < nconcsolvertypes; ++i )
2962 prefpriosum += SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]);
2963
2964 ncandsolvertypes = 0;
2965 SCIP_CALL( SCIPallocBufferArray(scip, &solvertypes, nthreads + nconcsolvertypes) );
2966 SCIP_CALL( SCIPallocBufferArray(scip, &weights, nthreads + nconcsolvertypes) );
2967 SCIP_CALL( SCIPallocBufferArray(scip, &prios, nthreads + nconcsolvertypes) );
2968 for( i = 0; i < nconcsolvertypes; ++i )
2969 {
2970 int j;
2971 SCIP_Real prio;
2972 prio = nthreads * SCIPconcsolverTypeGetPrefPrio(concsolvertypes[i]) / prefpriosum;
2973 while( prio > 0.0 )
2974 {
2975 j = ncandsolvertypes++;
2976 assert(j < 2*nthreads);
2977 weights[j] = 1;
2978 solvertypes[j] = i;
2979 prios[j] = MIN(1.0, prio);
2980 prio = prio - 1.0;
2981 }
2982 }
2983 /* select nthreads many concurrent solver types to create instances
2984 * according to the preferred prioriteis the user has set
2985 * This basically corresponds to a knapsack problem
2986 * with unit weights and capacity nthreads, where the profits are
2987 * the unrounded fraction of the total number of threads to be used.
2988 */
2990
2991 SCIP_CALL( SCIPcreateRandom(scip, &rndgen, (unsigned) scip->set->concurrent_initseed, TRUE) );
2992 for( i = 0; i < nthreads; ++i )
2993 {
2994 SCIP_CONCSOLVER* concsolver;
2995
2996 SCIP_CALL( SCIPconcsolverCreateInstance(scip->set, concsolvertypes[solvertypes[i]], &concsolver) );
2997 if( scip->set->concurrent_changeseeds && SCIPgetNConcurrentSolvers(scip) > 1 )
2999 }
3002 SCIPfreeBufferArray(scip, &weights);
3004
3006
3008 }
3009
3011 {
3012 /* switch stage to solving */
3014 }
3015
3016 SCIPclockStart(scip->stat->solvingtime, scip->set);
3017 retcode = SCIPconcurrentSolve(scip);
3018 SCIPclockStop(scip->stat->solvingtime, scip->set);
3020
3021 return retcode;
3022#endif
3023}
3024
3025/** include specific heuristics and branching rules for reoptimization
3026 *
3027 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3028 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3029 *
3030 * @pre This method can be called if @p scip is in one of the following stages:
3031 * - \ref SCIP_STAGE_PROBLEM
3032 */
3034 SCIP* scip, /**< SCIP data structure */
3035 SCIP_Bool enable /**< enable reoptimization (TRUE) or disable it (FALSE) */
3036 )
3037{
3038 assert(scip != NULL);
3039
3040 /* we want to skip if nothing has changed */
3041 if( (enable && scip->set->reopt_enable && scip->reopt != NULL)
3042 || (!enable && !scip->set->reopt_enable && scip->reopt == NULL) )
3043 return SCIP_OKAY;
3044
3045 /* check stage and throw an error if we try to disable reoptimization during the solving process.
3046 *
3047 * @note the case that we will disable the reoptimization and have already performed presolving can only happen if
3048 * we are try to solve a general MIP
3049 *
3050 * @note this fix is only for the bugfix release 3.2.1, in the next major release reoptimization can be used for
3051 * general MIPs, too.
3052 */
3053 if( scip->set->stage > SCIP_STAGE_PROBLEM && !(!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3054 {
3055 SCIPerrorMessage("Reoptimization cannot be %s after starting the (pre)solving process.\n", enable ? "enabled" : "disabled");
3056 return SCIP_INVALIDCALL;
3057 }
3058
3059 /* if the current stage is SCIP_STAGE_PROBLEM we have to include the heuristics and branching rule */
3060 if( scip->set->stage == SCIP_STAGE_PROBLEM || (!enable && scip->set->stage == SCIP_STAGE_PRESOLVED) )
3061 {
3062 /* initialize all reoptimization data structures */
3063 if( enable && scip->reopt == NULL )
3064 {
3065 /* set enable flag */
3066 scip->set->reopt_enable = enable;
3067
3068 SCIP_CALL( SCIPreoptCreate(&scip->reopt, scip->set, scip->mem->probmem) );
3069 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3070 }
3071 /* disable all reoptimization plugins and free the structure if necessary */
3072 else if( (!enable && scip->reopt != NULL) || (!enable && scip->set->reopt_enable && scip->reopt == NULL) )
3073 {
3074 /* set enable flag */
3075 scip->set->reopt_enable = enable;
3076
3077 if( scip->reopt != NULL )
3078 {
3079 SCIP_CALL( SCIPreoptFree(&(scip->reopt), scip->set, scip->origprimal, scip->mem->probmem) );
3080 assert(scip->reopt == NULL);
3081 }
3082 SCIP_CALL( SCIPsetSetReoptimizationParams(scip->set, scip->messagehdlr) );
3083 }
3084 }
3085 else
3086 {
3087 /* set enable flag */
3088 scip->set->reopt_enable = enable;
3089 }
3090
3091 return SCIP_OKAY;
3092}
3093
3094/** save bound change based on dual information in the reoptimization tree
3095 *
3096 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3097 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3098 *
3099 * @pre This method can be called if @p scip is in one of the following stages:
3100 * - \ref SCIP_STAGE_SOLVING
3101 * - \ref SCIP_STAGE_SOLVED
3102 */
3104 SCIP* scip, /**< SCIP data structure */
3105 SCIP_NODE* node, /**< node of the search tree */
3106 SCIP_VAR* var, /**< variable whose bound changed */
3107 SCIP_Real newbound, /**< new bound of the variable */
3108 SCIP_Real oldbound /**< old bound of the variable */
3109 )
3110{
3111 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddReoptDualBndchg", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3112
3113 assert(SCIPsetIsFeasLT(scip->set, newbound, oldbound) || SCIPsetIsFeasGT(scip->set, newbound, oldbound));
3114
3115 SCIP_CALL( SCIPreoptAddDualBndchg(scip->reopt, scip->set, scip->mem->probmem, node, var, newbound, oldbound) );
3116
3117 return SCIP_OKAY;
3118}
3119
3120/** returns the optimal solution of the last iteration or NULL of none exists */
3122 SCIP* scip /**< SCIP data structure */
3123 )
3124{
3125 SCIP_SOL* sol;
3126
3127 assert(scip != NULL);
3128
3129 sol = NULL;
3130
3131 if( scip->set->reopt_enable && scip->stat->nreoptruns > 1 )
3132 {
3134 }
3135
3136 return sol;
3137}
3138
3139/** returns the objective coefficent of a given variable in a previous iteration
3140 *
3141 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3142 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3143 *
3144 * @pre This method can be called if @p scip is in one of the following stages:
3145 * - \ref SCIP_STAGE_PRESOLVING
3146 * - \ref SCIP_STAGE_SOLVING
3147 */
3149 SCIP* scip, /**< SCIP data structure */
3150 SCIP_VAR* var, /**< variable */
3151 int run, /**< number of the run */
3152 SCIP_Real* objcoef /**< pointer to store the objective coefficient */
3153 )
3154{
3155 assert(scip != NULL);
3156 assert(var != NULL);
3157 assert(0 < run && run <= scip->stat->nreoptruns);
3158
3159 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetReoptOldObjCoef", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3160
3161 if( SCIPvarIsOriginal(var) )
3163 else
3164 {
3166 SCIP_Real constant;
3167 SCIP_Real scalar;
3168
3170
3171 origvar = var;
3172 constant = 0.0;
3173 scalar = 1.0;
3174
3175 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
3176 assert(origvar != NULL);
3178
3180 }
3181 return SCIP_OKAY;
3182}
3183
3184/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3185 * preserved
3186 *
3187 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3188 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3189 *
3190 * @pre This method can be called if @p scip is in one of the following stages:
3191 * - \ref SCIP_STAGE_INIT
3192 * - \ref SCIP_STAGE_PROBLEM
3193 * - \ref SCIP_STAGE_TRANSFORMED
3194 * - \ref SCIP_STAGE_PRESOLVING
3195 * - \ref SCIP_STAGE_PRESOLVED
3196 * - \ref SCIP_STAGE_SOLVING
3197 * - \ref SCIP_STAGE_SOLVED
3198 *
3199 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT or \ref SCIP_STAGE_PROBLEM, the stage of
3200 * \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_TRANSFORMED
3201 *
3202 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3203 */
3205 SCIP* scip, /**< SCIP data structure */
3206 SCIP_Bool restart /**< should certain data be preserved for improved restarting? */
3207 )
3208{
3210
3211 switch( scip->set->stage )
3212 {
3213 case SCIP_STAGE_INIT:
3215 case SCIP_STAGE_PROBLEM:
3216 return SCIP_OKAY;
3217
3219 {
3220 SCIP_Bool infeasible;
3221
3222 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3223 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3224 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3225 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3226
3227 /* exit presolving */
3228 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3229 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3230 }
3231
3232 /*lint -fallthrough*/
3234 /* switch stage to TRANSFORMED */
3235 scip->set->stage = SCIP_STAGE_TRANSFORMED;
3236 return SCIP_OKAY;
3237
3238 case SCIP_STAGE_SOLVING:
3239 case SCIP_STAGE_SOLVED:
3240 /* free solution process data structures */
3241 SCIP_CALL( freeSolve(scip, restart) );
3242 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3243 return SCIP_OKAY;
3244
3245 default:
3246 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3247 return SCIP_INVALIDCALL;
3248 } /*lint !e788*/
3249}
3250
3251/** frees branch and bound tree and all solution process data; statistics, presolving data and transformed problem is
3252 * preserved
3253 *
3254 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3255 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3256 *
3257 * @pre This method can be called if @p scip is in one of the following stages:
3258 * - \ref SCIP_STAGE_INIT
3259 * - \ref SCIP_STAGE_PROBLEM
3260 * - \ref SCIP_STAGE_TRANSFORMED
3261 * - \ref SCIP_STAGE_PRESOLVING
3262 * - \ref SCIP_STAGE_PRESOLVED
3263 * - \ref SCIP_STAGE_SOLVING
3264 * - \ref SCIP_STAGE_SOLVED
3265 *
3266 * @post If this method is called in \SCIP stage \ref SCIP_STAGE_INIT, \ref SCIP_STAGE_TRANSFORMED or \ref SCIP_STAGE_PROBLEM,
3267 * the stage of \SCIP is not changed; otherwise, the \SCIP stage is changed to \ref SCIP_STAGE_PRESOLVED.
3268 *
3269 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3270 */
3272 SCIP* scip /**< SCIP data structure */
3273 )
3274{
3275 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeReoptSolve", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3276
3277 switch( scip->set->stage )
3278 {
3279 case SCIP_STAGE_INIT:
3282 case SCIP_STAGE_PROBLEM:
3283 return SCIP_OKAY;
3284
3286 {
3287 SCIP_Bool infeasible;
3288
3289 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3290 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3291 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3292 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3293
3294 /* exit presolving */
3295 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3296 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3297
3298 return SCIP_OKAY;
3299 }
3300
3301 case SCIP_STAGE_SOLVING:
3302 case SCIP_STAGE_SOLVED:
3303 /* free solution process data structures */
3305 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3306 return SCIP_OKAY;
3307
3308 default:
3309 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3310 return SCIP_INVALIDCALL;
3311 } /*lint !e788*/
3312}
3313
3314/** frees all solution process data including presolving and transformed problem, only original problem is kept
3315 *
3316 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3317 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3318 *
3319 * @pre This method can be called if @p scip is in one of the following stages:
3320 * - \ref SCIP_STAGE_INIT
3321 * - \ref SCIP_STAGE_PROBLEM
3322 * - \ref SCIP_STAGE_TRANSFORMED
3323 * - \ref SCIP_STAGE_PRESOLVING
3324 * - \ref SCIP_STAGE_PRESOLVED
3325 * - \ref SCIP_STAGE_SOLVING
3326 * - \ref SCIP_STAGE_SOLVED
3327 *
3328 * @post After calling this method \SCIP reaches one of the following stages:
3329 * - \ref SCIP_STAGE_INIT if the method was called from \SCIP stage \ref SCIP_STAGE_INIT
3330 * - \ref SCIP_STAGE_PROBLEM if the method was called from any other of the allowed stages
3331 *
3332 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3333 */
3335 SCIP* scip /**< SCIP data structure */
3336 )
3337{
3338 assert(scip != NULL);
3339
3340 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeTransform", TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3341
3342 /* release variables and constraints captured by reoptimization */
3343 if( scip->reopt != NULL )
3344 {
3345 SCIP_CALL( SCIPreoptReleaseData(scip->reopt, scip->set, scip->mem->probmem) );
3346 }
3347
3348 switch( scip->set->stage )
3349 {
3350 case SCIP_STAGE_INIT:
3351 case SCIP_STAGE_PROBLEM:
3352 return SCIP_OKAY;
3353
3355 {
3356 SCIP_Bool infeasible;
3357
3358 assert(scip->stat->status != SCIP_STATUS_INFEASIBLE);
3359 assert(scip->stat->status != SCIP_STATUS_INFORUNBD);
3360 assert(scip->stat->status != SCIP_STATUS_UNBOUNDED);
3361 assert(scip->stat->status != SCIP_STATUS_OPTIMAL);
3362
3363 /* exit presolving */
3364 SCIP_CALL( exitPresolve(scip, FALSE, &infeasible) );
3365 assert(scip->set->stage == SCIP_STAGE_PRESOLVED);
3366 }
3367
3368 /*lint -fallthrough*/
3370 case SCIP_STAGE_SOLVING:
3371 case SCIP_STAGE_SOLVED:
3372 /* the solve was already freed, we directly go to freeTransform() */
3373 if( !scip->set->reopt_enable || scip->set->stage != SCIP_STAGE_PRESOLVED )
3374 {
3375 /* free solution process data */
3377 assert(scip->set->stage == SCIP_STAGE_TRANSFORMED);
3378 }
3379 /*lint -fallthrough*/
3380
3382 /* free transformed problem data structures */
3384 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3385 return SCIP_OKAY;
3386
3388 assert(scip->set->stage == SCIP_STAGE_TRANSFORMING);
3390 assert(scip->set->stage == SCIP_STAGE_PROBLEM);
3391 return SCIP_OKAY;
3392
3393 default:
3394 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3395 return SCIP_INVALIDCALL;
3396 } /*lint !e788*/
3397}
3398
3399/** informs \SCIP that the solving process should be interrupted as soon as possible (e.g., after the current node has
3400 * been solved)
3401 *
3402 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3403 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3404 *
3405 * @pre This method can be called if @p scip is in one of the following stages:
3406 * - \ref SCIP_STAGE_PROBLEM
3407 * - \ref SCIP_STAGE_TRANSFORMING
3408 * - \ref SCIP_STAGE_TRANSFORMED
3409 * - \ref SCIP_STAGE_INITPRESOLVE
3410 * - \ref SCIP_STAGE_PRESOLVING
3411 * - \ref SCIP_STAGE_EXITPRESOLVE
3412 * - \ref SCIP_STAGE_PRESOLVED
3413 * - \ref SCIP_STAGE_SOLVING
3414 * - \ref SCIP_STAGE_SOLVED
3415 * - \ref SCIP_STAGE_EXITSOLVE
3416 * - \ref SCIP_STAGE_FREETRANS
3417 *
3418 * @note the \SCIP stage does not get changed
3419 */
3421 SCIP* scip /**< SCIP data structure */
3422 )
3423{
3424 SCIP_CALL( SCIPcheckStage(scip, "SCIPinterruptSolve", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3425
3426 /* set the userinterrupt flag */
3427 scip->stat->userinterrupt = TRUE;
3428
3429 return SCIP_OKAY;
3430}
3431
3432/** indicates whether \SCIP has been informed that the solving process should be interrupted as soon as possible
3433 *
3434 * This function returns whether SCIPinterruptSolve() has been called, which is different from SCIPinterrupted(),
3435 * which returns whether a SIGINT signal has been received by the SCIP signal handler.
3436 *
3437 * @pre This method can be called if @p scip is in one of the following stages:
3438 * - \ref SCIP_STAGE_PROBLEM
3439 * - \ref SCIP_STAGE_TRANSFORMING
3440 * - \ref SCIP_STAGE_TRANSFORMED
3441 * - \ref SCIP_STAGE_INITPRESOLVE
3442 * - \ref SCIP_STAGE_PRESOLVING
3443 * - \ref SCIP_STAGE_EXITPRESOLVE
3444 * - \ref SCIP_STAGE_PRESOLVED
3445 * - \ref SCIP_STAGE_SOLVING
3446 * - \ref SCIP_STAGE_SOLVED
3447 * - \ref SCIP_STAGE_EXITSOLVE
3448 * - \ref SCIP_STAGE_FREETRANS
3449 *
3450 * @note the \SCIP stage does not get changed
3451 */
3453 SCIP* scip /**< SCIP data structure */
3454 )
3455{
3456 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisSolveInterrupted", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3457
3458 return scip->stat->userinterrupt;
3459}
3460
3461/** informs SCIP that the solving process should be restarted as soon as possible (e.g., after the current node has
3462 * been solved)
3463 *
3464 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3465 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3466 *
3467 * @pre This method can be called if @p scip is in one of the following stages:
3468 * - \ref SCIP_STAGE_INITPRESOLVE
3469 * - \ref SCIP_STAGE_PRESOLVING
3470 * - \ref SCIP_STAGE_EXITPRESOLVE
3471 * - \ref SCIP_STAGE_SOLVING
3472 *
3473 * @note the \SCIP stage does not get changed
3474 */
3476 SCIP* scip /**< SCIP data structure */
3477 )
3478{
3480
3481 /* set the userrestart flag */
3482 scip->stat->userrestart = TRUE;
3483
3484 return SCIP_OKAY;
3485}
3486
3487/** returns whether reoptimization is enabled or not */
3489 SCIP* scip /**< SCIP data structure */
3490 )
3491{
3492 assert(scip != NULL);
3493
3494 return scip->set->reopt_enable;
3495}
3496
3497/** returns the stored solutions corresponding to a given run */
3499 SCIP* scip, /**< SCIP data structure */
3500 int run, /**< number of the run */
3501 SCIP_SOL** sols, /**< array to store solutions */
3502 int solssize, /**< size of the array */
3503 int* nsols /**< pointer to store number of solutions */
3504 )
3505{
3506 assert(scip != NULL);
3507 assert(sols != NULL);
3508 assert(solssize > 0);
3509
3510 if( scip->set->reopt_enable )
3511 {
3512 assert(run > 0 && run <= scip->stat->nreoptruns);
3513 SCIP_CALL( SCIPreoptGetSolsRun(scip->reopt, run, sols, solssize, nsols) );
3514 }
3515 else
3516 {
3517 *nsols = 0;
3518 }
3519
3520 return SCIP_OKAY;
3521}
3522
3523/** mark all stored solutions as not updated */
3525 SCIP* scip /**< SCIP data structure */
3526 )
3527{
3528 assert(scip != NULL);
3529 assert(scip->set->reopt_enable);
3530 assert(scip->reopt != NULL);
3531
3532 if( scip->set->reopt_enable )
3533 {
3534 assert(scip->reopt != NULL);
3536 }
3537}
3538
3539/** check if the reoptimization process should be restarted
3540 *
3541 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3542 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3543 *
3544 * @pre This method can be called if @p scip is in one of the following stages:
3545 * - \ref SCIP_STAGE_TRANSFORMED
3546 * - \ref SCIP_STAGE_SOLVING
3547 */
3549 SCIP* scip, /**< SCIP data structure */
3550 SCIP_NODE* node, /**< current node of the branch and bound tree (or NULL) */
3551 SCIP_Bool* restart /**< pointer to store of the reoptimitation process should be restarted */
3552 )
3553{
3554 assert(scip != NULL);
3555 assert(scip->set->reopt_enable);
3556 assert(scip->reopt != NULL);
3557
3558 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckReoptRestart", FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3559
3560 SCIP_CALL( SCIPreoptCheckRestart(scip->reopt, scip->set, scip->mem->probmem, node, scip->transprob->vars,
3561 scip->transprob->nvars, restart) );
3562
3563 return SCIP_OKAY;
3564}
3565
3566/** returns whether we are in the restarting phase
3567 *
3568 * @return TRUE, if we are in the restarting phase; FALSE, otherwise
3569 *
3570 * @pre This method can be called if @p scip is in one of the following stages:
3571 * - \ref SCIP_STAGE_INITPRESOLVE
3572 * - \ref SCIP_STAGE_PRESOLVING
3573 * - \ref SCIP_STAGE_EXITPRESOLVE
3574 * - \ref SCIP_STAGE_PRESOLVED
3575 * - \ref SCIP_STAGE_INITSOLVE
3576 * - \ref SCIP_STAGE_SOLVING
3577 * - \ref SCIP_STAGE_SOLVED
3578 * - \ref SCIP_STAGE_EXITSOLVE
3579 * - \ref SCIP_STAGE_FREETRANS
3580 */
3582 SCIP* scip /**< SCIP data structure */
3583 )
3584{
3586
3587 /* return the restart status */
3588 return scip->stat->inrestart;
3589}
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:3129
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:4940
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:2411
SCIP_NODE * SCIPtreeGetFocusNode(SCIP_TREE *tree)
Definition tree.c:8358
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:4904
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition tree.c:8433
SCIP_NODE * SCIPtreeGetRootNode(SCIP_TREE *tree)
Definition tree.c:8500
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:5060
int SCIPtreeGetNNodes(SCIP_TREE *tree)
Definition tree.c:8305
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:4953
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:4398
SCIP_RETCODE SCIPtreeCreate(SCIP_TREE **tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_NODESEL *nodesel)
Definition tree.c:4823
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:5014
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:5101
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)