Scippy

SCIP

Solving Constraint Integer Programs

scip_probing.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file scip_probing.c
26 * @ingroup OTHER_CFILES
27 * @brief public methods for the probing mode
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/conflict.h"
47#include "scip/cons.h"
48#include "scip/debug.h"
49#include "scip/heur.h"
50#include "scip/lp.h"
51#include "scip/prob.h"
52#include "scip/pub_message.h"
53#include "scip/pub_misc.h"
54#include "scip/pub_relax.h"
55#include "scip/pub_tree.h"
56#include "scip/pub_var.h"
57#include "scip/relax.h"
58#include "scip/scip_exact.h"
59#include "scip/scip_general.h"
60#include "scip/scip_lp.h"
61#include "scip/scip_mem.h"
62#include "scip/scip_message.h"
63#include "scip/scip_numerics.h"
64#include "scip/scip_prob.h"
65#include "scip/scip_probing.h"
67#include "scip/scip_tree.h"
68#include "scip/sepastore.h"
69#include "scip/set.h"
70#include "scip/solve.h"
71#include "scip/stat.h"
72#include "scip/struct_lp.h"
73#include "scip/struct_mem.h"
74#include "scip/struct_scip.h"
75#include "scip/struct_set.h"
76#include "scip/struct_stat.h"
77#include "scip/struct_tree.h"
78#include "scip/struct_var.h"
79#include "scip/tree.h"
80#include "scip/var.h"
81
82/** returns whether we are in probing mode; probing mode is activated via SCIPstartProbing() and stopped
83 * via SCIPendProbing()
84 *
85 * @return TRUE, if SCIP is currently in probing mode, otherwise FALSE
86 *
87 * @pre This method can be called if @p scip is in one of the following stages:
88 * - \ref SCIP_STAGE_TRANSFORMED
89 * - \ref SCIP_STAGE_INITPRESOLVE
90 * - \ref SCIP_STAGE_PRESOLVING
91 * - \ref SCIP_STAGE_EXITPRESOLVE
92 * - \ref SCIP_STAGE_PRESOLVED
93 * - \ref SCIP_STAGE_INITSOLVE
94 * - \ref SCIP_STAGE_SOLVING
95 * - \ref SCIP_STAGE_SOLVED
96 * - \ref SCIP_STAGE_EXITSOLVE
97 */
99 SCIP* scip /**< SCIP data structure */
100 )
101{
103
104 return SCIPtreeProbing(scip->tree);
105}
106
107/** initiates probing, making methods SCIPnewProbingNode(), SCIPbacktrackProbing(), SCIPchgVarLbProbing(),
108 * SCIPchgVarUbProbing(), SCIPfixVarProbing(), SCIPpropagateProbing(), and SCIPsolveProbingLP() available
109 *
110 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
111 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
112 *
113 * @pre This method can be called if @p scip is in one of the following stages:
114 * - \ref SCIP_STAGE_PRESOLVING
115 * - \ref SCIP_STAGE_SOLVING
116 *
117 * @note The collection of variable statistics is turned off during probing. If these statistics should be collected
118 * during probing use the method SCIPenableVarHistory() to turn the collection explicitly on.
119 */
121 SCIP* scip /**< SCIP data structure */
122 )
123{
125
126 if( SCIPtreeProbing(scip->tree) )
127 {
128 SCIPerrorMessage("already in probing mode\n");
129 return SCIP_INVALIDCALL;
130 }
131
132 if( scip->lp != NULL && SCIPlpDiving(scip->lp) )
133 {
134 SCIPerrorMessage("cannot start probing while in diving mode\n");
135 return SCIP_INVALIDCALL;
136 }
137
138 /* use a different separation storage for probing mode; otherwise SCIP will remove the cuts that are currently in the
139 * separation storage after solving an LP in probing mode
140 */
141 if( scip->sepastore != NULL )
142 {
143 assert(scip->sepastoreprobing != NULL);
144 SCIPswapPointers((void**)&scip->sepastore, (void**)&scip->sepastoreprobing);
145 }
146
147 SCIP_CALL( SCIPtreeStartProbing(scip->tree, scip->mem->probmem, scip->set, scip->lp, scip->relaxation, scip->transprob, FALSE) );
148
149 /* disables the collection of any statistic for a variable */
151
152 return SCIP_OKAY;
153}
154
155/** creates a new probing sub node, whose changes can be undone by backtracking to a higher node in the probing path
156 * with a call to SCIPbacktrackProbing();
157 * using a sub node for each set of probing bound changes can improve conflict analysis
158 *
159 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
160 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
161 *
162 * @pre This method can be called if @p scip is in one of the following stages:
163 * - \ref SCIP_STAGE_PRESOLVING
164 * - \ref SCIP_STAGE_SOLVING
165 */
167 SCIP* scip /**< SCIP data structure */
168 )
169{
170 SCIP_RETCODE retcode;
171
173
174 if( !SCIPtreeProbing(scip->tree) )
175 {
176 SCIPerrorMessage("not in probing mode\n");
177 return SCIP_INVALIDCALL;
178 }
179
180 retcode = SCIPtreeCreateProbingNode(scip->tree, scip->mem->probmem, scip->set, scip->lp);
181
182 if( retcode == SCIP_MAXDEPTHLEVEL )
183 {
184 SCIPwarningMessage(scip, "probing reached maximal depth; it should be stopped\n");
185 }
186 SCIP_CALL( retcode );
187
188 return SCIP_OKAY;
189}
190
191/** returns the current probing depth
192 *
193 * @return the probing depth, i.e. the number of probing sub nodes existing in the probing path
194 *
195 * @pre This method can be called if @p scip is in one of the following stages:
196 * - \ref SCIP_STAGE_PRESOLVING
197 * - \ref SCIP_STAGE_SOLVING
198 */
200 SCIP* scip /**< SCIP data structure */
201 )
202{
204
205 if( !SCIPtreeProbing(scip->tree) )
206 {
207 SCIPerrorMessage("not in probing mode\n");
208 SCIPABORT();
209 return -1; /*lint !e527*/
210 }
211
212 return SCIPtreeGetProbingDepth(scip->tree);
213}
214
215/** undoes all changes to the problem applied in probing up to the given probing depth;
216 * the changes of the probing node of the given probing depth are the last ones that remain active;
217 * changes that were applied before calling SCIPnewProbingNode() cannot be undone
218 *
219 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
220 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
221 *
222 * @pre This method can be called if @p scip is in one of the following stages:
223 * - \ref SCIP_STAGE_PRESOLVING
224 * - \ref SCIP_STAGE_SOLVING
225 */
227 SCIP* scip, /**< SCIP data structure */
228 int probingdepth /**< probing depth of the node in the probing path that should be reactivated */
229 )
230{
231 SCIP_CALL( SCIPcheckStage(scip, "SCIPbacktrackProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
232
233 if( !SCIPtreeProbing(scip->tree) )
234 {
235 SCIPerrorMessage("not in probing mode\n");
236 return SCIP_INVALIDCALL;
237 }
238 if( probingdepth < 0 || probingdepth > SCIPtreeGetProbingDepth(scip->tree) )
239 {
240 SCIPerrorMessage("backtracking probing depth %d out of current probing range [0,%d]\n",
241 probingdepth, SCIPtreeGetProbingDepth(scip->tree));
242 return SCIP_INVALIDDATA;
243 }
244
245 SCIP_CALL( SCIPtreeBacktrackProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
246 scip->origprob, scip->lp, scip->primal, scip->branchcand, scip->eventqueue, scip->eventfilter,
247 scip->cliquetable, probingdepth) );
248
249 return SCIP_OKAY;
250}
251
252/** quits probing and resets bounds and constraints to the focus node's environment
253 *
254 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
255 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
256 *
257 * @pre This method can be called if @p scip is in one of the following stages:
258 * - \ref SCIP_STAGE_PRESOLVING
259 * - \ref SCIP_STAGE_SOLVING
260 */
262 SCIP* scip /**< SCIP data structure */
263 )
264{
266
267 if( !SCIPtreeProbing(scip->tree) )
268 {
269 SCIPerrorMessage("not in probing mode\n");
270 return SCIP_INVALIDCALL;
271 }
272
273 /* switch back from probing to normal operation mode and restore variables and constraints to focus node */
274 SCIP_CALL( SCIPtreeEndProbing(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
275 scip->transprob, scip->origprob, scip->lp, scip->relaxation, scip->primal,
276 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable) );
277
278 /* enables the collection of statistics for a variable */
280
281 /* switch to the original separation storage */
282 if( scip->sepastore != NULL )
283 {
284 assert(scip->sepastoreprobing != NULL);
285 SCIPswapPointers((void**)&scip->sepastore, (void**)&scip->sepastoreprobing);
286 assert(SCIPsepastoreGetNCuts(scip->sepastoreprobing) == 0);
287 }
288
289 return SCIP_OKAY;
290}
291
292/** injects a change of variable's lower bound into current probing node; the same can also be achieved with a call to
293 * SCIPchgVarLb(), but in this case, the bound change would be treated like a deduction instead of a branching decision
294 *
295 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
296 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
297 *
298 * @pre This method can be called if @p scip is in one of the following stages:
299 * - \ref SCIP_STAGE_PRESOLVING
300 * - \ref SCIP_STAGE_SOLVING
301 */
303 SCIP* scip, /**< SCIP data structure */
304 SCIP_VAR* var, /**< variable to change the bound for */
305 SCIP_Real newbound /**< new value for bound */
306 )
307{
309
310 if( !SCIPtreeProbing(scip->tree) )
311 {
312 SCIPerrorMessage("not in probing mode\n");
313 return SCIP_INVALIDCALL;
314 }
316
317 SCIPvarAdjustLb(var, scip->set, &newbound);
318
319 /* ignore tightenings of lower bounds to +infinity during solving process */
321 {
322#ifndef NDEBUG
323 SCIPwarningMessage(scip, "ignore lower bound tightening for %s from %e to +infinity\n", SCIPvarGetName(var),
324 SCIPvarGetLbLocal(var));
325#endif
326 return SCIP_OKAY;
327 }
328
329 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
330 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
331 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_LOWER, TRUE) );
332
333 return SCIP_OKAY;
334}
335
336/** injects a change of variable's upper bound into current probing node; the same can also be achieved with a call to
337 * SCIPchgVarUb(), but in this case, the bound change would be treated like a deduction instead of a branching decision
338 *
339 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
340 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
341 *
342 * @pre This method can be called if @p scip is in one of the following stages:
343 * - \ref SCIP_STAGE_PRESOLVING
344 * - \ref SCIP_STAGE_SOLVING
345 */
347 SCIP* scip, /**< SCIP data structure */
348 SCIP_VAR* var, /**< variable to change the bound for */
349 SCIP_Real newbound /**< new value for bound */
350 )
351{
353
354 if( !SCIPtreeProbing(scip->tree) )
355 {
356 SCIPerrorMessage("not in probing mode\n");
357 return SCIP_INVALIDCALL;
358 }
360
361 SCIPvarAdjustUb(var, scip->set, &newbound);
362
363 /* ignore tightenings of upper bounds to -infinity during solving process */
365 {
366#ifndef NDEBUG
367 SCIPwarningMessage(scip, "ignore upper bound tightening for %s from %e to -infinity\n", SCIPvarGetName(var),
368 SCIPvarGetUbLocal(var));
369#endif
370 return SCIP_OKAY;
371 }
372
373 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
374 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
375 scip->eventfilter, scip->cliquetable, var, newbound, SCIP_BOUNDTYPE_UPPER, TRUE) );
376
377 return SCIP_OKAY;
378}
379
380/** gets variable's objective value in current probing
381 *
382 * @return the variable's objective value in current probing.
383 *
384 * @pre This method can be called if @p scip is in one of the following stages:
385 * - \ref SCIP_STAGE_SOLVING
386 *
387 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
388 */
390 SCIP* scip, /**< SCIP data structure */
391 SCIP_VAR* var /**< variable to get the bound for */
392 )
393{
394 assert(scip != NULL);
395 assert(var != NULL);
396
398
399 if( !SCIPtreeProbing(scip->tree) )
400 {
401 SCIPerrorMessage("not in probing mode\n");
402 return SCIP_INVALID;
403 }
404
405 return SCIPvarGetObjLP(var);
406}
407
408/** injects a change of variable's bounds into current probing node to fix the variable to the specified value;
409 * the same can also be achieved with a call to SCIPfixVar(), but in this case, the bound changes would be treated
410 * like deductions instead of branching decisions
411 *
412 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
413 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
414 *
415 * @pre This method can be called if @p scip is in one of the following stages:
416 * - \ref SCIP_STAGE_PRESOLVING
417 * - \ref SCIP_STAGE_SOLVING
418 */
420 SCIP* scip, /**< SCIP data structure */
421 SCIP_VAR* var, /**< variable to change the bound for */
422 SCIP_Real fixedval /**< value to fix variable to */
423 )
424{
425 SCIP_Real fixlb;
426 SCIP_Real fixub;
427
429
430 if( !SCIPtreeProbing(scip->tree) )
431 {
432 SCIPerrorMessage("not in probing mode\n");
433 return SCIP_INVALIDCALL;
434 }
436
437 /* we adjust the fixing value here and compare the old bound with the adjusted values because otherwise,
438 * it might happen that the unadjusted value is better and we add the boundchange,
439 * but within SCIPnodeAddBoundchg() the bounds are adjusted - using the feasibility epsilon for integer variables -
440 * and it is asserted, that the bound is still better than the old one which might then be incorrect.
441 */
442 fixlb = fixedval;
443 fixub = fixedval;
444 SCIPvarAdjustLb(var, scip->set, &fixlb);
445 SCIPvarAdjustUb(var, scip->set, &fixub);
446 assert(SCIPsetIsEQ(scip->set, fixlb, fixub));
447
448 if( SCIPsetIsGT(scip->set, fixlb, SCIPvarGetLbLocal(var)) )
449 {
450 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
451 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
452 scip->eventfilter, scip->cliquetable, var, fixlb, SCIP_BOUNDTYPE_LOWER, TRUE) );
453 }
454 if( SCIPsetIsLT(scip->set, fixub, SCIPvarGetUbLocal(var)) )
455 {
456 SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
457 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
458 scip->eventfilter, scip->cliquetable, var, fixub, SCIP_BOUNDTYPE_UPPER, TRUE) );
459 }
460
461 return SCIP_OKAY;
462}
463
464/** changes (column) variable's objective value during probing mode
465 *
466 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
467 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
468 *
469 * @pre This method can be called if @p scip is in one of the following stages:
470 * - \ref SCIP_STAGE_PRESOLVING
471 * - \ref SCIP_STAGE_SOLVING
472 *
473 * @pre The variable needs to be a column variable.
474 */
476 SCIP* scip, /**< SCIP data structure */
477 SCIP_VAR* var, /**< variable to change the objective for */
478 SCIP_Real newobj /**< new objective function value */
479 )
480{
481 SCIP_NODE* node;
482 SCIP_Real oldobj;
483
484 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgVarObjProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
485
486 if( !SCIPtreeProbing(scip->tree) )
487 {
488 SCIPerrorMessage("not in probing mode\n");
489 return SCIP_INVALIDCALL;
490 }
491
492 /* get current probing node */
493 node = SCIPtreeGetCurrentNode(scip->tree);
495
496 /* get old objective function value */
497 oldobj = SCIPvarGetObj(var);
498
499 if( SCIPisEQ(scip, oldobj, newobj) )
500 return SCIP_OKAY;
501
502 if( node->data.probingnode->nchgdobjs == 0 )
503 {
504 SCIP_CALL( SCIPallocMemoryArray(scip, &node->data.probingnode->origobjvars, 1) ); /*lint !e506*/
505 SCIP_CALL( SCIPallocMemoryArray(scip, &node->data.probingnode->origobjvals, 1) ); /*lint !e506*/
506 }
507 else
508 {
511 }
512
514 node->data.probingnode->origobjvals[node->data.probingnode->nchgdobjs] = oldobj;
515 ++node->data.probingnode->nchgdobjs;
516 ++scip->tree->probingsumchgdobjs;
517
519
520 /* inform tree and LP that the objective was changed and invalidate the LP's cutoff bound, since this has nothing to
521 * do with the current objective value anymore; the cutoff bound is reset in SCIPendProbing()
522 */
523 if( !SCIPtreeProbingObjChanged(scip->tree) )
524 {
525 SCIP_CALL( SCIPlpSetCutoffbound(scip->lp, scip->set, scip->transprob, SCIPsetInfinity(scip->set)) );
526
529 }
530 assert(SCIPisInfinity(scip, scip->lp->cutoffbound));
531
532 /* perform the objective change */
533 SCIP_CALL( SCIPvarChgObj(var, scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp, scip->eventqueue, newobj) );
534
535 return SCIP_OKAY;
536}
537
538/** returns whether the objective function has changed during probing mode
539 *
540 * @return \ref TRUE if objective has changed, \ref FALSE otherwise
541 *
542 * @pre This method can be called if @p scip is in one of the following stages:
543 * - \ref SCIP_STAGE_TRANSFORMED
544 * - \ref SCIP_STAGE_INITPRESOLVE
545 * - \ref SCIP_STAGE_PRESOLVING
546 * - \ref SCIP_STAGE_EXITPRESOLVE
547 * - \ref SCIP_STAGE_PRESOLVED
548 * - \ref SCIP_STAGE_INITSOLVE
549 * - \ref SCIP_STAGE_SOLVING
550 * - \ref SCIP_STAGE_SOLVED
551 * - \ref SCIP_STAGE_EXITSOLVE
552 */
554 SCIP* scip /**< SCIP data structure */
555 )
556{
557 assert(scip != NULL);
558
559 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisObjChangedProbing", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
560
561 return scip->tree != NULL && SCIPinProbing(scip) && SCIPtreeProbingObjChanged(scip->tree);
562}
563
564/** applies domain propagation on the probing sub problem, that was changed after SCIPstartProbing() was called;
565 * the propagated domains of the variables can be accessed with the usual bound accessing calls SCIPvarGetLbLocal()
566 * and SCIPvarGetUbLocal(); the propagation is only valid locally, i.e. the local bounds as well as the changed
567 * bounds due to SCIPchgVarLbProbing(), SCIPchgVarUbProbing(), and SCIPfixVarProbing() are used for propagation
568 *
569 * @note Conflict analysis can run if the propagation finds infeasibilities. SCIPpropagateProbing can even find
570 * globally valid bound changes. For this reason, the function restores the original objective (i.e. undoes the changes
571 * done by SCIPchgVarObjProbing before performing the propagation, as the propagators don't know that the objective
572 * might have changed. Thus, SCIPpropagateProbing can have an effect on the problem after probing ends.
573 *
574 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
575 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
576 *
577 * @pre This method can be called if @p scip is in one of the following stages:
578 * - \ref SCIP_STAGE_PRESOLVING
579 * - \ref SCIP_STAGE_SOLVING
580 */
582 SCIP* scip, /**< SCIP data structure */
583 int maxproprounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
584 SCIP_Bool* cutoff, /**< pointer to store whether the probing node can be cut off */
585 SCIP_Longint* ndomredsfound /**< pointer to store the number of domain reductions found, or NULL */
586 )
587{
588 SCIP_VAR** objchgvars;
589 SCIP_Real* objchgvals;
590 SCIP_Bool changedobj;
591 int nobjchg;
592
593 if( SCIPisExact(scip) )
594 return SCIP_OKAY;
595
596 SCIP_CALL( SCIPcheckStage(scip, "SCIPpropagateProbing", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
597
598 if( !SCIPtreeProbing(scip->tree) )
599 {
600 SCIPerrorMessage("not in probing mode\n");
601 return SCIP_INVALIDCALL;
602 }
603
604 objchgvars = NULL;
605 objchgvals = NULL;
606 changedobj = FALSE;
607 nobjchg = 0;
608
609 /* undo objective changes if we want to propagate during probing */
610 if( scip->tree->probingobjchanged )
611 {
612 SCIP_VAR** vars;
613 int nvars;
614 int i;
615
616 vars = SCIPgetVars(scip);
617 nvars = SCIPgetNVars(scip);
618
619 SCIP_CALL( SCIPallocBufferArray(scip, &objchgvals, MIN(nvars, scip->tree->probingsumchgdobjs)) );
620 SCIP_CALL( SCIPallocBufferArray(scip, &objchgvars, MIN(nvars, scip->tree->probingsumchgdobjs)) );
621 nobjchg = 0;
622
623 for( i = 0; i < nvars; ++i )
624 {
625 if( !SCIPisEQ(scip, vars[i]->unchangedobj, SCIPgetVarObjProbing(scip, vars[i])) )
626 {
627 objchgvars[nobjchg] = vars[i];
628 objchgvals[nobjchg] = SCIPgetVarObjProbing(scip, vars[i]);
629 ++nobjchg;
630
631 SCIP_CALL( SCIPvarChgObj(vars[i], scip->mem->probmem, scip->set, scip->transprob, scip->primal, scip->lp,
632 scip->eventqueue, vars[i]->unchangedobj) );
633 }
634 }
635 assert(nobjchg <= scip->tree->probingsumchgdobjs);
636
638 scip->tree->probingobjchanged = FALSE;
639 changedobj = TRUE;
640 }
641
642 if( ndomredsfound != NULL )
643 *ndomredsfound = -(scip->stat->nprobboundchgs + scip->stat->nprobholechgs);
644
645 SCIP_CALL( SCIPpropagateDomains(scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->origprob,
646 scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
647 scip->conflict, scip->cliquetable, SCIPgetDepth(scip), maxproprounds, SCIP_PROPTIMING_ALWAYS, cutoff) );
648
649 if( ndomredsfound != NULL )
650 *ndomredsfound += scip->stat->nprobboundchgs + scip->stat->nprobholechgs;
651
652 /* restore old objective function */
653 if( changedobj )
654 {
655 int i;
656
657 assert(objchgvars != NULL);
658 assert(objchgvals != NULL);
659
661 scip->tree->probingobjchanged = TRUE;
662
663 for( i = 0; i < nobjchg; ++i )
664 {
665 SCIP_CALL( SCIPvarChgObj(objchgvars[i], scip->mem->probmem, scip->set, scip->transprob, scip->primal,
666 scip->lp, scip->eventqueue, objchgvals[i]) );
667 }
668
669 SCIPfreeBufferArray(scip, &objchgvars);
670 SCIPfreeBufferArray(scip, &objchgvals);
671 }
672
673 return SCIP_OKAY;
674}
675
676/** applies domain propagation on the probing sub problem, that was changed after SCIPstartProbing() was called;
677 * only propagations of the binary variables fixed at the current probing node that are triggered by the implication
678 * graph and the clique table are applied;
679 * the propagated domains of the variables can be accessed with the usual bound accessing calls SCIPvarGetLbLocal()
680 * and SCIPvarGetUbLocal(); the propagation is only valid locally, i.e. the local bounds as well as the changed
681 * bounds due to SCIPchgVarLbProbing(), SCIPchgVarUbProbing(), and SCIPfixVarProbing() are used for propagation
682 *
683 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
684 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
685 *
686 * @pre This method can be called if @p scip is in one of the following stages:
687 * - \ref SCIP_STAGE_PRESOLVING
688 * - \ref SCIP_STAGE_SOLVING
689 */
691 SCIP* scip, /**< SCIP data structure */
692 SCIP_Bool* cutoff /**< pointer to store whether the probing node can be cut off */
693 )
694{
695 SCIP_CALL( SCIPcheckStage(scip, "SCIPpropagateProbingImplications", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
696
697 if( !SCIPtreeProbing(scip->tree) )
698 {
699 SCIPerrorMessage("not in probing mode\n");
700 return SCIP_INVALIDCALL;
701 }
702
703 SCIP_CALL( SCIPnodePropagateImplics(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
704 scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue,
705 scip->eventfilter, scip->cliquetable, cutoff) );
706
707 return SCIP_OKAY;
708}
709
710/** solves the LP at the current probing node (cannot be applied at preprocessing stage) with or without pricing */
711static
713 SCIP* scip, /**< SCIP data structure */
714 int itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
715 SCIP_Bool pricing, /**< should pricing be applied? */
716 SCIP_Bool pretendroot, /**< should the pricers be called as if we are at the root node? */
717 SCIP_Bool displayinfo, /**< should info lines be displayed after each pricing round? */
718 int maxpricerounds, /**< maximal number of pricing rounds (-1: no limit) */
719 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
720 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
721 * limit was reached (or NULL, if not needed) */
722 )
723{
724 SCIP_Bool initcutoff;
725
726 assert(lperror != NULL);
728
729 if( !SCIPtreeProbing(scip->tree) )
730 {
731 SCIPerrorMessage("not in probing mode\n");
732 return SCIP_INVALIDCALL;
733 }
734 assert(SCIPtreeGetCurrentDepth(scip->tree) > 0);
735
736 SCIP_CALL( SCIPinitConssLP(scip->mem->probmem, scip->set, scip->sepastore, scip->cutpool, scip->stat, scip->transprob,
737 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
738 scip->cliquetable, FALSE, FALSE, &initcutoff) );
739
740 if( initcutoff )
741 {
742 if( cutoff != NULL )
743 *cutoff = TRUE;
744
745 return SCIP_OKAY;
746 }
747 else if( cutoff != NULL )
748 *cutoff = FALSE;
749
750 /* load the LP state (if necessary) */
751 SCIP_CALL( SCIPtreeLoadProbingLPState(scip->tree, scip->mem->probmem, scip->set, scip->transprob, scip->eventqueue, scip->lp) );
752
753 /* the LP is a relaxation if and only if the objective has not been changed */
754 SCIPlpSetIsRelax(scip->lp, !scip->tree->probingobjchanged);
755
756 /* solve probing LP */
757 SCIP_CALL( SCIPlpSolveAndEval(scip->lp, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat,
758 scip->eventqueue, scip->eventfilter, scip->transprob, (SCIP_Longint)itlim, FALSE, FALSE, FALSE, FALSE, lperror) );
759
760 assert((*lperror) || SCIPlpGetSolstat(scip->lp) != SCIP_LPSOLSTAT_NOTSOLVED);
761
762 /* mark the probing node to have a solved LP */
763 if( !(*lperror) )
764 {
765 SCIP_CALL( SCIPtreeMarkProbingNodeHasLP(scip->tree, scip->mem->probmem, scip->lp) );
766
767 /* call pricing */
768 if( pricing )
769 {
770 SCIP_Bool mustsepa;
771 int npricedcolvars;
772 SCIP_Bool result;
773
774 mustsepa = FALSE;
775 SCIP_CALL( SCIPpriceLoop(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->transprob,
776 scip->origprob, scip->primal, scip->tree, scip->reopt, scip->lp, scip->pricestore, scip->sepastore, scip->cutpool,
777 scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable, pretendroot, displayinfo,
778 maxpricerounds, &npricedcolvars, &mustsepa, lperror, &result) );
779
780 /* mark the probing node again to update the LP size in the node and the tree path */
781 if( !(*lperror) )
782 {
783 SCIP_CALL( SCIPtreeMarkProbingNodeHasLP(scip->tree, scip->mem->probmem, scip->lp) );
784 }
785 }
786 }
787
788 /* remember that probing might have changed the LPi state; this holds even if solving returned with an LP error */
789 scip->tree->probingsolvedlp = TRUE;
790
791 /* the LP is infeasible or the objective limit was reached */
792 if( !(*lperror) && (SCIPlpGetSolstat(scip->lp) == SCIP_LPSOLSTAT_INFEASIBLE
794 (SCIPlpGetSolstat(scip->lp) == SCIP_LPSOLSTAT_OPTIMAL && !scip->tree->probingobjchanged
796 {
797 /* analyze the infeasible LP (only if all columns are in the LP and no external pricers exist) */
798 if( SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && !scip->tree->probingobjchanged )
799 {
800 SCIP_CALL( SCIPconflictAnalyzeLP(scip->conflict, scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
801 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter, scip->cliquetable, NULL) );
802 }
803
804 if( cutoff != NULL )
805 *cutoff = TRUE;
806 }
807
808 return SCIP_OKAY;
809}
810
811/** solves the LP at the current probing node (cannot be applied at preprocessing stage);
812 * no separation or pricing is applied
813 *
814 * The LP has to be constructed before (you can use SCIPisLPConstructed() or SCIPconstructLP()).
815 *
816 * @note if the LP is infeasible or the objective limit is reached, and if all columns are in the LP and no external
817 * pricers exist then conflict analysis will be run. This can have an effect on the problem after probing ends.
818 *
819 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
820 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
821 *
822 * @pre This method can be called if @p scip is in one of the following stages:
823 * - \ref SCIP_STAGE_SOLVING
824 */
826 SCIP* scip, /**< SCIP data structure */
827 int itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
828 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
829 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
830 * limit was reached (or NULL, if not needed) */
831 )
832{
834
835 SCIP_CALL( solveProbingLP(scip, itlim, FALSE, FALSE, FALSE, -1, lperror, cutoff) );
836
837 return SCIP_OKAY;
838}
839
840/** solves the LP at the current probing node (cannot be applied at preprocessing stage) and applies pricing
841 * until the LP is solved to optimality; no separation is applied
842 *
843 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
844 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
845 *
846 * @pre This method can be called if @p scip is in one of the following stages:
847 * - \ref SCIP_STAGE_SOLVING
848 */
850 SCIP* scip, /**< SCIP data structure */
851 SCIP_Bool pretendroot, /**< should the pricers be called as if we were at the root node? */
852 SCIP_Bool displayinfo, /**< should info lines be displayed after each pricing round? */
853 int maxpricerounds, /**< maximal number of pricing rounds (-1: no limit);
854 * a finite limit means that the LP might not be solved to optimality! */
855 SCIP_Bool* lperror, /**< pointer to store whether an unresolved LP error occurred */
856 SCIP_Bool* cutoff /**< pointer to store whether the probing LP was infeasible or the objective
857 * limit was reached (or NULL, if not needed) */
858 )
859{
860 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveProbingLPWithPricing", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
861
862 SCIP_CALL( solveProbingLP(scip, -1, TRUE, pretendroot, displayinfo, maxpricerounds, lperror, cutoff) );
863
864 return SCIP_OKAY;
865}
866
867/** sets the LP state for the current probing node
868 *
869 * @note state and norms are stored at the node and later released by SCIP; therefore, the pointers are set
870 * to NULL by the method
871 *
872 * @note the pointers to state and norms must not be NULL; however, they may point to a NULL pointer if the
873 * respective information should not be set
874 *
875 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
876 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
877 *
878 * @pre This method can be called if @p scip is in one of the following stages:
879 * - \ref SCIP_STAGE_PRESOLVING
880 * - \ref SCIP_STAGE_SOLVING
881 */
883 SCIP* scip, /**< SCIP data structure */
884 SCIP_LPISTATE** lpistate, /**< pointer to LP state information (like basis information) */
885 SCIP_LPINORMS** lpinorms, /**< pointer to LP pricing norms information */
886 SCIP_Bool primalfeas, /**< primal feasibility when LP state information was stored */
887 SCIP_Bool dualfeas /**< dual feasibility when LP state information was stored */
888 )
889{
890 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbingLPState", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
891
892 if( !SCIPtreeProbing(scip->tree) )
893 {
894 SCIPerrorMessage("not in probing mode\n");
895 return SCIP_INVALIDCALL;
896 }
897
898 SCIP_CALL( SCIPtreeSetProbingLPState(scip->tree, scip->mem->probmem, scip->lp, lpistate, lpinorms, primalfeas, dualfeas) );
899
900 return SCIP_OKAY;
901}
902
903/** adds a row to the LP in the current probing node
904 *
905 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
906 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
907 *
908 * @pre This method can be called if @p scip is in one of the following stages:
909 * - \ref SCIP_STAGE_SOLVING
910 *
911 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
912 */
914 SCIP* scip, /**< SCIP data structure */
915 SCIP_ROW* row /**< row to be added */
916 )
917{
918 SCIP_NODE* node;
919 int depth;
920
921 assert(scip != NULL);
922 assert(row != NULL);
923
925
926 if( !SCIPtreeProbing(scip->tree) )
927 {
928 SCIPerrorMessage("not in probing mode\n");
929 return SCIP_INVALIDCALL;
930 }
931
932 /* get depth of current node */
933 node = SCIPtreeGetCurrentNode(scip->tree);
934 assert(node != NULL);
935 depth = SCIPnodeGetDepth(node);
936
937 SCIP_CALL( SCIPlpAddRow(scip->lp, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter, row, depth) );
938
939 return SCIP_OKAY;
940}
941
942
943/** applies the cuts in the separation storage to the LP and clears the storage afterwards;
944 * this method can only be applied during probing; the user should resolve the probing LP afterwards
945 * in order to get a new solution
946 *
947 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
948 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
949 *
950 * @pre This method can be called if @p scip is in one of the following stages:
951 * - \ref SCIP_STAGE_SOLVING
952 */
954 SCIP* scip, /**< SCIP data structure */
955 SCIP_Bool* cutoff /**< pointer to store whether an empty domain was created */
956 )
957{
958 SCIP_CALL( SCIPcheckStage(scip, "SCIPapplyCutsProbing", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
959
960 if( !SCIPtreeProbing(scip->tree) )
961 {
962 SCIPerrorMessage("not in probing mode\n");
963 return SCIP_INVALIDCALL;
964 }
965
966 SCIP_CALL( SCIPsepastoreApplyCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->stat, scip->transprob,
967 scip->origprob, scip->tree, scip->reopt, scip->lp, scip->branchcand, scip->eventqueue, scip->eventfilter,
968 scip->cliquetable, FALSE, SCIP_EFFICIACYCHOICE_LP, cutoff) );
969
970 return SCIP_OKAY;
971}
972
973/** solves relaxation(s) at the current probing node (cannot be applied at preprocessing stage);
974 * no separation or pricing is applied
975 *
976 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
977 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
978 *
979 * @pre This method can be called if @p scip is in one of the following stages:
980 * - \ref SCIP_STAGE_SOLVING
981 */
983 SCIP* scip, /**< SCIP data structure */
984 SCIP_Bool* cutoff /**< pointer to store whether a relaxation was infeasible or the objective
985 * limit was reached (or NULL, if not needed) */
986 )
987{
988 SCIP_SET* set;
989 int r;
990
991 SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveProbingRelax", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
992
993 if ( ! SCIPtreeProbing(scip->tree) )
994 {
995 SCIPerrorMessage("not in probing mode\n");
996 return SCIP_INVALIDCALL;
997 }
998 assert( SCIPtreeGetCurrentDepth(scip->tree) > 0 );
999
1000 assert( cutoff != NULL );
1001 *cutoff = FALSE;
1002
1003 set = scip->set;
1004
1005 /* sort relaxators by priority */
1007
1008 /* solve relaxations */
1009 for (r = 0; r < set->nrelaxs && !(*cutoff); ++r)
1010 {
1011 SCIP_RELAX* relax;
1012 SCIP_Real lowerbound;
1013 SCIP_RESULT result;
1014
1015 lowerbound = -SCIPinfinity(scip);
1016
1017 relax = set->relaxs[r];
1018 assert( relax != NULL );
1019
1020 SCIP_CALL( SCIPrelaxExec(relax, set, scip->tree, scip->stat, SCIPtreeGetCurrentDepth(scip->tree), &lowerbound, &result) );
1021
1022 switch( result )
1023 {
1024 case SCIP_CUTOFF:
1025 *cutoff = TRUE;
1026 SCIPdebugMsg(scip, " -> relaxator <%s> detected cutoff\n", SCIPrelaxGetName(relax));
1027 break;
1028
1029 case SCIP_CONSADDED:
1030 case SCIP_REDUCEDDOM:
1031 case SCIP_SEPARATED:
1032 case SCIP_SUSPENDED:
1033 SCIPerrorMessage("The relaxator should not return <%d> within probing mode.\n", result);
1034 break;
1035
1036 case SCIP_SUCCESS:
1037 case SCIP_DIDNOTRUN:
1038 break;
1039
1040 default:
1041 SCIPerrorMessage("Invalid result code <%d> of relaxator <%s>\n", result, SCIPrelaxGetName(relax));
1042 return SCIP_INVALIDRESULT;
1043 } /*lint !e788*/
1044 }
1045
1046 return SCIP_OKAY;
1047}
1048
1049/** print statistics of probing */
1051 SCIP* scip, /**< SCIP data structure */
1052 char* strbuf, /**< string buffer */
1053 int len /**< length of string buffer */
1054 )
1055{
1056 char* ptr = strbuf;
1057 const int nvartypes = 4;
1058
1059 assert(scip != NULL);
1060 assert(strbuf != NULL);
1061
1062 if( SCIPinProbing(scip) )
1063 {
1064 SCIP_VAR** vars;
1065 int nbinvars = SCIPgetNBinVars(scip);
1066 int nintvars = SCIPgetNIntVars(scip);
1067 int nimplvars = SCIPgetNImplVars(scip);
1068 int nvars = SCIPgetNVars(scip);
1069 int vartypeend[] = {
1070 nbinvars,
1071 nbinvars + nintvars,
1072 nbinvars + nintvars + nimplvars,
1073 nvars
1074 };
1075 const char* vartypenames[] = {
1076 "binary",
1077 "integer",
1078 "implicit integer",
1079 "continuous"
1080 };
1081 int nvartypefixed[4];
1082 int nvarsfixed = 0;
1083 int depth;
1084 int probingdepth;
1085 int vartypestart = 0;
1086 int v;
1087 int p;
1088
1089 vars = SCIPgetVars(scip);
1090 BMSclearMemoryArray(nvartypefixed, nvartypes);
1091
1092 /* loop over vartypes and count fixings */
1093 for( p = 0; p < nvartypes; ++p )
1094 {
1095 for( v = vartypestart; v < vartypeend[p]; ++v )
1096 {
1097 if( SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v])) )
1098 ++nvartypefixed[p];
1099 }
1100 nvarsfixed += nvartypefixed[p];
1101 vartypestart = vartypeend[p];
1102 }
1103
1104 depth = SCIPgetDepth(scip);
1105 probingdepth = SCIPgetProbingDepth(scip);
1106
1107 ptr += SCIPsnprintf(ptr, len, "Depth: (%d total, %d probing) ", depth, probingdepth);
1108 ptr += SCIPsnprintf(ptr, len, "Fixed/Variables: %d / %d (", nvarsfixed, vartypeend[nvartypes - 1]);
1109
1110 for( p = 0; p < nvartypes; ++p )
1111 {
1112 int ntypevars = vartypeend[p] - (p == 0 ? 0 : vartypeend[p - 1]);
1113 ptr += SCIPsnprintf(ptr, len, "%d / %d %s%s", nvartypefixed[p], ntypevars, vartypenames[p], p < (nvartypes - 1) ? ", " : ")");
1114 }
1115 }
1116 else
1117 {
1118 (void) SCIPsnprintf(strbuf, len, "Not in probing");
1119 }
1120
1121 return strbuf;
1122}
1123
1124/** gets the candidate score and preferred rounding direction for a candidate variable */
1126 SCIP* scip, /**< SCIP data structure */
1127 SCIP_DIVESET* diveset, /**< general diving settings */
1128 SCIP_DIVETYPE divetype, /**< represents different methods for a dive set to explore the next children */
1129 SCIP_VAR* divecand, /**< the candidate for which the branching direction is requested */
1130 SCIP_Real divecandsol, /**< LP solution value of the candidate */
1131 SCIP_Real divecandfrac, /**< fractionality of the candidate */
1132 SCIP_Real* candscore, /**< pointer to store the candidate score */
1133 SCIP_Bool* roundup /**< pointer to store whether preferred direction for diving is upwards */
1134 )
1135{
1136 assert(scip != NULL);
1137 assert(candscore != NULL);
1138 assert(roundup != NULL);
1139 assert(divecand != NULL);
1140
1141 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetDivesetScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1142
1143 SCIP_CALL( SCIPdivesetGetScore(diveset, scip->set, divetype, divecand, divecandsol, divecandfrac, candscore,
1144 roundup) );
1145
1146 return SCIP_OKAY;
1147}
1148
1149/** update diveset LP statistics, should be called after every LP solved by this diving heuristic */
1151 SCIP* scip, /**< SCIP data structure */
1152 SCIP_DIVESET* diveset, /**< diving settings */
1153 SCIP_Longint niterstoadd, /**< additional number of LP iterations to be added */
1154 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
1155 )
1156{
1157 assert(scip != NULL);
1158 assert(diveset != NULL);
1159
1160 SCIPdivesetUpdateLPStats(diveset, scip->stat, niterstoadd, divecontext);
1161}
1162
1163/** update diveset statistics and global diveset statistics */
1165 SCIP* scip, /**< SCIP data structure */
1166 SCIP_DIVESET* diveset, /**< diveset to be reset */
1167 int nprobingnodes, /**< the number of probing nodes explored this time */
1168 int nbacktracks, /**< the number of backtracks during probing this time */
1169 SCIP_Longint nsolsfound, /**< the number of solutions found */
1170 SCIP_Longint nbestsolsfound, /**< the number of best solutions found */
1171 SCIP_Longint nconflictsfound, /**< number of new conflicts found this time */
1172 SCIP_Bool leavewassol, /**< was a solution found at the leaf? */
1173 SCIP_DIVECONTEXT divecontext /**< context for diving statistics */
1174 )
1175{
1176 assert(scip != NULL);
1177 assert(diveset != NULL);
1178 assert(SCIPinProbing(scip));
1179
1180 SCIPdivesetUpdateStats(diveset, scip->stat, SCIPgetDepth(scip), nprobingnodes, nbacktracks, nsolsfound,
1181 nbestsolsfound, nconflictsfound, leavewassol, divecontext);
1182}
1183
1184/** enforces a probing/diving solution by suggesting bound changes that maximize the score w.r.t. the current diving settings
1185 *
1186 * the process is guided by the enforcement priorities of the constraint handlers and the scoring mechanism provided by
1187 * the dive set.
1188 * Constraint handlers may suggest diving bound changes in decreasing order of their enforcement priority, based on the
1189 * solution values in the solution @p sol and the current local bounds of the variables. A diving bound change
1190 * is a triple (variable,branching direction,value) and is used inside SCIPperformGenericDivingAlgorithm().
1191 *
1192 * After a successful call, SCIP holds two arrays of suggested dive bound changes, one for the preferred child
1193 * and one for the alternative.
1194 *
1195 * @see SCIPgetDiveBoundChangeData() for retrieving the dive bound change suggestions.
1196 *
1197 * The method stops after the first constraint handler was successful
1198 *
1199 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1200 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1201 *
1202 * @pre This method can be called if @p scip is in one of the following stages:
1203 * - \ref SCIP_STAGE_SOLVING
1204 *
1205 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
1206 */
1208 SCIP* scip, /**< SCIP data structure */
1209 SCIP_DIVESET* diveset, /**< diving settings to control scoring */
1210 SCIP_SOL* sol, /**< current solution of diving mode */
1211 SCIP_Bool* success, /**< pointer to store whether constraint handler successfully found a variable */
1212 SCIP_Bool* infeasible /**< pointer to store whether the current node was detected to be infeasible */
1213 )
1214{
1215 int i;
1216
1217 assert(scip != NULL);
1218 assert(diveset != NULL);
1219 assert(SCIPinProbing(scip));
1220 assert(infeasible != NULL);
1221 assert(success != NULL);
1222
1223 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetDiveBoundChanges", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1224
1225 *success = FALSE;
1226 *infeasible = FALSE;
1227
1228 /* we invalidate the previously stored bound changes */
1230
1231 /* loop over constraint handlers until a constraint handler successfully found a variable/value assignment for proceeding
1232 * or a constraint handler detected the infeasibility of the local node
1233 */
1234 for( i = 0; i < scip->set->nconshdlrs && !(*success || *infeasible); ++i )
1235 {
1236 SCIP_CALL( SCIPconshdlrGetDiveBoundChanges(scip->set->conshdlrs_enfo[i], scip->set, diveset, sol,
1237 success, infeasible) );
1238 }
1239
1240#ifndef NDEBUG
1241 /* check if the constraint handler correctly assigned values to the dive set */
1242 if( *success )
1243 {
1244 SCIP_VAR** bdchgvars;
1245 SCIP_BRANCHDIR* bdchgdirs;
1246 SCIP_Real* values;
1247 int nbdchanges;
1248 SCIPtreeGetDiveBoundChangeData(scip->tree, &bdchgvars, &bdchgdirs, &values, &nbdchanges, TRUE);
1249 assert(nbdchanges > 0);
1250 SCIPtreeGetDiveBoundChangeData(scip->tree, &bdchgvars, &bdchgdirs, &values, &nbdchanges, FALSE);
1251 assert(nbdchanges > 0);
1252 }
1253#endif
1254
1255 return SCIP_OKAY;
1256}
1257
1258/** adds a diving bound change to the diving bound change storage of SCIP together with the information if this is a
1259 * bound change for the preferred direction or not
1260 *
1261 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1262 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1263 *
1264 * @pre This method can be called if @p scip is in one of the following stages:
1265 * - \ref SCIP_STAGE_SOLVING
1266 *
1267 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
1268 */
1270 SCIP* scip, /**< SCIP data structure */
1271 SCIP_VAR* var, /**< variable to apply the bound change to */
1272 SCIP_BRANCHDIR dir, /**< direction of the bound change */
1273 SCIP_Real value, /**< value to adjust this variable bound to */
1274 SCIP_Bool preferred /**< is this a bound change for the preferred child? */
1275 )
1276{
1277 assert(scip->tree != NULL);
1278 assert(scip->mem->probmem != NULL);
1279 assert(SCIPinProbing(scip));
1280
1281 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddDiveBoundChange", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1282
1283 SCIP_CALL( SCIPtreeAddDiveBoundChange(scip->tree, scip->mem->probmem, var, dir, value, preferred) );
1284
1285 return SCIP_OKAY;
1286}
1287
1288/** get the dive bound change data for the preferred or the alternative direction
1289 *
1290 * @pre This method can be called if @p scip is in one of the following stages:
1291 * - \ref SCIP_STAGE_SOLVING
1292 *
1293 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
1294 */
1296 SCIP* scip, /**< SCIP data structure */
1297 SCIP_VAR*** variables, /**< pointer to store variables for the specified direction */
1298 SCIP_BRANCHDIR** directions, /**< pointer to store the branching directions */
1299 SCIP_Real** values, /**< pointer to store bound change values */
1300 int* ndivebdchgs, /**< pointer to store the number of dive bound changes */
1301 SCIP_Bool preferred /**< should the dive bound changes for the preferred child be output? */
1302 )
1303{
1304 assert(variables != NULL);
1305 assert(directions != NULL);
1306 assert(values != NULL);
1307 assert(ndivebdchgs != NULL);
1308 assert(SCIPinProbing(scip));
1309
1310 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDiveBoundChangeData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1311
1312 SCIPtreeGetDiveBoundChangeData(scip->tree, variables, directions, values, ndivebdchgs, preferred);
1313}
1314
1315/** clear the dive bound change data structures
1316 *
1317 * @pre This method can be called if @p scip is in one of the following stages:
1318 * - \ref SCIP_STAGE_SOLVING
1319 *
1320 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
1321 */
1323 SCIP* scip /**< SCIP data structure */
1324 )
1325{
1326 assert(scip->tree != NULL);
1327
1328 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPclearDiveBoundChanges", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1329
1331}
SCIP_Real * r
Definition: circlepacking.c:59
internal methods for conflict analysis
SCIP_RETCODE SCIPconflictAnalyzeLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *success)
SCIP_RETCODE SCIPconshdlrGetDiveBoundChanges(SCIP_CONSHDLR *conshdlr, SCIP_SET *set, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
Definition: cons.c:3589
internal methods for constraints and constraint handlers
methods for debugging
#define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
Definition: debug.h:364
#define NULL
Definition: def.h:248
#define SCIP_Longint
Definition: def.h:141
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIPABORT()
Definition: def.h:327
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:444
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2340
int SCIPgetNImplVars(SCIP *scip)
Definition: scip_prob.c:2387
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2293
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10511
SCIP_Bool SCIPisExact(SCIP *scip)
Definition: scip_exact.c:193
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip_lp.c:253
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip_mem.h:70
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:64
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:8473
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:8493
SCIP_RETCODE SCIPaddRowProbing(SCIP *scip, SCIP_ROW *row)
Definition: scip_probing.c:913
void SCIPclearDiveBoundChanges(SCIP *scip)
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:199
void SCIPupdateDivesetStats(SCIP *scip, SCIP_DIVESET *diveset, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavewassol, SCIP_DIVECONTEXT divecontext)
SCIP_RETCODE SCIPapplyCutsProbing(SCIP *scip, SCIP_Bool *cutoff)
Definition: scip_probing.c:953
void SCIPgetDiveBoundChangeData(SCIP *scip, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
SCIP_RETCODE SCIPgetDiveBoundChanges(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *sol, SCIP_Bool *success, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPgetDivesetScore(SCIP *scip, SCIP_DIVESET *diveset, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:346
SCIP_RETCODE SCIPsetProbingLPState(SCIP *scip, SCIP_LPISTATE **lpistate, SCIP_LPINORMS **lpinorms, SCIP_Bool primalfeas, SCIP_Bool dualfeas)
Definition: scip_probing.c:882
char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
SCIP_Bool SCIPisObjChangedProbing(SCIP *scip)
Definition: scip_probing.c:553
SCIP_RETCODE SCIPsolveProbingRelax(SCIP *scip, SCIP_Bool *cutoff)
Definition: scip_probing.c:982
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:302
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPchgVarObjProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_probing.c:475
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
void SCIPupdateDivesetLPStats(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Longint niterstoadd, SCIP_DIVECONTEXT divecontext)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:98
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:120
SCIP_Real SCIPgetVarObjProbing(SCIP *scip, SCIP_VAR *var)
Definition: scip_probing.c:389
SCIP_RETCODE SCIPaddDiveBoundChange(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:825
SCIP_RETCODE SCIPpropagateProbingImplications(SCIP *scip, SCIP_Bool *cutoff)
Definition: scip_probing.c:690
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:419
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:261
SCIP_RETCODE SCIPsolveProbingLPWithPricing(SCIP *scip, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:849
const char * SCIPrelaxGetName(SCIP_RELAX *relax)
Definition: relax.c:557
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:672
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
void SCIPdivesetUpdateLPStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, SCIP_Longint niterstoadd, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:787
void SCIPdivesetUpdateStats(SCIP_DIVESET *diveset, SCIP_STAT *stat, int depth, int nprobingnodes, int nbacktracks, SCIP_Longint nsolsfound, SCIP_Longint nbestsolsfound, SCIP_Longint nconflictsfound, SCIP_Bool leavesol, SCIP_DIVECONTEXT divecontext)
Definition: heur.c:203
SCIP_RETCODE SCIPdivesetGetScore(SCIP_DIVESET *diveset, SCIP_SET *set, SCIP_DIVETYPE divetype, SCIP_VAR *divecand, SCIP_Real divecandsol, SCIP_Real divecandfrac, SCIP_Real *candscore, SCIP_Bool *roundup)
Definition: heur.c:834
internal methods for primal heuristics
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:18261
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13420
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:18188
SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool forcedlpsolve, SCIP_Bool *lperror)
Definition: lp.c:12680
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:18271
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:18251
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:18282
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10451
SCIP_RETCODE SCIPlpAddRow(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_ROW *row, int depth)
Definition: lp.c:9759
internal methods for LP management
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2825
internal methods for storing and manipulating the main problem
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public data structures and miscellaneous methods
public methods for relaxation handlers
public methods for branch and bound tree
public methods for problem variables
SCIP_RETCODE SCIPrelaxExec(SCIP_RELAX *relax, SCIP_SET *set, SCIP_TREE *tree, SCIP_STAT *stat, int depth, SCIP_Real *lowerbound, SCIP_RESULT *result)
Definition: relax.c:354
internal methods for relaxators
public methods for exact solving
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
static SCIP_RETCODE solveProbingLP(SCIP *scip, int itlim, SCIP_Bool pricing, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:712
public methods for the probing mode
public methods for querying solving statistics
public methods for the branch-and-bound tree
int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
Definition: sepastore.c:1183
SCIP_RETCODE SCIPsepastoreApplyCuts(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_EFFICIACYCHOICE efficiacychoice, SCIP_Bool *cutoff)
Definition: sepastore.c:935
internal methods for storing separated cuts
void SCIPsetSortRelaxs(SCIP_SET *set)
Definition: set.c:4455
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6537
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6380
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6557
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6597
internal methods for global SCIP settings
SCIP_RETCODE SCIPinitConssLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_Bool firstsubtreeinit, SCIP_Bool *cutoff)
Definition: solve.c:1225
SCIP_RETCODE SCIPpriceLoop(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_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, int *npricedcolvars, SCIP_Bool *mustsepa, SCIP_Bool *lperror, SCIP_Bool *aborted)
Definition: solve.c:2211
SCIP_RETCODE SCIPpropagateDomains(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CONFLICT *conflict, SCIP_CLIQUETABLE *cliquetable, int depth, int maxrounds, SCIP_PROPTIMING timingmask, SCIP_Bool *cutoff)
Definition: solve.c:658
internal methods for main solving loop and node processing
void SCIPstatEnableVarHistory(SCIP_STAT *stat)
Definition: stat.c:191
void SCIPstatDisableVarHistory(SCIP_STAT *stat)
Definition: stat.c:181
internal methods for problem statistics
union SCIP_Node::@21 data
SCIP_PROBINGNODE * probingnode
Definition: struct_tree.h:149
SCIP_VAR ** origobjvars
Definition: struct_tree.h:63
SCIP_Real * origobjvals
Definition: struct_tree.h:64
SCIP_Real unchangedobj
Definition: struct_var.h:264
data structures for LP management
datastructures for block memory pools and memory buffers
SCIP main data structure.
datastructures for global SCIP settings
datastructures for problem statistics
data structures for branch and bound tree
datastructures for problem variables
Definition: heur_padm.c:135
SCIP_Bool SCIPtreeIsFocusNodeLPConstructed(SCIP_TREE *tree)
Definition: tree.c:9442
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:9361
SCIP_Bool SCIPtreeProbingObjChanged(SCIP_TREE *tree)
Definition: tree.c:9540
SCIP_RETCODE SCIPnodeAddBoundchg(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_VAR *var, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype, SCIP_Bool probingchange)
Definition: tree.c:2539
int SCIPtreeGetProbingDepth(SCIP_TREE *tree)
Definition: tree.c:9507
SCIP_RETCODE SCIPtreeStartProbing(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PROB *transprob, SCIP_Bool strongbranching)
Definition: tree.c:7377
SCIP_RETCODE SCIPtreeSetProbingLPState(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_LP *lp, SCIP_LPISTATE **lpistate, SCIP_LPINORMS **lpinorms, SCIP_Bool primalfeas, SCIP_Bool dualfeas)
Definition: tree.c:7470
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:9462
void SCIPtreeMarkProbingObjChanged(SCIP_TREE *tree)
Definition: tree.c:9551
SCIP_RETCODE SCIPtreeAddDiveBoundChange(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Bool preferred)
Definition: tree.c:7216
SCIP_RETCODE SCIPtreeLoadProbingLPState(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: tree.c:7524
SCIP_RETCODE SCIPnodePropagateImplics(SCIP_NODE *node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff)
Definition: tree.c:3100
SCIP_RETCODE SCIPtreeEndProbing(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_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable)
Definition: tree.c:7814
void SCIPtreeGetDiveBoundChangeData(SCIP_TREE *tree, SCIP_VAR ***variables, SCIP_BRANCHDIR **directions, SCIP_Real **values, int *ndivebdchgs, SCIP_Bool preferred)
Definition: tree.c:7248
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:9479
SCIP_RETCODE SCIPtreeCreateProbingNode(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: tree.c:7445
SCIP_RETCODE SCIPtreeMarkProbingNodeHasLP(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_LP *lp)
Definition: tree.c:7606
SCIP_RETCODE SCIPtreeBacktrackProbing(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_PRIMAL *primal, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, int probingdepth)
Definition: tree.c:7780
void SCIPtreeClearDiveBoundChanges(SCIP_TREE *tree)
Definition: tree.c:7271
internal methods for branch and bound tree
enum SCIP_DiveContext SCIP_DIVECONTEXT
Definition: type_heur.h:73
unsigned int SCIP_DIVETYPE
Definition: type_heur.h:63
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:57
@ SCIP_LPSOLSTAT_NOTSOLVED
Definition: type_lp.h:43
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:44
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition: type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition: type_lp.h:47
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_CUTOFF
Definition: type_result.h:48
@ SCIP_REDUCEDDOM
Definition: type_result.h:51
@ SCIP_CONSADDED
Definition: type_result.h:52
@ SCIP_SUSPENDED
Definition: type_result.h:57
@ SCIP_SEPARATED
Definition: type_result.h:49
@ SCIP_SUCCESS
Definition: type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_INVALIDRESULT
Definition: type_retcode.h:53
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
@ SCIP_MAXDEPTHLEVEL
Definition: type_retcode.h:59
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_EFFICIACYCHOICE_LP
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
#define SCIP_PROPTIMING_ALWAYS
Definition: type_timing.h:73
@ SCIP_NODETYPE_PROBINGNODE
Definition: type_tree.h:42
SCIP_Real SCIPvarGetObjLP(SCIP_VAR *var)
Definition: var.c:18522
SCIP_RETCODE SCIPvarChgObj(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_Real newobj)
Definition: var.c:9419
void SCIPvarAdjustLb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *lb)
Definition: var.c:9910
void SCIPvarAdjustUb(SCIP_VAR *var, SCIP_SET *set, SCIP_Real *ub)
Definition: var.c:9961
internal methods for problem variables