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