1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2021 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /**@file scip_prob.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for global and local (sub)problems
19 * @author Tobias Achterberg
20 * @author Timo Berthold
21 * @author Gerald Gamrath
22 * @author Leona Gottwald
23 * @author Stefan Heinz
24 * @author Gregor Hendel
25 * @author Thorsten Koch
26 * @author Alexander Martin
27 * @author Marc Pfetsch
28 * @author Michael Winkler
29 * @author Kati Wolter
30 *
31 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32 */
33
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36 #include "blockmemshell/memory.h"
37 #include "scip/benders.h"
38 #include "scip/clock.h"
39 #include "scip/concurrent.h"
40 #include "scip/conflictstore.h"
41 #include "scip/cons.h"
42 #include "scip/dcmp.h"
43 #include "scip/debug.h"
44 #include "scip/lp.h"
45 #include "scip/pricer.h"
46 #include "scip/pricestore.h"
47 #include "scip/primal.h"
48 #include "scip/prob.h"
49 #include "scip/pub_cons.h"
50 #include "scip/pub_event.h"
51 #include "scip/pub_message.h"
52 #include "scip/pub_misc.h"
53 #include "scip/pub_reader.h"
54 #include "scip/pub_sol.h"
55 #include "scip/pub_tree.h"
56 #include "scip/pub_var.h"
57 #include "scip/reader.h"
58 #include "scip/reopt.h"
59 #include "scip/scip_cons.h"
60 #include "scip/scip_general.h"
61 #include "scip/scip_mem.h"
62 #include "scip/scip_numerics.h"
63 #include "scip/scip_param.h"
64 #include "scip/scip_prob.h"
65 #include "scip/scip_randnumgen.h"
66 #include "scip/scip_sol.h"
67 #include "scip/scip_solve.h"
68 #include "scip/scip_solvingstats.h"
69 #include "scip/scip_timing.h"
70 #include "scip/scip_var.h"
71 #include "scip/set.h"
72 #include "scip/stat.h"
73 #include "scip/struct_cons.h"
74 #include "scip/struct_lp.h"
75 #include "scip/struct_mem.h"
76 #include "scip/struct_primal.h"
77 #include "scip/struct_prob.h"
78 #include "scip/struct_scip.h"
79 #include "scip/struct_set.h"
80 #include "scip/struct_stat.h"
81 #include "scip/struct_var.h"
82 #include "scip/syncstore.h"
83 #include "scip/tree.h"
84 #include <stdio.h>
85 #include <string.h>
86
87 /** creates empty problem and initializes all solving data structures (the objective sense is set to MINIMIZE)
88 * If the problem type requires the use of variable pricers, these pricers should be added to the problem with calls
89 * to SCIPactivatePricer(). These pricers are automatically deactivated, when the problem is freed.
90 *
91 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
92 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
93 *
94 * @pre This method can be called if @p scip is in one of the following stages:
95 * - \ref SCIP_STAGE_INIT
96 * - \ref SCIP_STAGE_PROBLEM
97 * - \ref SCIP_STAGE_TRANSFORMED
98 * - \ref SCIP_STAGE_PRESOLVING
99 * - \ref SCIP_STAGE_PRESOLVED
100 * - \ref SCIP_STAGE_SOLVING
101 * - \ref SCIP_STAGE_SOLVED
102 * - \ref SCIP_STAGE_FREE
103 *
104 * @post After calling this method, \SCIP reaches the following stage:
105 * - \ref SCIP_STAGE_PROBLEM
106 */
107 SCIP_RETCODE SCIPcreateProb(
108 SCIP* scip, /**< SCIP data structure */
109 const char* name, /**< problem name */
110 SCIP_DECL_PROBDELORIG ((*probdelorig)), /**< frees user data of original problem */
111 SCIP_DECL_PROBTRANS ((*probtrans)), /**< creates user data of transformed problem by transforming original user data */
112 SCIP_DECL_PROBDELTRANS((*probdeltrans)), /**< frees user data of transformed problem */
113 SCIP_DECL_PROBINITSOL ((*probinitsol)), /**< solving process initialization method of transformed data */
114 SCIP_DECL_PROBEXITSOL ((*probexitsol)), /**< solving process deinitialization method of transformed data */
115 SCIP_DECL_PROBCOPY ((*probcopy)), /**< copies user data if you want to copy it to a subscip, or NULL */
116 SCIP_PROBDATA* probdata /**< user problem data set by the reader */
117 )
118 {
119 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateProb", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) );
120
121 /* free old problem */
122 SCIP_CALL( SCIPfreeProb(scip) );
123 assert(scip->set->stage == SCIP_STAGE_INIT);
124
125 /* switch stage to PROBLEM */
126 scip->set->stage = SCIP_STAGE_PROBLEM;
127
128 SCIP_CALL( SCIPstatCreate(&scip->stat, scip->mem->probmem, scip->set, NULL, NULL, scip->messagehdlr) );
129
130 SCIP_CALL( SCIPprobCreate(&scip->origprob, scip->mem->probmem, scip->set, name,
131 probdelorig, probtrans, probdeltrans, probinitsol, probexitsol, probcopy, probdata, FALSE) );
132
133 /* create solution pool for original solution candidates */
134 SCIP_CALL( SCIPprimalCreate(&scip->origprimal) );
135
136 /* create conflict pool for storing conflict constraints */
137 SCIP_CALL( SCIPconflictstoreCreate(&scip->conflictstore, scip->set) );
138
139 /* initialize reoptimization structure, if needed */
140 SCIP_CALL( SCIPenableReoptimization(scip, scip->set->reopt_enable) );
141
142 SCIP_CALL( SCIPdecompstoreCreate(&scip->decompstore, SCIPblkmem(scip), SCIP_DECOMPSTORE_CAPA) );
143
144 return SCIP_OKAY;
145 }
146
147 /** creates empty problem and initializes all solving data structures (the objective sense is set to MINIMIZE)
148 * all callback methods will be set to NULL and can be set afterwards, if needed, via SCIPsetProbDelorig(),
149 * SCIPsetProbTrans(), SCIPsetProbDeltrans(), SCIPsetProbInitsol(), SCIPsetProbExitsol(), and
150 * SCIPsetProbCopy()
151 * If the problem type requires the use of variable pricers, these pricers should be added to the problem with calls
152 * to SCIPactivatePricer(). These pricers are automatically deactivated, when the problem is freed.
153 *
154 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
155 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
156 *
157 * @pre This method can be called if @p scip is in one of the following stages:
158 * - \ref SCIP_STAGE_INIT
159 * - \ref SCIP_STAGE_PROBLEM
160 * - \ref SCIP_STAGE_TRANSFORMED
161 * - \ref SCIP_STAGE_PRESOLVING
162 * - \ref SCIP_STAGE_PRESOLVED
163 * - \ref SCIP_STAGE_SOLVING
164 * - \ref SCIP_STAGE_SOLVED
165 * - \ref SCIP_STAGE_FREE
166 *
167 * @post After calling this method, \SCIP reaches the following stage:
168 * - \ref SCIP_STAGE_PROBLEM
169 */
170 SCIP_RETCODE SCIPcreateProbBasic(
171 SCIP* scip, /**< SCIP data structure */
172 const char* name /**< problem name */
173 )
174 {
175 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateProbBasic", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) );
176
177 SCIP_CALL( SCIPcreateProb(scip, name, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
178
179 return SCIP_OKAY;
180 }
181
182 /** sets callback to free user data of original problem
183 *
184 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
185 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
186 *
187 * @pre This method can be called if @p scip is in one of the following stages:
188 * - \ref SCIP_STAGE_PROBLEM
189 */
190 SCIP_RETCODE SCIPsetProbDelorig(
191 SCIP* scip, /**< SCIP data structure */
192 SCIP_DECL_PROBDELORIG ((*probdelorig)) /**< frees user data of original problem */
193 )
194 {
195 assert(scip != NULL);
196 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbDelorig", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
197
198 SCIPprobSetDelorig(scip->origprob, probdelorig);
199
200 return SCIP_OKAY;
201 }
202
203 /** sets callback to create user data of transformed problem by transforming original user data
204 *
205 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
206 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
207 *
208 * @pre This method can be called if @p scip is in one of the following stages:
209 * - \ref SCIP_STAGE_PROBLEM
210 */
211 SCIP_RETCODE SCIPsetProbTrans(
212 SCIP* scip, /**< SCIP data structure */
213 SCIP_DECL_PROBTRANS ((*probtrans)) /**< creates user data of transformed problem by transforming original user data */
214 )
215 {
216 assert(scip != NULL);
217 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbTrans", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
218
219 SCIPprobSetTrans(scip->origprob, probtrans);
220
221 return SCIP_OKAY;
222 }
223
224 /** sets callback to free user data of transformed problem
225 *
226 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
227 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
228 *
229 * @pre This method can be called if @p scip is in one of the following stages:
230 * - \ref SCIP_STAGE_PROBLEM
231 */
232 SCIP_RETCODE SCIPsetProbDeltrans(
233 SCIP* scip, /**< SCIP data structure */
234 SCIP_DECL_PROBDELTRANS((*probdeltrans)) /**< frees user data of transformed problem */
235 )
236 {
237 assert(scip != NULL);
238 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbDeltrans", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
239
240 SCIPprobSetDeltrans(scip->origprob, probdeltrans);
241
242 return SCIP_OKAY;
243 }
244
245 /** sets solving process initialization callback of transformed data
246 *
247 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
248 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
249 *
250 * @pre This method can be called if @p scip is in one of the following stages:
251 * - \ref SCIP_STAGE_PROBLEM
252 */
253 SCIP_RETCODE SCIPsetProbInitsol(
254 SCIP* scip, /**< SCIP data structure */
255 SCIP_DECL_PROBINITSOL ((*probinitsol)) /**< solving process initialization method of transformed data */
256 )
257 {
258 assert(scip != NULL);
259
260 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbInitsol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
261
262 SCIPprobSetInitsol(scip->origprob, probinitsol);
263
264 return SCIP_OKAY;
265 }
266
267 /** sets solving process deinitialization callback of transformed data
268 *
269 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
270 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
271 *
272 * @pre This method can be called if @p scip is in one of the following stages:
273 * - \ref SCIP_STAGE_PROBLEM
274 */
275 SCIP_RETCODE SCIPsetProbExitsol(
276 SCIP* scip, /**< SCIP data structure */
277 SCIP_DECL_PROBEXITSOL ((*probexitsol)) /**< solving process deinitialization method of transformed data */
278 )
279 {
280 assert(scip != NULL);
281 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbExitsol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
282
283 SCIPprobSetExitsol(scip->origprob, probexitsol);
284
285 return SCIP_OKAY;
286 }
287
288 /** sets callback to copy user data to a subscip
289 *
290 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
291 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
292 *
293 * @pre This method can be called if @p scip is in one of the following stages:
294 * - \ref SCIP_STAGE_PROBLEM
295 */
296 SCIP_RETCODE SCIPsetProbCopy(
297 SCIP* scip, /**< SCIP data structure */
298 SCIP_DECL_PROBCOPY ((*probcopy)) /**< copies user data if you want to copy it to a subscip, or NULL */
299 )
300 {
301 assert(scip != NULL);
302 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbCopy", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
303
304 SCIPprobSetCopy(scip->origprob, probcopy);
305
306 return SCIP_OKAY;
307 }
308
309 /** reads problem from file and initializes all solving data structures
310 *
311 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
312 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
313 *
314 * @pre This method can be called if @p scip is in one of the following stages:
315 * - \ref SCIP_STAGE_INIT
316 * - \ref SCIP_STAGE_PROBLEM
317 * - \ref SCIP_STAGE_TRANSFORMED
318 * - \ref SCIP_STAGE_INITPRESOLVE
319 * - \ref SCIP_STAGE_PRESOLVING
320 * - \ref SCIP_STAGE_EXITPRESOLVE
321 * - \ref SCIP_STAGE_PRESOLVED
322 * - \ref SCIP_STAGE_SOLVING
323 * - \ref SCIP_STAGE_EXITSOLVE
324 *
325 * @post After the method was called, \SCIP is in one of the following stages:
326 * - \ref SCIP_STAGE_INIT if reading failed (usually, when a SCIP_READERROR occurs)
327 * - \ref SCIP_STAGE_PROBLEM if the problem file was successfully read
328 */
329 SCIP_RETCODE SCIPreadProb(
330 SCIP* scip, /**< SCIP data structure */
331 const char* filename, /**< problem file name */
332 const char* extension /**< extension of the desired file reader,
333 * or NULL if file extension should be used */
334 )
335 {
336 SCIP_RETCODE retcode;
337 SCIP_RESULT result;
338 SCIP_Bool usevartable;
339 SCIP_Bool useconstable;
340 int i;
341 char* tmpfilename;
342 char* fileextension;
343
344 assert(scip != NULL);
345 assert(filename != NULL);
346
347 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadProb", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
348
349 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
350 SCIP_CALL( SCIPgetBoolParam(scip, "misc/useconstable", &useconstable) );
351
352 if( !usevartable || !useconstable )
353 {
354 SCIPerrorMessage("Cannot read problem if vartable or constable is disabled. Make sure parameters 'misc/usevartable' and 'misc/useconstable' are set to TRUE.\n");
355 return SCIP_READERROR;
356 }
357
358 /* try all readers until one could read the file */
359 result = SCIP_DIDNOTRUN;
360
361 /* copy filename */
362 SCIP_CALL( SCIPduplicateBufferArray(scip, &tmpfilename, filename, (int)strlen(filename)+1) );
363
364 fileextension = NULL;
365 if( extension == NULL )
366 {
367 /* get extension from filename */
368 SCIPsplitFilename(tmpfilename, NULL, NULL, &fileextension, NULL);
369 }
370
371 for( i = 0; i < scip->set->nreaders && result == SCIP_DIDNOTRUN; ++i )
372 {
373 retcode = SCIPreaderRead(scip->set->readers[i], scip->set, filename,
374 extension != NULL ? extension : fileextension, &result);
375
376 /* check for reader errors */
377 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
378 goto TERMINATE;
379 SCIP_CALL( retcode );
380 }
381
382 switch( result )
383 {
384 case SCIP_DIDNOTRUN:
385 retcode = SCIP_PLUGINNOTFOUND;
386 break;
387 case SCIP_SUCCESS:
388 if( scip->origprob != NULL )
389 {
390 SCIP_Real readingtime;
391
392 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
393 "original problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
394 scip->origprob->nvars, scip->origprob->nbinvars, scip->origprob->nintvars,
395 scip->origprob->nimplvars, scip->origprob->ncontvars,
396 scip->origprob->nconss);
397
398 /* in full verbose mode we will also print the number of constraints per constraint handler */
399 if( scip->set->disp_verblevel == SCIP_VERBLEVEL_FULL )
400 {
401 int* nconss;
402 int c;
403 int h;
404
405 SCIP_CALL( SCIPallocClearBufferArray(scip, &nconss, scip->set->nconshdlrs) );
406
407 /* loop over all constraints and constraint-handlers to count for each type the amount of original
408 * constraints
409 */
410 for( c = scip->origprob->nconss - 1; c >= 0; --c )
411 {
412 for( h = scip->set->nconshdlrs - 1; h >= 0; --h )
413 {
414 if( scip->origprob->conss[c]->conshdlr == scip->set->conshdlrs[h] )
415 {
416 ++(nconss[h]);
417 break;
418 }
419 }
420 /* constraint handler should be found */
421 assert(h >= 0);
422 }
423
424 /* loop over all constraints handlers for printing the number of original constraints */
425 for( h = 0; h < scip->set->nconshdlrs; ++h )
426 {
427 if( nconss[h] > 0 )
428 {
429 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
430 "%7d constraints of type <%s>\n", nconss[h], SCIPconshdlrGetName(scip->set->conshdlrs[h]));
431 }
432 }
433
434 SCIPfreeBufferArray(scip, &nconss);
435 }
436
437 /* in case the permutation seed is different to 0, permute the original problem */
438 if( scip->set->random_permutationseed > 0 )
439 {
440 SCIP_Bool permuteconss;
441 SCIP_Bool permutevars;
442 int permutationseed;
443
444 permuteconss = scip->set->random_permuteconss;
445 permutevars = scip->set->random_permutevars;
446 permutationseed = scip->set->random_permutationseed;
447
448 SCIP_CALL( SCIPpermuteProb(scip, (unsigned int)permutationseed, permuteconss, permutevars, permutevars, permutevars, permutevars) );
449 }
450
451 /* get reading time */
452 readingtime = SCIPgetReadingTime(scip);
453
454 /* display timing statistics */
455 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL,
456 "Reading Time: %.2f\n", readingtime);
457 }
458 retcode = SCIP_OKAY;
459 break;
460 default:
461 assert(i < scip->set->nreaders);
462 SCIPerrorMessage("invalid result code <%d> from reader <%s> reading file <%s>\n",
463 result, SCIPreaderGetName(scip->set->readers[i]), filename);
464 retcode = SCIP_READERROR;
465 } /*lint !e788*/
466
467 TERMINATE:
468 /* free buffer array */
469 SCIPfreeBufferArray(scip, &tmpfilename);
470
471 /* check if reading time should belong to solving time */
472 if( scip->set->time_reading )
473 {
474 SCIP_Real readingtime;
475
476 /* get reading time */
477 readingtime = SCIPgetReadingTime(scip);
478
479 /* add reading time to solving time */
480 SCIPclockSetTime(scip->stat->solvingtime, readingtime);
481 }
482
483 return retcode;
484 }
485
486 /** write original or transformed problem */
487 static
488 SCIP_RETCODE writeProblem(
489 SCIP* scip, /**< SCIP data structure */
490 const char* filename, /**< output file (or NULL for standard output) */
491 const char* extension, /**< extension of the desired file reader,
492 * or NULL if file extension should be used */
493 SCIP_Bool transformed, /**< output the transformed problem? */
494 SCIP_Bool genericnames /**< using generic variable and constraint names? */
495 )
496 {
497 SCIP_RETCODE retcode;
498 char* tmpfilename;
499 char* fileextension;
500 char* compression;
501 FILE* file;
502
503 assert(scip != NULL );
504
505 fileextension = NULL;
506 compression = NULL;
507 file = NULL;
508 tmpfilename = NULL;
509
510 if( filename != NULL && filename[0] != '\0' )
511 {
512 int success;
513
514 file = fopen(filename, "w");
515 if( file == NULL )
516 {
517 SCIPerrorMessage("cannot create file <%s> for writing\n", filename);
518 SCIPprintSysError(filename);
519 return SCIP_FILECREATEERROR;
520 }
521
522 /* get extension from filename,
523 * if an error occurred, close the file before returning */
524 if( BMSduplicateMemoryArray(&tmpfilename, filename, strlen(filename)+1) == NULL )
525 {
526 (void) fclose(file);
527 SCIPerrorMessage("Error <%d> in function call\n", SCIP_NOMEMORY);
528 return SCIP_NOMEMORY;
529 }
530
531 SCIPsplitFilename(tmpfilename, NULL, NULL, &fileextension, &compression);
532
533 if( compression != NULL )
534 {
535 SCIPmessagePrintWarning(scip->messagehdlr, "currently it is not possible to write files with any compression\n");
536 BMSfreeMemoryArray(&tmpfilename);
537 (void) fclose(file);
538 return SCIP_FILECREATEERROR;
539 }
540
541 if( extension == NULL && fileextension == NULL )
542 {
543 SCIPmessagePrintWarning(scip->messagehdlr, "filename <%s> has no file extension, select default <cip> format for writing\n", filename);
544 }
545
546 if( transformed )
547 retcode = SCIPprintTransProblem(scip, file, extension != NULL ? extension : fileextension, genericnames);
548 else
549 retcode = SCIPprintOrigProblem(scip, file, extension != NULL ? extension : fileextension, genericnames);
550
551 BMSfreeMemoryArray(&tmpfilename);
552
553 success = fclose(file);
554 if( success != 0 )
555 {
556 SCIPerrorMessage("An error occurred while closing file <%s>\n", filename);
557 return SCIP_FILECREATEERROR;
558 }
559 }
560 else
561 {
562 /* print to stdout */
563 if( transformed )
564 retcode = SCIPprintTransProblem(scip, NULL, extension, genericnames);
565 else
566 retcode = SCIPprintOrigProblem(scip, NULL, extension, genericnames);
567 }
568
569 /* check for write errors */
570 if( retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND )
571 return retcode;
572 else
573 {
574 SCIP_CALL( retcode );
575 }
576
577 return SCIP_OKAY;
578 }
579
580 /** writes original problem to file
581 *
582 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
583 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
584 *
585 * @pre This method can be called if @p scip is in one of the following stages:
586 * - \ref SCIP_STAGE_PROBLEM
587 * - \ref SCIP_STAGE_TRANSFORMING
588 * - \ref SCIP_STAGE_TRANSFORMED
589 * - \ref SCIP_STAGE_INITPRESOLVE
590 * - \ref SCIP_STAGE_PRESOLVING
591 * - \ref SCIP_STAGE_EXITPRESOLVE
592 * - \ref SCIP_STAGE_PRESOLVED
593 * - \ref SCIP_STAGE_INITSOLVE
594 * - \ref SCIP_STAGE_SOLVING
595 * - \ref SCIP_STAGE_SOLVED
596 * - \ref SCIP_STAGE_EXITSOLVE
597 * - \ref SCIP_STAGE_FREETRANS
598 */
599 SCIP_RETCODE SCIPwriteOrigProblem(
600 SCIP* scip, /**< SCIP data structure */
601 const char* filename, /**< output file (or NULL for standard output) */
602 const char* extension, /**< extension of the desired file reader,
603 * or NULL if file extension should be used */
604 SCIP_Bool genericnames /**< using generic variable and constraint names? */
605 )
606 {
607 SCIP_RETCODE retcode;
608
609 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteOrigProblem", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
610
611 assert( scip != NULL );
612 assert( scip->origprob != NULL );
613
614 retcode = writeProblem(scip, filename, extension, FALSE, genericnames);
615
616 /* check for write errors */
617 if( retcode == SCIP_FILECREATEERROR || retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND )
618 return retcode;
619 else
620 {
621 SCIP_CALL( retcode );
622 }
623
624 return SCIP_OKAY;
625 }
626
627 /** writes transformed problem which are valid in the current node to file
628 *
629 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
630 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
631 *
632 * @pre This method can be called if @p scip is in one of the following stages:
633 * - \ref SCIP_STAGE_TRANSFORMED
634 * - \ref SCIP_STAGE_INITPRESOLVE
635 * - \ref SCIP_STAGE_PRESOLVING
636 * - \ref SCIP_STAGE_EXITPRESOLVE
637 * - \ref SCIP_STAGE_PRESOLVED
638 * - \ref SCIP_STAGE_INITSOLVE
639 * - \ref SCIP_STAGE_SOLVING
640 * - \ref SCIP_STAGE_SOLVED
641 * - \ref SCIP_STAGE_EXITSOLVE
642 *
643 * @note If you want the write all constraints (including the once which are redundant for example), you need to set
644 * the parameter <write/allconss> to TRUE
645 */
646 SCIP_RETCODE SCIPwriteTransProblem(
647 SCIP* scip, /**< SCIP data structure */
648 const char* filename, /**< output file (or NULL for standard output) */
649 const char* extension, /**< extension of the desired file reader,
650 * or NULL if file extension should be used */
651 SCIP_Bool genericnames /**< using generic variable and constraint names? */
652 )
653 {
654 SCIP_RETCODE retcode;
655
656 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteTransProblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
657
658 assert( scip != NULL );
659 assert( scip->transprob != NULL );
660
661 retcode = writeProblem(scip, filename, extension, TRUE, genericnames);
662
663 /* check for write errors */
664 if( retcode == SCIP_FILECREATEERROR || retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND )
665 return retcode;
666 else
667 {
668 SCIP_CALL( retcode );
669 }
670
671 return SCIP_OKAY;
672 }
673
674 /** frees problem and solution process data
675 *
676 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
677 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
678 *
679 * @pre This method can be called if @p scip is in one of the following stages:
680 * - \ref SCIP_STAGE_INIT
681 * - \ref SCIP_STAGE_PROBLEM
682 * - \ref SCIP_STAGE_TRANSFORMED
683 * - \ref SCIP_STAGE_PRESOLVING
684 * - \ref SCIP_STAGE_PRESOLVED
685 * - \ref SCIP_STAGE_SOLVING
686 * - \ref SCIP_STAGE_SOLVED
687 * - \ref SCIP_STAGE_FREE
688 *
689 * @post After this method was called, SCIP is in the following stage:
690 * - \ref SCIP_STAGE_INIT
691 */
692 SCIP_RETCODE SCIPfreeProb(
693 SCIP* scip /**< SCIP data structure */
694 )
695 {
696 SCIP_Bool transsolorig;
697
698 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeProb", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) );
699
700 /* if we free the problem, we do not have to transfer transformed solutions to the original space, so temporarily disable it */
701 transsolorig = scip->set->misc_transsolsorig;
702 scip->set->misc_transsolsorig = FALSE;
703
704 SCIP_CALL( SCIPfreeTransform(scip) );
705 /* for some reason the free transform can generate events caught in the globalbnd eventhander
706 * which requires the concurrent so it must be freed afterwards this happened o instance fiber
707 */
708 SCIP_CALL( SCIPfreeConcurrent(scip) );
709
710 assert(scip->set->stage == SCIP_STAGE_INIT || scip->set->stage == SCIP_STAGE_PROBLEM);
711 scip->set->misc_transsolsorig = transsolorig;
712
713 if( scip->set->stage == SCIP_STAGE_PROBLEM )
714 {
715 int i;
716
717 /* free concsolvers and deinitialize the syncstore */
718 if( scip->set->nconcsolvers > 0 )
719 {
720 assert(SCIPsyncstoreIsInitialized(scip->syncstore));
721
722 SCIP_CALL( SCIPsetFreeConcsolvers(scip->set) );
723 SCIP_CALL( SCIPsyncstoreExit(scip->syncstore) );
724 }
725
726 /* deactivate all pricers */
727 for( i = scip->set->nactivepricers-1; i >= 0; --i )
728 {
729 SCIP_CALL( SCIPpricerDeactivate(scip->set->pricers[i], scip->set) );
730 }
731 assert(scip->set->nactivepricers == 0);
732
733 /* deactivate all Benders' decomposition */
734 for( i = scip->set->nactivebenders-1; i >= 0; --i )
735 {
736 SCIP_CALL( SCIPbendersDeactivate(scip->set->benders[i], scip->set) );
737 }
738 assert(scip->set->nactivebenders == 0);
739
740 /* free all debug data */
741 SCIP_CALL( SCIPdebugFreeDebugData(scip->set) );
742
743 /* free original primal solution candidate pool, original problem and problem statistics data structures */
744 if( scip->reopt != NULL )
745 {
746 SCIP_CALL( SCIPreoptFree(&scip->reopt, scip->set, scip->origprimal, scip->mem->probmem) );
747 }
748 SCIPdecompstoreFree(&scip->decompstore, SCIPblkmem(scip));
749 SCIP_CALL( SCIPconflictstoreFree(&scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) );
750 SCIP_CALL( SCIPprimalFree(&scip->origprimal, scip->mem->probmem) );
751 SCIP_CALL( SCIPprobFree(&scip->origprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) );
752 SCIP_CALL( SCIPstatFree(&scip->stat, scip->mem->probmem) );
753
754 /* readers */
755 for( i = 0; i < scip->set->nreaders; ++i )
756 {
757 SCIP_CALL( SCIPreaderResetReadingTime(scip->set->readers[i]) );
758 }
759
760 /* switch stage to INIT */
761 scip->set->stage = SCIP_STAGE_INIT;
762 }
763 assert(scip->set->stage == SCIP_STAGE_INIT);
764
765 return SCIP_OKAY;
766 }
767
768 /** permutes parts of the problem data structure
769 *
770 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
771 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
772 *
773 * @pre This method can be called if @p scip is in one of the following stages:
774 * - \ref SCIP_STAGE_PROBLEM
775 * - \ref SCIP_STAGE_TRANSFORMED
776 *
777 * @todo This need to be changed to use the new random number generator implemented in random.c
778 */
779 SCIP_RETCODE SCIPpermuteProb(
780 SCIP* scip, /**< SCIP data structure */
781 unsigned int randseed, /**< seed value for random generator */
782 SCIP_Bool permuteconss, /**< should the list of constraints in each constraint handler be permuted? */
783 SCIP_Bool permutebinvars, /**< should the list of binary variables be permuted? */
784 SCIP_Bool permuteintvars, /**< should the list of integer variables be permuted? */
785 SCIP_Bool permuteimplvars, /**< should the list of implicit integer variables be permuted? */
786 SCIP_Bool permutecontvars /**< should the list of continuous integer variables be permuted? */
787 )
788 {
789 SCIP_VAR** vars;
790 SCIP_CONSHDLR** conshdlrs;
791 SCIP_RANDNUMGEN* randnumgen;
792 SCIP_Bool permuted;
793 int nconshdlrs;
794 int nbinvars;
795 int nintvars;
796 int nimplvars;
797 int nvars;
798 int j;
799
800 assert(scip != NULL);
801 SCIP_CALL( SCIPcheckStage(scip, "SCIPpermuteProb", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
802
803 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, &nimplvars, NULL) );
804
805 assert(nvars == 0 || vars != NULL);
806 assert(nvars == nbinvars+nintvars+nimplvars+SCIPgetNContVars(scip));
807
808 conshdlrs = SCIPgetConshdlrs(scip);
809 nconshdlrs = SCIPgetNConshdlrs(scip);
810 assert(nconshdlrs == 0 || conshdlrs != NULL);
811
812 /* create a random number generator */
813 SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, randseed, TRUE) );
814
815 /* The constraint handler should not be permuted since they are called w.r.t. to certain properties; besides
816 * that the "conshdlrs" array should stay in the order as it is since this array is used to copy the plugins for
817 * sub-SCIPs and contains the dependencies between the constraint handlers; for example the linear constraint
818 * handler stays in front of all constraint handler which can upgrade a linear constraint (such as logicor,
819 * setppc, and knapsack).
820 */
821
822 permuted = FALSE;
823
824 /* for each constraint handler, permute its constraints */
825 if( permuteconss )
826 {
827 int i;
828
829 /* we must only permute active constraints */
830 if( SCIPisTransformed(scip) && !SCIPprobIsPermuted(scip->transprob) )
831 {
832 /* loop over all constraint handlers */
833 for( i = 0; i < nconshdlrs; ++i )
834 {
835 SCIP_CONS** conss;
836 int nconss;
837
838 conss = SCIPconshdlrGetConss(conshdlrs[i]);
839 nconss = SCIPconshdlrGetNActiveConss(conshdlrs[i]);
840
841 assert(nconss == 0 || conss != NULL);
842
843 SCIPrandomPermuteArray(randnumgen, (void**)conss, 0, nconss);
844
845 /* readjust the mapping of constraints to array positions */
846 for( j = 0; j < nconss; ++j )
847 conss[j]->consspos = j;
848
849 permuted = TRUE;
850 }
851 }
852 else if( !SCIPisTransformed(scip) && !SCIPprobIsPermuted(scip->origprob) )
853 {
854 SCIP_CONS** conss = scip->origprob->conss;
855 int nconss = scip->origprob->nconss;
856
857 SCIPrandomPermuteArray(randnumgen, (void**)conss, 0, nconss);
858
859 for( j = 0; j < nconss; ++j )
860 {
861 assert(conss[j]->consspos == -1);
862 conss[j]->addarraypos = j;
863 }
864
865 permuted = TRUE;
866 }
867 }
868
869 /* permute binary variables */
870 if( permutebinvars && !SCIPprobIsPermuted(scip->origprob) )
871 {
872 SCIPrandomPermuteArray(randnumgen, (void**)vars, 0, nbinvars);
873
874 /* readjust the mapping of variables to array positions */
875 for( j = 0; j < nbinvars; ++j )
876 vars[j]->probindex = j;
877
878 permuted = TRUE;
879 }
880
881 /* permute general integer variables */
882 if( permuteintvars && !SCIPprobIsPermuted(scip->origprob) )
883 {
884 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars, nbinvars+nintvars);
885
886 /* readjust the mapping of variables to array positions */
887 for( j = nbinvars; j < nbinvars+nintvars; ++j )
888 vars[j]->probindex = j;
889
890 permuted = TRUE;
891 }
892
893 /* permute general integer variables */
894 if( permuteimplvars && !SCIPprobIsPermuted(scip->origprob) )
895 {
896 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars+nintvars, nbinvars+nintvars+nimplvars);
897
898 /* readjust the mapping of variables to array positions */
899 for( j = nbinvars+nintvars; j < nbinvars+nintvars+nimplvars; ++j )
900 vars[j]->probindex = j;
901
902 permuted = TRUE;
903 }
904
905 /* permute general integer variables */
906 if( permutecontvars && !SCIPprobIsPermuted(scip->origprob) )
907 {
908 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars+nintvars+nimplvars, nvars);
909
910 /* readjust the mapping of variables to array positions */
911 for( j = nbinvars+nintvars+nimplvars; j < nvars; ++j )
912 vars[j]->probindex = j;
913
914 permuted = TRUE;
915 }
916
917 if( permuted && SCIPisTransformed(scip) )
918 {
919 assert(!SCIPprobIsPermuted(scip->transprob));
920
921 /* mark tranformed problem as permuted */
922 SCIPprobMarkPermuted(scip->transprob);
923
924 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
925 "permute transformed problem using random seed %u\n", randseed);
926 }
927 else if( permuted && !SCIPisTransformed(scip) )
928 {
929 assert(!SCIPprobIsPermuted(scip->origprob));
930
931 /* mark original problem as permuted */
932 SCIPprobMarkPermuted(scip->origprob);
933
934 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
935 "permute original problem using random seed %u\n", randseed);
936 }
937
938 /* free random number generator */
939 SCIPfreeRandom(scip, &randnumgen);
940
941 return SCIP_OKAY;
942 }
943
944 /** gets user problem data
945 *
946 * @return a SCIP_PROBDATA pointer, or NULL if no problem data was allocated
947 *
948 * @pre This method can be called if @p scip is in one of the following stages:
949 * - \ref SCIP_STAGE_PROBLEM
950 * - \ref SCIP_STAGE_TRANSFORMING
951 * - \ref SCIP_STAGE_TRANSFORMED
952 * - \ref SCIP_STAGE_INITPRESOLVE
953 * - \ref SCIP_STAGE_PRESOLVING
954 * - \ref SCIP_STAGE_EXITPRESOLVE
955 * - \ref SCIP_STAGE_PRESOLVED
956 * - \ref SCIP_STAGE_INITSOLVE
957 * - \ref SCIP_STAGE_SOLVING
958 * - \ref SCIP_STAGE_SOLVED
959 * - \ref SCIP_STAGE_EXITSOLVE
960 * - \ref SCIP_STAGE_FREETRANS
961 */
962 SCIP_PROBDATA* SCIPgetProbData(
963 SCIP* scip /**< SCIP data structure */
964 )
965 {
966 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetProbData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
967
968 switch( scip->set->stage )
969 {
970 case SCIP_STAGE_PROBLEM:
971 return SCIPprobGetData(scip->origprob);
972
973 case SCIP_STAGE_TRANSFORMING:
974 case SCIP_STAGE_TRANSFORMED:
975 case SCIP_STAGE_INITPRESOLVE:
976 case SCIP_STAGE_PRESOLVING:
977 case SCIP_STAGE_EXITPRESOLVE:
978 case SCIP_STAGE_PRESOLVED:
979 case SCIP_STAGE_INITSOLVE:
980 case SCIP_STAGE_SOLVING:
981 case SCIP_STAGE_SOLVED:
982 case SCIP_STAGE_EXITSOLVE:
983 case SCIP_STAGE_FREETRANS:
984 return SCIPprobGetData(scip->transprob);
985
986 default:
987 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
988 SCIPABORT();
989 return NULL; /*lint !e527*/
990 } /*lint !e788*/
991 }
992
993 /** sets user problem data
994 *
995 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
996 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
997 *
998 * @pre This method can be called if @p scip is in one of the following stages:
999 * - \ref SCIP_STAGE_PROBLEM
1000 * - \ref SCIP_STAGE_TRANSFORMING
1001 * - \ref SCIP_STAGE_TRANSFORMED
1002 * - \ref SCIP_STAGE_INITPRESOLVE
1003 * - \ref SCIP_STAGE_PRESOLVING
1004 * - \ref SCIP_STAGE_EXITPRESOLVE
1005 * - \ref SCIP_STAGE_PRESOLVED
1006 * - \ref SCIP_STAGE_INITSOLVE
1007 * - \ref SCIP_STAGE_SOLVING
1008 * - \ref SCIP_STAGE_SOLVED
1009 * - \ref SCIP_STAGE_EXITSOLVE
1010 * - \ref SCIP_STAGE_FREETRANS
1011 */
1012 SCIP_RETCODE SCIPsetProbData(
1013 SCIP* scip, /**< SCIP data structure */
1014 SCIP_PROBDATA* probdata /**< user problem data to use */
1015 )
1016 {
1017 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1018
1019 switch( scip->set->stage )
1020 {
1021 case SCIP_STAGE_PROBLEM:
1022 SCIPprobSetData(scip->origprob, probdata);
1023 return SCIP_OKAY;
1024
1025 case SCIP_STAGE_TRANSFORMING:
1026 case SCIP_STAGE_TRANSFORMED:
1027 case SCIP_STAGE_INITPRESOLVE:
1028 case SCIP_STAGE_PRESOLVING:
1029 case SCIP_STAGE_EXITPRESOLVE:
1030 case SCIP_STAGE_PRESOLVED:
1031 case SCIP_STAGE_INITSOLVE:
1032 case SCIP_STAGE_SOLVING:
1033 case SCIP_STAGE_SOLVED:
1034 case SCIP_STAGE_EXITSOLVE:
1035 case SCIP_STAGE_FREETRANS:
1036 SCIPprobSetData(scip->transprob, probdata);
1037 return SCIP_OKAY;
1038
1039 case SCIP_STAGE_INIT:
1040 case SCIP_STAGE_FREE:
1041 default:
1042 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1043 return SCIP_INVALIDCALL;
1044 }
1045 }
1046
1047 /** returns name of the current problem instance
1048 *
1049 * @return name of the current problem instance
1050 *
1051 * @pre This method can be called if @p scip is in one of the following stages:
1052 * - \ref SCIP_STAGE_PROBLEM
1053 * - \ref SCIP_STAGE_TRANSFORMING
1054 * - \ref SCIP_STAGE_TRANSFORMED
1055 * - \ref SCIP_STAGE_INITPRESOLVE
1056 * - \ref SCIP_STAGE_PRESOLVING
1057 * - \ref SCIP_STAGE_EXITPRESOLVE
1058 * - \ref SCIP_STAGE_PRESOLVED
1059 * - \ref SCIP_STAGE_INITSOLVE
1060 * - \ref SCIP_STAGE_SOLVING
1061 * - \ref SCIP_STAGE_SOLVED
1062 * - \ref SCIP_STAGE_EXITSOLVE
1063 * - \ref SCIP_STAGE_FREETRANS
1064 */
1065 const char* SCIPgetProbName(
1066 SCIP* scip /**< SCIP data structure */
1067 )
1068 {
1069 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetProbName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1070
1071 return SCIPprobGetName(scip->origprob);
1072 }
1073
1074 /** sets name of the current problem instance
1075 *
1076 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1077 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1078 *
1079 * @pre This method can be called if @p scip is in one of the following stages:
1080 * - \ref SCIP_STAGE_PROBLEM
1081 * - \ref SCIP_STAGE_TRANSFORMING
1082 * - \ref SCIP_STAGE_TRANSFORMED
1083 * - \ref SCIP_STAGE_INITPRESOLVE
1084 * - \ref SCIP_STAGE_PRESOLVING
1085 * - \ref SCIP_STAGE_EXITPRESOLVE
1086 * - \ref SCIP_STAGE_PRESOLVED
1087 * - \ref SCIP_STAGE_INITSOLVE
1088 * - \ref SCIP_STAGE_SOLVING
1089 * - \ref SCIP_STAGE_SOLVED
1090 * - \ref SCIP_STAGE_EXITSOLVE
1091 * - \ref SCIP_STAGE_FREETRANS
1092 */
1093 SCIP_RETCODE SCIPsetProbName(
1094 SCIP* scip, /**< SCIP data structure */
1095 const char* name /**< name to be set */
1096 )
1097 {
1098 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1099
1100 return SCIPprobSetName(scip->origprob, name);
1101 }
1102
1103 /** changes the objective function of the original problem.
1104 *
1105 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1106 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1107 *
1108 * @pre This method can be called if @p scip is in one of the following stages:
1109 * - \ref SCIP_STAGE_PROBLEM
1110 * - \ref SCIP_STAGE_PRESOLVED
1111 *
1112 * @note This method should be only used to change the objective function during two reoptimization runs and is only
1113 * recommended to an experienced user.
1114 *
1115 * @note All variables not given in \p vars array are assumed to have an objective coefficient of zero.
1116 */
1117 SCIP_RETCODE SCIPchgReoptObjective(
1118 SCIP* scip, /**< SCIP data structure */
1119 SCIP_OBJSENSE objsense, /**< new objective function */
1120 SCIP_VAR** vars, /**< original problem variables */
1121 SCIP_Real* coefs, /**< objective coefficients */
1122 int nvars /**< variables in vars array */
1123 )
1124 {
1125 SCIP_VAR** origvars;
1126 int norigvars;
1127 int i;
1128
1129 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgReoptObjective", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1130
1131 assert(nvars == 0 || vars != NULL);
1132 assert(nvars == 0 || coefs != NULL);
1133
1134 origvars = scip->origprob->vars;
1135 norigvars = scip->origprob->nvars;
1136
1137 #ifdef SCIP_MORE_DEBUG
1138 SCIPdebugMsg(scip, "objective function need to be set:\n");
1139 for( i = 0; i < nvars; i++ )
1140 {
1141 if( !SCIPisZero(scip, coefs[i]) )
1142 SCIPdebugMsg(scip, "%s%g <%s> ", SCIPisPositive(scip, coefs[i]) ? "+" : "", coefs[i], SCIPvarGetName(vars[i]));
1143 }
1144 SCIPdebugMsg(scip, "\n");
1145 #endif
1146
1147 /* Set all coefficients of original variables to 0, since we will add the new objective coefficients later. */
1148 for( i = 0; i < norigvars; i++ )
1149 {
1150 SCIP_CALL( SCIPchgVarObj(scip, origvars[i], 0.0) );
1151 }
1152
1153 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED )
1154 {
1155 /* In order to avoid numerical troubles, also explicitly set all transformed objective coefficients to 0. */
1156 for( i = 0; i < scip->transprob->nvars; i++ )
1157 {
1158 SCIP_CALL( SCIPchgVarObj(scip, scip->transprob->vars[i], 0.0) );
1159 }
1160 }
1161
1162 /* reset objective data of original problem */
1163 scip->origprob->objscale = 1.0;
1164 scip->origprob->objsense = objsense;
1165 scip->origprob->objoffset = 0.0;
1166 scip->origprob->objisintegral = FALSE;
1167
1168 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED )
1169 {
1170 /* reset objective data of transformed problem */
1171 scip->transprob->objscale = 1.0;
1172 scip->transprob->objsense = objsense;
1173 scip->transprob->objoffset = 0.0;
1174 scip->transprob->objisintegral = FALSE;
1175 }
1176
1177 /* set new objective values */
1178 for( i = 0; i < nvars; ++i )
1179 {
1180 if( !SCIPvarIsOriginal(vars[i]) )
1181 {
1182 SCIPerrorMessage("Cannot handle variable <%s> (status: %d) in SCIPchgReoptObjective().\n",
1183 SCIPvarGetName(vars[i]), SCIPvarGetStatus(vars[i]));
1184 return SCIP_INVALIDDATA;
1185 }
1186
1187 /* Add coefficients because this gets transferred to the transformed problem (the coefficients were set to 0 above). */
1188 SCIP_CALL( SCIPaddVarObj(scip, vars[i], coefs[i]) );
1189 }
1190
1191 #ifdef SCIP_MORE_DEBUG
1192 SCIPdebugMsg(scip, "new objective function:\n");
1193 for( i = 0; i < norigvars; i++ )
1194 {
1195 SCIP_Real objval = SCIPvarGetObj(origvars[i]);
1196 if( !SCIPisZero(scip, objval) )
1197 SCIPdebugMsg(scip, "%s%g <%s> ", SCIPisPositive(scip, objval) ? "+" : "", objval, SCIPvarGetName(origvars[i]));
1198 }
1199 SCIPdebugMsg(scip, "\n");
1200 #endif
1201
1202 return SCIP_OKAY;
1203 }
1204
1205 /** returns objective sense of original problem
1206 *
1207 * @return objective sense of original problem
1208 *
1209 * @pre This method can be called if @p scip is in one of the following stages:
1210 * - \ref SCIP_STAGE_PROBLEM
1211 * - \ref SCIP_STAGE_TRANSFORMING
1212 * - \ref SCIP_STAGE_TRANSFORMED
1213 * - \ref SCIP_STAGE_INITPRESOLVE
1214 * - \ref SCIP_STAGE_PRESOLVING
1215 * - \ref SCIP_STAGE_EXITPRESOLVE
1216 * - \ref SCIP_STAGE_PRESOLVED
1217 * - \ref SCIP_STAGE_INITSOLVE
1218 * - \ref SCIP_STAGE_SOLVING
1219 * - \ref SCIP_STAGE_SOLVED
1220 * - \ref SCIP_STAGE_EXITSOLVE
1221 * - \ref SCIP_STAGE_FREETRANS
1222 */
1223 SCIP_OBJSENSE SCIPgetObjsense(
1224 SCIP* scip /**< SCIP data structure */
1225 )
1226 {
1227 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjsense", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1228
1229 return scip->origprob->objsense;
1230 }
1231
1232 /** sets objective sense of problem
1233 *
1234 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1235 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1236 *
1237 * @pre This method can be called if @p scip is in one of the following stages:
1238 * - \ref SCIP_STAGE_PROBLEM
1239 */
1240 SCIP_RETCODE SCIPsetObjsense(
1241 SCIP* scip, /**< SCIP data structure */
1242 SCIP_OBJSENSE objsense /**< new objective sense */
1243 )
1244 {
1245 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjsense", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1246
1247 if( objsense != SCIP_OBJSENSE_MAXIMIZE && objsense != SCIP_OBJSENSE_MINIMIZE )
1248 {
1249 SCIPerrorMessage("invalid objective sense\n");
1250 return SCIP_INVALIDDATA;
1251 }
1252
1253 SCIPprobSetObjsense(scip->origprob, objsense);
1254
1255 return SCIP_OKAY;
1256 }
1257
1258 /** adds offset of objective function
1259 *
1260 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1261 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1262 *
1263 * @pre This method can be called if @p scip is in one of the following stages:
1264 * - \ref SCIP_STAGE_PRESOLVING
1265 */
1266 SCIP_RETCODE SCIPaddObjoffset(
1267 SCIP* scip, /**< SCIP data structure */
1268 SCIP_Real addval /**< value to add to objective offset */
1269 )
1270 {
1271 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddObjoffset", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1272
1273 SCIPprobAddObjoffset(scip->transprob, addval);
1274 SCIP_CALL( SCIPprimalUpdateObjoffset(scip->primal, SCIPblkmem(scip), scip->set, scip->stat, scip->eventfilter,
1275 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1276
1277 return SCIP_OKAY;
1278 }
1279
1280 /** adds offset of objective function to original problem and to all existing solution in original space
1281 *
1282 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1283 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1284 *
1285 * @pre This method can be called if @p scip is in one of the following stages:
1286 * - \ref SCIP_STAGE_PROBLEM
1287 */
1288 SCIP_RETCODE SCIPaddOrigObjoffset(
1289 SCIP* scip, /**< SCIP data structure */
1290 SCIP_Real addval /**< value to add to objective offset */
1291 )
1292 {
1293 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddOrigObjoffset", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1294
1295 scip->origprob->objoffset += addval;
1296 SCIPprimalAddOrigObjoffset(scip->origprimal, scip->set, addval);
1297
1298 return SCIP_OKAY;
1299 }
1300
1301 /** returns the objective offset of the original problem
1302 *
1303 * @return the objective offset of the original problem
1304 *
1305 * @pre This method can be called if @p scip is in one of the following stages:
1306 * - \ref SCIP_STAGE_PROBLEM
1307 * - \ref SCIP_STAGE_TRANSFORMING
1308 * - \ref SCIP_STAGE_TRANSFORMED
1309 * - \ref SCIP_STAGE_INITPRESOLVE
1310 * - \ref SCIP_STAGE_PRESOLVING
1311 * - \ref SCIP_STAGE_EXITPRESOLVE
1312 * - \ref SCIP_STAGE_PRESOLVED
1313 * - \ref SCIP_STAGE_INITSOLVE
1314 * - \ref SCIP_STAGE_SOLVING
1315 * - \ref SCIP_STAGE_SOLVED
1316 */
1317 SCIP_Real SCIPgetOrigObjoffset(
1318 SCIP* scip /**< SCIP data structure */
1319 )
1320 {
1321 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigObjoffset", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1322
1323 return scip->origprob->objoffset;
1324 }
1325
1326 /** returns the objective scale of the original problem
1327 *
1328 * @return the objective scale of the original problem
1329 *
1330 * @pre This method can be called if @p scip is in one of the following stages:
1331 * - \ref SCIP_STAGE_PROBLEM
1332 * - \ref SCIP_STAGE_TRANSFORMING
1333 * - \ref SCIP_STAGE_TRANSFORMED
1334 * - \ref SCIP_STAGE_INITPRESOLVE
1335 * - \ref SCIP_STAGE_PRESOLVING
1336 * - \ref SCIP_STAGE_EXITPRESOLVE
1337 * - \ref SCIP_STAGE_PRESOLVED
1338 * - \ref SCIP_STAGE_INITSOLVE
1339 * - \ref SCIP_STAGE_SOLVING
1340 * - \ref SCIP_STAGE_SOLVED
1341 */
1342 SCIP_Real SCIPgetOrigObjscale(
1343 SCIP* scip /**< SCIP data structure */
1344 )
1345 {
1346 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigObjscale", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1347
1348 return scip->origprob->objscale;
1349 }
1350
1351 /** returns the objective offset of the transformed problem
1352 *
1353 * @return the objective offset of the transformed problem
1354 *
1355 * @pre This method can be called if @p scip is in one of the following stages:
1356 * - \ref SCIP_STAGE_TRANSFORMED
1357 * - \ref SCIP_STAGE_INITPRESOLVE
1358 * - \ref SCIP_STAGE_PRESOLVING
1359 * - \ref SCIP_STAGE_EXITPRESOLVE
1360 * - \ref SCIP_STAGE_PRESOLVED
1361 * - \ref SCIP_STAGE_INITSOLVE
1362 * - \ref SCIP_STAGE_SOLVING
1363 * - \ref SCIP_STAGE_SOLVED
1364 */
1365 SCIP_Real SCIPgetTransObjoffset(
1366 SCIP* scip /**< SCIP data structure */
1367 )
1368 {
1369 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetTransObjoffset", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1370
1371 return scip->transprob->objoffset;
1372 }
1373
1374 /** returns the objective scale of the transformed problem
1375 *
1376 * @return the objective scale of the transformed problem
1377 *
1378 * @pre This method can be called if @p scip is in one of the following stages:
1379 * - \ref SCIP_STAGE_TRANSFORMED
1380 * - \ref SCIP_STAGE_INITPRESOLVE
1381 * - \ref SCIP_STAGE_PRESOLVING
1382 * - \ref SCIP_STAGE_EXITPRESOLVE
1383 * - \ref SCIP_STAGE_PRESOLVED
1384 * - \ref SCIP_STAGE_INITSOLVE
1385 * - \ref SCIP_STAGE_SOLVING
1386 * - \ref SCIP_STAGE_SOLVED
1387 */
1388 SCIP_Real SCIPgetTransObjscale(
1389 SCIP* scip /**< SCIP data structure */
1390 )
1391 {
1392 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetTransObjscale", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1393
1394 return scip->transprob->objscale;
1395 }
1396
1397 /** sets limit on objective function, such that only solutions better than this limit are accepted
1398 *
1399 * @note SCIP will only look for solutions with a strictly better objective value, thus, e.g., prune
1400 * all branch-and-bound nodes with dual bound equal or worse to the objective limit.
1401 * However, SCIP will also collect solutions with objective value worse than the objective limit and
1402 * use them to run improvement heuristics on them.
1403 * @note If SCIP can prove that there exists no solution with a strictly better objective value, the solving status
1404 * will normally be infeasible (the objective limit is interpreted as part of the problem).
1405 * The only exception is that by chance, SCIP found a solution with the same objective value and thus
1406 * proved the optimality of this solution, resulting in solution status optimal.
1407 *
1408 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1409 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1410 *
1411 * @pre This method can be called if @p scip is in one of the following stages:
1412 * - \ref SCIP_STAGE_PROBLEM
1413 * - \ref SCIP_STAGE_TRANSFORMED
1414 * - \ref SCIP_STAGE_INITPRESOLVE
1415 * - \ref SCIP_STAGE_PRESOLVING
1416 * - \ref SCIP_STAGE_EXITPRESOLVE
1417 * - \ref SCIP_STAGE_PRESOLVED
1418 * - \ref SCIP_STAGE_SOLVING
1419 */
1420 SCIP_RETCODE SCIPsetObjlimit(
1421 SCIP* scip, /**< SCIP data structure */
1422 SCIP_Real objlimit /**< new primal objective limit */
1423 )
1424 {
1425 SCIP_Real oldobjlimit;
1426
1427 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjlimit", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1428
1429 switch( scip->set->stage )
1430 {
1431 case SCIP_STAGE_PROBLEM:
1432 SCIPprobSetObjlim(scip->origprob, objlimit);
1433 break;
1434 case SCIP_STAGE_PRESOLVED:
1435 oldobjlimit = SCIPprobGetObjlim(scip->origprob, scip->set);
1436 assert(oldobjlimit == SCIPprobGetObjlim(scip->transprob, scip->set)); /*lint !e777*/
1437 if( SCIPtransformObj(scip, objlimit) > SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, oldobjlimit) && ! scip->set->reopt_enable)
1438 {
1439 SCIPerrorMessage("cannot relax objective limit from %.15g to %.15g in presolved stage.\n", oldobjlimit, objlimit);
1440 return SCIP_INVALIDDATA;
1441 }
1442 SCIPprobSetObjlim(scip->origprob, objlimit);
1443 SCIPprobSetObjlim(scip->transprob, objlimit);
1444 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1445 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1446 break;
1447
1448 case SCIP_STAGE_TRANSFORMED:
1449 case SCIP_STAGE_INITPRESOLVE:
1450 case SCIP_STAGE_PRESOLVING:
1451 case SCIP_STAGE_EXITPRESOLVE:
1452 case SCIP_STAGE_SOLVING:
1453 oldobjlimit = SCIPprobGetObjlim(scip->origprob, scip->set);
1454 assert(oldobjlimit == SCIPprobGetObjlim(scip->transprob, scip->set)); /*lint !e777*/
1455 if( SCIPtransformObj(scip, objlimit) > SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, oldobjlimit) )
1456 {
1457 SCIPerrorMessage("cannot relax objective limit from %.15g to %.15g after problem was transformed.\n", oldobjlimit, objlimit);
1458 return SCIP_INVALIDDATA;
1459 }
1460 SCIPprobSetObjlim(scip->origprob, objlimit);
1461 SCIPprobSetObjlim(scip->transprob, objlimit);
1462 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter,
1463 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) );
1464 break;
1465
1466 default:
1467 SCIPerrorMessage("method is not callable in SCIP stage <%d>\n", scip->set->stage);
1468 return SCIP_INVALIDCALL;
1469 } /*lint !e788*/
1470
1471 return SCIP_OKAY;
1472 }
1473
1474 /** returns current limit on objective function
1475 *
1476 * @return the current objective limit of the original problem
1477 *
1478 * @pre This method can be called if @p scip is in one of the following stages:
1479 * - \ref SCIP_STAGE_PROBLEM
1480 * - \ref SCIP_STAGE_TRANSFORMING
1481 * - \ref SCIP_STAGE_TRANSFORMED
1482 * - \ref SCIP_STAGE_INITPRESOLVE
1483 * - \ref SCIP_STAGE_PRESOLVING
1484 * - \ref SCIP_STAGE_EXITPRESOLVE
1485 * - \ref SCIP_STAGE_PRESOLVED
1486 * - \ref SCIP_STAGE_INITSOLVE
1487 * - \ref SCIP_STAGE_SOLVING
1488 * - \ref SCIP_STAGE_SOLVED
1489 */
1490 SCIP_Real SCIPgetObjlimit(
1491 SCIP* scip /**< SCIP data structure */
1492 )
1493 {
1494 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjlimit", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1495
1496 return SCIPprobGetObjlim(scip->origprob, scip->set);
1497 }
1498
1499 /** informs SCIP, that the objective value is always integral in every feasible solution
1500 *
1501 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref
1502 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1503 *
1504 * @pre This method can be called if @p scip is in one of the following stages:
1505 * - \ref SCIP_STAGE_PROBLEM
1506 * - \ref SCIP_STAGE_TRANSFORMING
1507 * - \ref SCIP_STAGE_INITPRESOLVE
1508 * - \ref SCIP_STAGE_EXITPRESOLVE
1509 * - \ref SCIP_STAGE_SOLVING
1510 *
1511 * @note This function should be used to inform SCIP that the objective function is integral, helping to improve the
1512 * performance. This is useful when using column generation. If no column generation (pricing) is used, SCIP
1513 * automatically detects whether the objective function is integral or can be scaled to be integral. However, in
1514 * any case, the user has to make sure that no variable is added during the solving process that destroys this
1515 * property.
1516 */
1517 SCIP_RETCODE SCIPsetObjIntegral(
1518 SCIP* scip /**< SCIP data structure */
1519 )
1520 {
1521 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjIntegral", FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1522
1523 switch( scip->set->stage )
1524 {
1525 case SCIP_STAGE_PROBLEM:
1526 SCIPprobSetObjIntegral(scip->origprob);
1527 return SCIP_OKAY;
1528
1529 case SCIP_STAGE_TRANSFORMING:
1530 case SCIP_STAGE_PRESOLVING:
1531 case SCIP_STAGE_PRESOLVED:
1532 case SCIP_STAGE_SOLVING:
1533 SCIPprobSetObjIntegral(scip->transprob);
1534 return SCIP_OKAY;
1535
1536 default:
1537 SCIPerrorMessage("method is not callable in SCIP stage <%d>\n", scip->set->stage);
1538 return SCIP_INVALIDCALL;
1539 } /*lint !e788*/
1540 }
1541
1542 /** returns whether the objective value is known to be integral in every feasible solution
1543 *
1544 * @return TRUE, if objective value is known to be always integral, otherwise FALSE
1545 *
1546 * @pre This method can be called if @p scip is in one of the following stages:
1547 * - \ref SCIP_STAGE_PROBLEM
1548 * - \ref SCIP_STAGE_TRANSFORMING
1549 * - \ref SCIP_STAGE_INITPRESOLVE
1550 * - \ref SCIP_STAGE_PRESOLVING
1551 * - \ref SCIP_STAGE_EXITPRESOLVE
1552 * - \ref SCIP_STAGE_PRESOLVED
1553 * - \ref SCIP_STAGE_SOLVING
1554 *
1555 * @note If no pricing is performed, SCIP automatically detects whether the objective function is integral or can be
1556 * scaled to be integral, helping to improve performance. This function returns the result. Otherwise
1557 * SCIPsetObjIntegral() can be used to inform SCIP. However, in any case, the user has to make sure that no
1558 * variable is added during the solving process that destroys this property.
1559 */
1560 SCIP_Bool SCIPisObjIntegral(
1561 SCIP* scip /**< SCIP data structure */
1562 )
1563 {
1564 int v;
1565
1566 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisObjIntegral", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1567
1568 switch( scip->set->stage )
1569 {
1570 case SCIP_STAGE_PROBLEM:
1571 /* if the user explicitly added the information that there is an integral objective, return TRUE */
1572 if( SCIPprobIsObjIntegral(scip->origprob) )
1573 return TRUE;
1574
1575 /* if there exist unknown variables, we cannot conclude that the objective value is always integral */
1576 if ( scip->set->nactivepricers != 0 )
1577 return FALSE;
1578
1579 /* if the objective value offset is fractional, the value itself is possibly fractional */
1580 if ( ! SCIPisIntegral(scip, scip->origprob->objoffset) )
1581 return FALSE;
1582
1583 /* scan through the variables */
1584 for (v = 0; v < scip->origprob->nvars; ++v)
1585 {
1586 SCIP_Real obj;
1587
1588 /* get objective value of variable */
1589 obj = SCIPvarGetObj(scip->origprob->vars[v]);
1590
1591 /* check, if objective value is non-zero */
1592 if ( ! SCIPisZero(scip, obj) )
1593 {
1594 /* if variable's objective value is fractional, the problem's objective value may also be fractional */
1595 if ( ! SCIPisIntegral(scip, obj) )
1596 break;
1597
1598 /* if variable with non-zero objective value is continuous, the problem's objective value may be fractional */
1599 if ( SCIPvarGetType(scip->origprob->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
1600 break;
1601 }
1602 }
1603
1604 /* we do not store the result, since we assume that the original problem might be changed */
1605 if ( v == scip->origprob->nvars )
1606 return TRUE;
1607 return FALSE;
1608
1609 case SCIP_STAGE_TRANSFORMING:
1610 case SCIP_STAGE_INITPRESOLVE:
1611 case SCIP_STAGE_PRESOLVING:
1612 case SCIP_STAGE_EXITPRESOLVE:
1613 case SCIP_STAGE_PRESOLVED:
1614 case SCIP_STAGE_SOLVING:
1615 return SCIPprobIsObjIntegral(scip->transprob);
1616
1617 default:
1618 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1619 SCIPABORT();
1620 return FALSE; /*lint !e527*/
1621 } /*lint !e788*/
1622 }
1623
1624 /** returns the Euclidean norm of the objective function vector (available only for transformed problem)
1625 *
1626 * @return the Euclidean norm of the transformed objective function vector
1627 *
1628 * @pre This method can be called if @p scip is in one of the following stages:
1629 * - \ref SCIP_STAGE_TRANSFORMED
1630 * - \ref SCIP_STAGE_INITPRESOLVE
1631 * - \ref SCIP_STAGE_PRESOLVING
1632 * - \ref SCIP_STAGE_EXITPRESOLVE
1633 * - \ref SCIP_STAGE_PRESOLVED
1634 * - \ref SCIP_STAGE_INITSOLVE
1635 * - \ref SCIP_STAGE_SOLVING
1636 * - \ref SCIP_STAGE_SOLVED
1637 * - \ref SCIP_STAGE_EXITSOLVE
1638 */
1639 SCIP_Real SCIPgetObjNorm(
1640 SCIP* scip /**< SCIP data structure */
1641 )
1642 {
1643 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjNorm", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1644
1645 if( scip->lp->objsqrnormunreliable )
1646 SCIPlpRecalculateObjSqrNorm(scip->set, scip->lp);
1647 assert(!scip->lp->objsqrnormunreliable);
1648
1649 return SCIPlpGetObjNorm(scip->lp);
1650 }
1651
1652 /** adds variable to the problem
1653 *
1654 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1655 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1656 *
1657 * @pre This method can be called if @p scip is in one of the following stages:
1658 * - \ref SCIP_STAGE_PROBLEM
1659 * - \ref SCIP_STAGE_TRANSFORMING
1660 * - \ref SCIP_STAGE_INITPRESOLVE
1661 * - \ref SCIP_STAGE_PRESOLVING
1662 * - \ref SCIP_STAGE_EXITPRESOLVE
1663 * - \ref SCIP_STAGE_PRESOLVED
1664 * - \ref SCIP_STAGE_SOLVING
1665 */
1666 SCIP_RETCODE SCIPaddVar(
1667 SCIP* scip, /**< SCIP data structure */
1668 SCIP_VAR* var /**< variable to add */
1669 )
1670 {
1671 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1672
1673 /* avoid inserting the same variable twice */
1674 if( SCIPvarGetProbindex(var) != -1 )
1675 return SCIP_OKAY;
1676
1677 /* insert the negation variable x instead of the negated variable x' in x' = offset - x */
1678 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED )
1679 {
1680 assert(SCIPvarGetNegationVar(var) != NULL);
1681 SCIP_CALL( SCIPaddVar(scip, SCIPvarGetNegationVar(var)) );
1682 return SCIP_OKAY;
1683 }
1684
1685 switch( scip->set->stage )
1686 {
1687 case SCIP_STAGE_PROBLEM:
1688 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_ORIGINAL )
1689 {
1690 SCIPerrorMessage("cannot add transformed variables to original problem\n");
1691 return SCIP_INVALIDDATA;
1692 }
1693 SCIP_CALL( SCIPprobAddVar(scip->origprob, scip->mem->probmem, scip->set, scip->lp, scip->branchcand,
1694 scip->eventfilter, scip->eventqueue, var) );
1695 return SCIP_OKAY;
1696
1697 case SCIP_STAGE_TRANSFORMING:
1698 case SCIP_STAGE_INITPRESOLVE:
1699 case SCIP_STAGE_PRESOLVING:
1700 case SCIP_STAGE_EXITPRESOLVE:
1701 case SCIP_STAGE_PRESOLVED:
1702 case SCIP_STAGE_SOLVING:
1703 /* check variable's status */
1704 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL )
1705 {
1706 SCIPerrorMessage("cannot add original variables to transformed problem\n");
1707 return SCIP_INVALIDDATA;
1708 }
1709 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN )
1710 {
1711 SCIPerrorMessage("cannot add fixed or aggregated variables to transformed problem\n");
1712 return SCIP_INVALIDDATA;
1713 }
1714 SCIP_CALL( SCIPprobAddVar(scip->transprob, scip->mem->probmem, scip->set, scip->lp,
1715 scip->branchcand, scip->eventfilter, scip->eventqueue, var) );
1716 return SCIP_OKAY;
1717
1718 default:
1719 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1720 return SCIP_INVALIDCALL;
1721 } /*lint !e788*/
1722 }
1723
1724 /** adds variable to the problem and uses it as pricing candidate to enter the LP
1725 *
1726 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1727 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1728 *
1729 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING
1730 */
1731 SCIP_RETCODE SCIPaddPricedVar(
1732 SCIP* scip, /**< SCIP data structure */
1733 SCIP_VAR* var, /**< variable to add */
1734 SCIP_Real score /**< pricing score of variable (the larger, the better the variable) */
1735 )
1736 {
1737 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddPricedVar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1738
1739 /* insert the negation variable x instead of the negated variable x' in x' = offset - x */
1740 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED )
1741 {
1742 assert(SCIPvarGetNegationVar(var) != NULL);
1743 SCIP_CALL( SCIPaddPricedVar(scip, SCIPvarGetNegationVar(var), score) );
1744 return SCIP_OKAY;
1745 }
1746
1747 /* add variable to problem if not yet inserted */
1748 if( SCIPvarGetProbindex(var) == -1 )
1749 {
1750 /* check variable's status */
1751 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL )
1752 {
1753 SCIPerrorMessage("cannot add original variables to transformed problem\n");
1754 return SCIP_INVALIDDATA;
1755 }
1756 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN )
1757 {
1758 SCIPerrorMessage("cannot add fixed or aggregated variables to transformed problem\n");
1759 return SCIP_INVALIDDATA;
1760 }
1761 SCIP_CALL( SCIPprobAddVar(scip->transprob, scip->mem->probmem, scip->set, scip->lp,
1762 scip->branchcand, scip->eventfilter, scip->eventqueue, var) );
1763 }
1764
1765 /* add variable to pricing storage */
1766 SCIP_CALL( SCIPpricestoreAddVar(scip->pricestore, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, var, score,
1767 (SCIPtreeGetCurrentDepth(scip->tree) == 0)) );
1768
1769 return SCIP_OKAY;
1770 }
1771
1772 /** removes variable from the problem
1773 *
1774 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1775 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1776 *
1777 * @pre This method can be called if @p scip is in one of the following stages:
1778 * - \ref SCIP_STAGE_PROBLEM
1779 * - \ref SCIP_STAGE_TRANSFORMING
1780 * - \ref SCIP_STAGE_TRANSFORMED
1781 * - \ref SCIP_STAGE_PRESOLVING
1782 * - \ref SCIP_STAGE_FREETRANS
1783 *
1784 * @warning The variable is not deleted from the constraints when in SCIP_STAGE_PROBLEM. In this stage, it is the
1785 * user's responsibility to ensure the variable has been removed from all constraints or the constraints
1786 * deleted.
1787 */
1788 SCIP_RETCODE SCIPdelVar(
1789 SCIP* scip, /**< SCIP data structure */
1790 SCIP_VAR* var, /**< variable to delete */
1791 SCIP_Bool* deleted /**< pointer to store whether marking variable to be deleted was successful */
1792 )
1793 {
1794 assert(scip != NULL);
1795 assert(var != NULL);
1796 assert(deleted != NULL);
1797
1798 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelVar", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE) );
1799
1800 switch( scip->set->stage )
1801 {
1802 case SCIP_STAGE_PROBLEM:
1803 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_ORIGINAL )
1804 {
1805 SCIPerrorMessage("cannot remove transformed variables from original problem\n");
1806 return SCIP_INVALIDDATA;
1807 }
1808 SCIP_CALL( SCIPprobDelVar(scip->origprob, scip->mem->probmem, scip->set, scip->eventqueue, var, deleted) );
1809
1810 /* delete the variables from the problems that were marked to be deleted */
1811 SCIP_CALL( SCIPprobPerformVarDeletions(scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp, scip->branchcand) );
1812
1813 return SCIP_OKAY;
1814
1815 case SCIP_STAGE_TRANSFORMING:
1816 case SCIP_STAGE_TRANSFORMED:
1817 case SCIP_STAGE_PRESOLVING:
1818 /* check variable's status */
1819 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL )
1820 {
1821 SCIPerrorMessage("cannot remove original variables from transformed problem\n");
1822 return SCIP_INVALIDDATA;
1823 }
1824 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN )
1825 {
1826 SCIPerrorMessage("cannot remove fixed or aggregated variables from transformed problem\n");
1827 return SCIP_INVALIDDATA;
1828 }
1829
1830 SCIP_CALL( SCIPprobDelVar(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, var, deleted) );
1831
1832 return SCIP_OKAY;
1833 case SCIP_STAGE_FREETRANS:
1834 /* in FREETRANS stage, we don't need to remove the variable, because the transformed problem is freed anyways */
1835 *deleted = FALSE;
1836
1837 return SCIP_OKAY;
1838 default:
1839 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1840 return SCIP_INVALIDCALL;
1841 } /*lint !e788*/
1842 }
1843
1844 /** gets variables of the problem along with the numbers of different variable types; data may become invalid after
1845 * calls to SCIPchgVarType(), SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar()
1846 *
1847 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1848 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1849 *
1850 * @pre This method can be called if @p scip is in one of the following stages:
1851 * - \ref SCIP_STAGE_PROBLEM
1852 * - \ref SCIP_STAGE_TRANSFORMED
1853 * - \ref SCIP_STAGE_INITPRESOLVE
1854 * - \ref SCIP_STAGE_PRESOLVING
1855 * - \ref SCIP_STAGE_EXITPRESOLVE
1856 * - \ref SCIP_STAGE_PRESOLVED
1857 * - \ref SCIP_STAGE_INITSOLVE
1858 * - \ref SCIP_STAGE_SOLVING
1859 * - \ref SCIP_STAGE_SOLVED
1860 * - \ref SCIP_STAGE_EXITSOLVE
1861 *
1862 * @note Variables in the vars array are ordered: binaries first, then integers, implicit integers and continuous last.
1863 */
1864 SCIP_RETCODE SCIPgetVarsData(
1865 SCIP* scip, /**< SCIP data structure */
1866 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */
1867 int* nvars, /**< pointer to store number of variables or NULL if not needed */
1868 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */
1869 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */
1870 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */
1871 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */
1872 )
1873 {
1874 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsData", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1875
1876 switch( scip->set->stage )
1877 {
1878 case SCIP_STAGE_PROBLEM:
1879 if( vars != NULL )
1880 *vars = scip->origprob->vars;
1881 if( nvars != NULL )
1882 *nvars = scip->origprob->nvars;
1883 if( nbinvars != NULL )
1884 *nbinvars = scip->origprob->nbinvars;
1885 if( nintvars != NULL )
1886 *nintvars = scip->origprob->nintvars;
1887 if( nimplvars != NULL )
1888 *nimplvars = scip->origprob->nimplvars;
1889 if( ncontvars != NULL )
1890 *ncontvars = scip->origprob->ncontvars;
1891 return SCIP_OKAY;
1892
1893 case SCIP_STAGE_TRANSFORMED:
1894 case SCIP_STAGE_INITPRESOLVE:
1895 case SCIP_STAGE_PRESOLVING:
1896 case SCIP_STAGE_EXITPRESOLVE:
1897 case SCIP_STAGE_PRESOLVED:
1898 case SCIP_STAGE_INITSOLVE:
1899 case SCIP_STAGE_SOLVING:
1900 case SCIP_STAGE_SOLVED:
1901 case SCIP_STAGE_EXITSOLVE:
1902 if( vars != NULL )
1903 *vars = scip->transprob->vars;
1904 if( nvars != NULL )
1905 *nvars = scip->transprob->nvars;
1906 if( nbinvars != NULL )
1907 *nbinvars = scip->transprob->nbinvars;
1908 if( nintvars != NULL )
1909 *nintvars = scip->transprob->nintvars;
1910 if( nimplvars != NULL )
1911 *nimplvars = scip->transprob->nimplvars;
1912 if( ncontvars != NULL )
1913 *ncontvars = scip->transprob->ncontvars;
1914 return SCIP_OKAY;
1915
1916 default:
1917 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1918 return SCIP_INVALIDCALL;
1919 } /*lint !e788*/
1920 }
1921
1922 /** gets array with active problem variables
1923 *
1924 * @return array with active problem variables
1925 *
1926 * @pre This method can be called if @p scip is in one of the following stages:
1927 * - \ref SCIP_STAGE_PROBLEM
1928 * - \ref SCIP_STAGE_TRANSFORMED
1929 * - \ref SCIP_STAGE_INITPRESOLVE
1930 * - \ref SCIP_STAGE_PRESOLVING
1931 * - \ref SCIP_STAGE_EXITPRESOLVE
1932 * - \ref SCIP_STAGE_PRESOLVED
1933 * - \ref SCIP_STAGE_INITSOLVE
1934 * - \ref SCIP_STAGE_SOLVING
1935 * - \ref SCIP_STAGE_SOLVED
1936 * - \ref SCIP_STAGE_EXITSOLVE
1937 *
1938 * @note Variables in the array are ordered: binaries first, then integers, implicit integers and continuous last.
1939 *
1940 * @warning If your are using the methods which add or change bound of variables (e.g., SCIPchgVarType(), SCIPfixVar(),
1941 * SCIPaggregateVars(), and SCIPmultiaggregateVar()), it can happen that the internal variable array (which is
1942 * accessed via this method) gets resized and/or resorted. This can invalid the data pointer which is returned
1943 * by this method.
1944 */
1945 SCIP_VAR** SCIPgetVars(
1946 SCIP* scip /**< SCIP data structure */
1947 )
1948 {
1949 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1950
1951 switch( scip->set->stage )
1952 {
1953 case SCIP_STAGE_PROBLEM:
1954 return scip->origprob->vars;
1955
1956 case SCIP_STAGE_TRANSFORMED:
1957 case SCIP_STAGE_INITPRESOLVE:
1958 case SCIP_STAGE_PRESOLVING:
1959 case SCIP_STAGE_EXITPRESOLVE:
1960 case SCIP_STAGE_PRESOLVED:
1961 case SCIP_STAGE_INITSOLVE:
1962 case SCIP_STAGE_SOLVING:
1963 case SCIP_STAGE_SOLVED:
1964 case SCIP_STAGE_EXITSOLVE:
1965 return scip->transprob->vars;
1966
1967 default:
1968 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1969 SCIPABORT();
1970 return NULL; /*lint !e527*/
1971 } /*lint !e788*/
1972 }
1973
1974 /** gets number of active problem variables
1975 *
1976 * @return the number of active problem variables
1977 *
1978 * @pre This method can be called if @p scip is in one of the following stages:
1979 * - \ref SCIP_STAGE_PROBLEM
1980 * - \ref SCIP_STAGE_TRANSFORMED
1981 * - \ref SCIP_STAGE_INITPRESOLVE
1982 * - \ref SCIP_STAGE_PRESOLVING
1983 * - \ref SCIP_STAGE_EXITPRESOLVE
1984 * - \ref SCIP_STAGE_PRESOLVED
1985 * - \ref SCIP_STAGE_INITSOLVE
1986 * - \ref SCIP_STAGE_SOLVING
1987 * - \ref SCIP_STAGE_SOLVED
1988 * - \ref SCIP_STAGE_EXITSOLVE
1989 */
1990 int SCIPgetNVars(
1991 SCIP* scip /**< SCIP data structure */
1992 )
1993 {
|
(1) Event cond_false: |
Condition "(_restat_ = SCIP_OKAY) != SCIP_OKAY", taking false branch. |
|
(2) Event if_end: |
End of if statement. |
1994 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1995
|
(3) Event switch: |
Switch case default. |
1996 switch( scip->set->stage )
1997 {
1998 case SCIP_STAGE_PROBLEM:
1999 return scip->origprob->nvars;
2000
2001 case SCIP_STAGE_TRANSFORMED:
2002 case SCIP_STAGE_INITPRESOLVE:
2003 case SCIP_STAGE_PRESOLVING:
2004 case SCIP_STAGE_EXITPRESOLVE:
2005 case SCIP_STAGE_PRESOLVED:
2006 case SCIP_STAGE_INITSOLVE:
2007 case SCIP_STAGE_SOLVING:
2008 case SCIP_STAGE_SOLVED:
2009 case SCIP_STAGE_EXITSOLVE:
2010 return scip->transprob->nvars;
2011
|
(4) Event switch_default: |
Reached default. |
2012 default:
2013 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2014 SCIPABORT();
|
(5) Event return_zero_constant: |
Explicitly returning zero value "0". |
2015 return 0; /*lint !e527*/
2016 } /*lint !e788*/
2017 }
2018
2019 /** gets number of binary active problem variables
2020 *
2021 * @return the number of binary active problem variables
2022 *
2023 * @pre This method can be called if @p scip is in one of the following stages:
2024 * - \ref SCIP_STAGE_PROBLEM
2025 * - \ref SCIP_STAGE_TRANSFORMED
2026 * - \ref SCIP_STAGE_INITPRESOLVE
2027 * - \ref SCIP_STAGE_PRESOLVING
2028 * - \ref SCIP_STAGE_EXITPRESOLVE
2029 * - \ref SCIP_STAGE_PRESOLVED
2030 * - \ref SCIP_STAGE_INITSOLVE
2031 * - \ref SCIP_STAGE_SOLVING
2032 * - \ref SCIP_STAGE_SOLVED
2033 * - \ref SCIP_STAGE_EXITSOLVE
2034 */
2035 int SCIPgetNBinVars(
2036 SCIP* scip /**< SCIP data structure */
2037 )
2038 {
2039 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBinVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2040
2041 switch( scip->set->stage )
2042 {
2043 case SCIP_STAGE_PROBLEM:
2044 return scip->origprob->nbinvars;
2045
2046 case SCIP_STAGE_TRANSFORMED:
2047 case SCIP_STAGE_INITPRESOLVE:
2048 case SCIP_STAGE_PRESOLVING:
2049 case SCIP_STAGE_EXITPRESOLVE:
2050 case SCIP_STAGE_PRESOLVED:
2051 case SCIP_STAGE_INITSOLVE:
2052 case SCIP_STAGE_SOLVING:
2053 case SCIP_STAGE_SOLVED:
2054 case SCIP_STAGE_EXITSOLVE:
2055 return scip->transprob->nbinvars;
2056
2057 default:
2058 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2059 SCIPABORT();
2060 return 0; /*lint !e527*/
2061 } /*lint !e788*/
2062 }
2063
2064 /** gets number of integer active problem variables
2065 *
2066 * @return the number of integer active problem variables
2067 *
2068 * @pre This method can be called if @p scip is in one of the following stages:
2069 * - \ref SCIP_STAGE_PROBLEM
2070 * - \ref SCIP_STAGE_TRANSFORMED
2071 * - \ref SCIP_STAGE_INITPRESOLVE
2072 * - \ref SCIP_STAGE_PRESOLVING
2073 * - \ref SCIP_STAGE_EXITPRESOLVE
2074 * - \ref SCIP_STAGE_PRESOLVED
2075 * - \ref SCIP_STAGE_INITSOLVE
2076 * - \ref SCIP_STAGE_SOLVING
2077 * - \ref SCIP_STAGE_SOLVED
2078 * - \ref SCIP_STAGE_EXITSOLVE
2079 */
2080 int SCIPgetNIntVars(
2081 SCIP* scip /**< SCIP data structure */
2082 )
2083 {
2084 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNIntVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2085
2086 switch( scip->set->stage )
2087 {
2088 case SCIP_STAGE_PROBLEM:
2089 return scip->origprob->nintvars;
2090
2091 case SCIP_STAGE_TRANSFORMED:
2092 case SCIP_STAGE_INITPRESOLVE:
2093 case SCIP_STAGE_PRESOLVING:
2094 case SCIP_STAGE_EXITPRESOLVE:
2095 case SCIP_STAGE_PRESOLVED:
2096 case SCIP_STAGE_INITSOLVE:
2097 case SCIP_STAGE_SOLVING:
2098 case SCIP_STAGE_SOLVED:
2099 case SCIP_STAGE_EXITSOLVE:
2100 return scip->transprob->nintvars;
2101
2102 default:
2103 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2104 SCIPABORT();
2105 return 0; /*lint !e527*/
2106 } /*lint !e788*/
2107 }
2108
2109 /** gets number of implicit integer active problem variables
2110 *
2111 * @return the number of implicit integer active problem variables
2112 *
2113 * @pre This method can be called if @p scip is in one of the following stages:
2114 * - \ref SCIP_STAGE_PROBLEM
2115 * - \ref SCIP_STAGE_TRANSFORMED
2116 * - \ref SCIP_STAGE_INITPRESOLVE
2117 * - \ref SCIP_STAGE_PRESOLVING
2118 * - \ref SCIP_STAGE_EXITPRESOLVE
2119 * - \ref SCIP_STAGE_PRESOLVED
2120 * - \ref SCIP_STAGE_INITSOLVE
2121 * - \ref SCIP_STAGE_SOLVING
2122 * - \ref SCIP_STAGE_SOLVED
2123 * - \ref SCIP_STAGE_EXITSOLVE
2124 */
2125 int SCIPgetNImplVars(
2126 SCIP* scip /**< SCIP data structure */
2127 )
2128 {
2129 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNImplVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2130
2131 switch( scip->set->stage )
2132 {
2133 case SCIP_STAGE_PROBLEM:
2134 return scip->origprob->nimplvars;
2135
2136 case SCIP_STAGE_TRANSFORMED:
2137 case SCIP_STAGE_INITPRESOLVE:
2138 case SCIP_STAGE_PRESOLVING:
2139 case SCIP_STAGE_EXITPRESOLVE:
2140 case SCIP_STAGE_PRESOLVED:
2141 case SCIP_STAGE_INITSOLVE:
2142 case SCIP_STAGE_SOLVING:
2143 case SCIP_STAGE_SOLVED:
2144 case SCIP_STAGE_EXITSOLVE:
2145 return scip->transprob->nimplvars;
2146
2147 default:
2148 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2149 SCIPABORT();
2150 return 0; /*lint !e527*/
2151 } /*lint !e788*/
2152 }
2153
2154 /** gets number of continuous active problem variables
2155 *
2156 * @return the number of continuous active problem variables
2157 *
2158 * @pre This method can be called if @p scip is in one of the following stages:
2159 * - \ref SCIP_STAGE_PROBLEM
2160 * - \ref SCIP_STAGE_TRANSFORMED
2161 * - \ref SCIP_STAGE_INITPRESOLVE
2162 * - \ref SCIP_STAGE_PRESOLVING
2163 * - \ref SCIP_STAGE_EXITPRESOLVE
2164 * - \ref SCIP_STAGE_PRESOLVED
2165 * - \ref SCIP_STAGE_INITSOLVE
2166 * - \ref SCIP_STAGE_SOLVING
2167 * - \ref SCIP_STAGE_SOLVED
2168 * - \ref SCIP_STAGE_EXITSOLVE
2169 */
2170 int SCIPgetNContVars(
2171 SCIP* scip /**< SCIP data structure */
2172 )
2173 {
2174 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNContVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2175
2176 switch( scip->set->stage )
2177 {
2178 case SCIP_STAGE_PROBLEM:
2179 return scip->origprob->ncontvars;
2180
2181 case SCIP_STAGE_TRANSFORMED:
2182 case SCIP_STAGE_INITPRESOLVE:
2183 case SCIP_STAGE_PRESOLVING:
2184 case SCIP_STAGE_EXITPRESOLVE:
2185 case SCIP_STAGE_PRESOLVED:
2186 case SCIP_STAGE_INITSOLVE:
2187 case SCIP_STAGE_SOLVING:
2188 case SCIP_STAGE_SOLVED:
2189 case SCIP_STAGE_EXITSOLVE:
2190 return scip->transprob->ncontvars;
2191
2192 default:
2193 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2194 SCIPABORT();
2195 return 0; /*lint !e527*/
2196 } /*lint !e788*/
2197 }
2198
2199
2200 /** gets number of active problem variables with a non-zero objective coefficient
2201 *
2202 * @note In case of the original problem the number of variables is counted. In case of the transformed problem the
2203 * number of variables is just returned since it is stored internally
2204 *
2205 * @return the number of active problem variables with a non-zero objective coefficient
2206 *
2207 * @pre This method can be called if @p scip is in one of the following stages:
2208 * - \ref SCIP_STAGE_PROBLEM
2209 * - \ref SCIP_STAGE_TRANSFORMED
2210 * - \ref SCIP_STAGE_INITPRESOLVE
2211 * - \ref SCIP_STAGE_PRESOLVING
2212 * - \ref SCIP_STAGE_EXITPRESOLVE
2213 * - \ref SCIP_STAGE_PRESOLVED
2214 * - \ref SCIP_STAGE_INITSOLVE
2215 * - \ref SCIP_STAGE_SOLVING
2216 * - \ref SCIP_STAGE_SOLVED
2217 */
2218 int SCIPgetNObjVars(
2219 SCIP* scip /**< SCIP data structure */
2220 )
2221 {
2222 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNObjVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2223
2224 switch( scip->set->stage )
2225 {
2226 case SCIP_STAGE_PROBLEM:
2227 return SCIPprobGetNObjVars(scip->origprob, scip->set);
2228
2229 case SCIP_STAGE_TRANSFORMED:
2230 case SCIP_STAGE_INITPRESOLVE:
2231 case SCIP_STAGE_PRESOLVING:
2232 case SCIP_STAGE_EXITPRESOLVE:
2233 case SCIP_STAGE_PRESOLVED:
2234 case SCIP_STAGE_INITSOLVE:
2235 case SCIP_STAGE_SOLVING:
2236 case SCIP_STAGE_SOLVED:
2237 return SCIPprobGetNObjVars(scip->transprob, scip->set);
2238
2239 default:
2240 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2241 SCIPABORT();
2242 return 0; /*lint !e527*/
2243 } /*lint !e788*/
2244 }
2245
2246
2247 /** gets array with fixed and aggregated problem variables; data may become invalid after
2248 * calls to SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar()
2249 *
2250 * @return an array with fixed and aggregated problem variables; data may become invalid after
2251 * calls to SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar()
2252 *
2253 * @pre This method can be called if @p scip is in one of the following stages:
2254 * - \ref SCIP_STAGE_PROBLEM
2255 * - \ref SCIP_STAGE_TRANSFORMED
2256 * - \ref SCIP_STAGE_INITPRESOLVE
2257 * - \ref SCIP_STAGE_PRESOLVING
2258 * - \ref SCIP_STAGE_EXITPRESOLVE
2259 * - \ref SCIP_STAGE_PRESOLVED
2260 * - \ref SCIP_STAGE_INITSOLVE
2261 * - \ref SCIP_STAGE_SOLVING
2262 * - \ref SCIP_STAGE_SOLVED
2263 */
2264 SCIP_VAR** SCIPgetFixedVars(
2265 SCIP* scip /**< SCIP data structure */
2266 )
2267 {
2268 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetFixedVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2269
2270 switch( scip->set->stage )
2271 {
2272 case SCIP_STAGE_PROBLEM:
2273 return NULL;
2274
2275 case SCIP_STAGE_TRANSFORMED:
2276 case SCIP_STAGE_INITPRESOLVE:
2277 case SCIP_STAGE_PRESOLVING:
2278 case SCIP_STAGE_EXITPRESOLVE:
2279 case SCIP_STAGE_PRESOLVED:
2280 case SCIP_STAGE_INITSOLVE:
2281 case SCIP_STAGE_SOLVING:
2282 case SCIP_STAGE_SOLVED:
2283 return scip->transprob->fixedvars;
2284
2285 default:
2286 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2287 SCIPABORT();
2288 return NULL; /*lint !e527*/
2289 } /*lint !e788*/
2290 }
2291
2292 /** gets number of fixed or aggregated problem variables
2293 *
2294 * @return the number of fixed or aggregated problem variables
2295 *
2296 * @pre This method can be called if @p scip is in one of the following stages:
2297 * - \ref SCIP_STAGE_PROBLEM
2298 * - \ref SCIP_STAGE_TRANSFORMED
2299 * - \ref SCIP_STAGE_INITPRESOLVE
2300 * - \ref SCIP_STAGE_PRESOLVING
2301 * - \ref SCIP_STAGE_EXITPRESOLVE
2302 * - \ref SCIP_STAGE_PRESOLVED
2303 * - \ref SCIP_STAGE_INITSOLVE
2304 * - \ref SCIP_STAGE_SOLVING
2305 * - \ref SCIP_STAGE_SOLVED
2306 */
2307 int SCIPgetNFixedVars(
2308 SCIP* scip /**< SCIP data structure */
2309 )
2310 {
2311 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNFixedVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2312
2313 switch( scip->set->stage )
2314 {
2315 case SCIP_STAGE_PROBLEM:
2316 return 0;
2317
2318 case SCIP_STAGE_TRANSFORMED:
2319 case SCIP_STAGE_INITPRESOLVE:
2320 case SCIP_STAGE_PRESOLVING:
2321 case SCIP_STAGE_EXITPRESOLVE:
2322 case SCIP_STAGE_PRESOLVED:
2323 case SCIP_STAGE_INITSOLVE:
2324 case SCIP_STAGE_SOLVING:
2325 case SCIP_STAGE_SOLVED:
2326 return scip->transprob->nfixedvars;
2327
2328 default:
2329 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2330 SCIPABORT();
2331 return 0; /*lint !e527*/
2332 } /*lint !e788*/
2333 }
2334
2335 /** gets variables of the original problem along with the numbers of different variable types; data may become invalid
2336 * after a call to SCIPchgVarType()
2337 *
2338 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2339 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2340 *
2341 * @pre This method can be called if @p scip is in one of the following stages:
2342 * - \ref SCIP_STAGE_PROBLEM
2343 * - \ref SCIP_STAGE_TRANSFORMING
2344 * - \ref SCIP_STAGE_TRANSFORMED
2345 * - \ref SCIP_STAGE_INITPRESOLVE
2346 * - \ref SCIP_STAGE_PRESOLVING
2347 * - \ref SCIP_STAGE_EXITPRESOLVE
2348 * - \ref SCIP_STAGE_PRESOLVED
2349 * - \ref SCIP_STAGE_INITSOLVE
2350 * - \ref SCIP_STAGE_SOLVING
2351 * - \ref SCIP_STAGE_SOLVED
2352 * - \ref SCIP_STAGE_EXITSOLVE
2353 * - \ref SCIP_STAGE_FREETRANS
2354 */
2355 SCIP_RETCODE SCIPgetOrigVarsData(
2356 SCIP* scip, /**< SCIP data structure */
2357 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */
2358 int* nvars, /**< pointer to store number of variables or NULL if not needed */
2359 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */
2360 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */
2361 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */
2362 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */
2363 )
2364 {
2365 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetOrigVarsData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2366
2367 if( vars != NULL )
2368 *vars = scip->origprob->vars;
2369 if( nvars != NULL )
2370 *nvars = scip->origprob->nvars;
2371 if( nbinvars != NULL )
2372 *nbinvars = scip->origprob->nbinvars;
2373 if( nintvars != NULL )
2374 *nintvars = scip->origprob->nintvars;
2375 if( nimplvars != NULL )
2376 *nimplvars = scip->origprob->nimplvars;
2377 if( ncontvars != NULL )
2378 *ncontvars = scip->origprob->ncontvars;
2379
2380 return SCIP_OKAY;
2381 }
2382
2383 /** gets array with original problem variables; data may become invalid after
2384 * a call to SCIPchgVarType()
2385 *
2386 * @return an array with original problem variables; data may become invalid after
2387 * a call to SCIPchgVarType()
2388 *
2389 * @pre This method can be called if @p scip is in one of the following stages:
2390 * - \ref SCIP_STAGE_PROBLEM
2391 * - \ref SCIP_STAGE_TRANSFORMING
2392 * - \ref SCIP_STAGE_TRANSFORMED
2393 * - \ref SCIP_STAGE_INITPRESOLVE
2394 * - \ref SCIP_STAGE_PRESOLVING
2395 * - \ref SCIP_STAGE_EXITPRESOLVE
2396 * - \ref SCIP_STAGE_PRESOLVED
2397 * - \ref SCIP_STAGE_INITSOLVE
2398 * - \ref SCIP_STAGE_SOLVING
2399 * - \ref SCIP_STAGE_SOLVED
2400 * - \ref SCIP_STAGE_EXITSOLVE
2401 * - \ref SCIP_STAGE_FREETRANS
2402 */
2403 SCIP_VAR** SCIPgetOrigVars(
2404 SCIP* scip /**< SCIP data structure */
2405 )
2406 {
2407 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2408
2409 return scip->origprob->vars;
2410 }
2411
2412 /** gets number of original problem variables
2413 *
2414 * @return the number of original problem variables
2415 *
2416 * @pre This method can be called if @p scip is in one of the following stages:
2417 * - \ref SCIP_STAGE_PROBLEM
2418 * - \ref SCIP_STAGE_TRANSFORMING
2419 * - \ref SCIP_STAGE_TRANSFORMED
2420 * - \ref SCIP_STAGE_INITPRESOLVE
2421 * - \ref SCIP_STAGE_PRESOLVING
2422 * - \ref SCIP_STAGE_EXITPRESOLVE
2423 * - \ref SCIP_STAGE_PRESOLVED
2424 * - \ref SCIP_STAGE_INITSOLVE
2425 * - \ref SCIP_STAGE_SOLVING
2426 * - \ref SCIP_STAGE_SOLVED
2427 * - \ref SCIP_STAGE_EXITSOLVE
2428 * - \ref SCIP_STAGE_FREETRANS
2429 */
2430 int SCIPgetNOrigVars(
2431 SCIP* scip /**< SCIP data structure */
2432 )
2433 {
2434 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2435
2436 return scip->origprob->nvars;
2437 }
2438
2439 /** gets number of binary variables in the original problem
2440 *
2441 * @return the number of binary variables in the original problem
2442 *
2443 * @pre This method can be called if @p scip is in one of the following stages:
2444 * - \ref SCIP_STAGE_PROBLEM
2445 * - \ref SCIP_STAGE_TRANSFORMING
2446 * - \ref SCIP_STAGE_TRANSFORMED
2447 * - \ref SCIP_STAGE_INITPRESOLVE
2448 * - \ref SCIP_STAGE_PRESOLVING
2449 * - \ref SCIP_STAGE_EXITPRESOLVE
2450 * - \ref SCIP_STAGE_PRESOLVED
2451 * - \ref SCIP_STAGE_INITSOLVE
2452 * - \ref SCIP_STAGE_SOLVING
2453 * - \ref SCIP_STAGE_SOLVED
2454 * - \ref SCIP_STAGE_EXITSOLVE
2455 * - \ref SCIP_STAGE_FREETRANS
2456 */
2457 int SCIPgetNOrigBinVars(
2458 SCIP* scip /**< SCIP data structure */
2459 )
2460 {
2461 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigBinVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2462
2463 return scip->origprob->nbinvars;
2464 }
2465
2466 /** gets the number of integer variables in the original problem
2467 *
2468 * @return the number of integer variables in the original problem
2469 *
2470 * @pre This method can be called if @p scip is in one of the following stages:
2471 * - \ref SCIP_STAGE_PROBLEM
2472 * - \ref SCIP_STAGE_TRANSFORMING
2473 * - \ref SCIP_STAGE_TRANSFORMED
2474 * - \ref SCIP_STAGE_INITPRESOLVE
2475 * - \ref SCIP_STAGE_PRESOLVING
2476 * - \ref SCIP_STAGE_EXITPRESOLVE
2477 * - \ref SCIP_STAGE_PRESOLVED
2478 * - \ref SCIP_STAGE_INITSOLVE
2479 * - \ref SCIP_STAGE_SOLVING
2480 * - \ref SCIP_STAGE_SOLVED
2481 * - \ref SCIP_STAGE_EXITSOLVE
2482 * - \ref SCIP_STAGE_FREETRANS
2483 */
2484 int SCIPgetNOrigIntVars(
2485 SCIP* scip /**< SCIP data structure */
2486 )
2487 {
2488 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigIntVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2489
2490 return scip->origprob->nintvars;
2491 }
2492
2493 /** gets number of implicit integer variables in the original problem
2494 *
2495 * @return the number of implicit integer variables in the original problem
2496 *
2497 * @pre This method can be called if @p scip is in one of the following stages:
2498 * - \ref SCIP_STAGE_PROBLEM
2499 * - \ref SCIP_STAGE_TRANSFORMING
2500 * - \ref SCIP_STAGE_TRANSFORMED
2501 * - \ref SCIP_STAGE_INITPRESOLVE
2502 * - \ref SCIP_STAGE_PRESOLVING
2503 * - \ref SCIP_STAGE_EXITPRESOLVE
2504 * - \ref SCIP_STAGE_PRESOLVED
2505 * - \ref SCIP_STAGE_INITSOLVE
2506 * - \ref SCIP_STAGE_SOLVING
2507 * - \ref SCIP_STAGE_SOLVED
2508 * - \ref SCIP_STAGE_EXITSOLVE
2509 * - \ref SCIP_STAGE_FREETRANS
2510 */
2511 int SCIPgetNOrigImplVars(
2512 SCIP* scip /**< SCIP data structure */
2513 )
2514 {
2515 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigImplVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2516
2517 return scip->origprob->nimplvars;
2518 }
2519
2520 /** gets number of continuous variables in the original problem
2521 *
2522 * @return the number of continuous variables in the original problem
2523 *
2524 * @pre This method can be called if @p scip is in one of the following stages:
2525 * - \ref SCIP_STAGE_PROBLEM
2526 * - \ref SCIP_STAGE_TRANSFORMING
2527 * - \ref SCIP_STAGE_TRANSFORMED
2528 * - \ref SCIP_STAGE_INITPRESOLVE
2529 * - \ref SCIP_STAGE_PRESOLVING
2530 * - \ref SCIP_STAGE_EXITPRESOLVE
2531 * - \ref SCIP_STAGE_PRESOLVED
2532 * - \ref SCIP_STAGE_INITSOLVE
2533 * - \ref SCIP_STAGE_SOLVING
2534 * - \ref SCIP_STAGE_SOLVED
2535 * - \ref SCIP_STAGE_EXITSOLVE
2536 * - \ref SCIP_STAGE_FREETRANS
2537 */
2538 int SCIPgetNOrigContVars(
2539 SCIP* scip /**< SCIP data structure */
2540 )
2541 {
2542 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigContVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2543
2544 return scip->origprob->ncontvars;
2545 }
2546
2547 /** gets number of all problem variables created during creation and solving of problem;
2548 * this includes also variables that were deleted in the meantime
2549 *
2550 * @return the number of all problem variables created during creation and solving of problem;
2551 * this includes also variables that were deleted in the meantime
2552 *
2553 * @pre This method can be called if @p scip is in one of the following stages:
2554 * - \ref SCIP_STAGE_PROBLEM
2555 * - \ref SCIP_STAGE_TRANSFORMING
2556 * - \ref SCIP_STAGE_TRANSFORMED
2557 * - \ref SCIP_STAGE_INITPRESOLVE
2558 * - \ref SCIP_STAGE_PRESOLVING
2559 * - \ref SCIP_STAGE_EXITPRESOLVE
2560 * - \ref SCIP_STAGE_PRESOLVED
2561 * - \ref SCIP_STAGE_INITSOLVE
2562 * - \ref SCIP_STAGE_SOLVING
2563 * - \ref SCIP_STAGE_SOLVED
2564 * - \ref SCIP_STAGE_EXITSOLVE
2565 * - \ref SCIP_STAGE_FREETRANS
2566 */
2567 int SCIPgetNTotalVars(
2568 SCIP* scip /**< SCIP data structure */
2569 )
2570 {
2571 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNTotalVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2572
2573 assert(scip->stat != NULL);
2574
2575 switch( scip->set->stage )
2576 {
2577 case SCIP_STAGE_PROBLEM:
2578 case SCIP_STAGE_TRANSFORMING:
2579 case SCIP_STAGE_TRANSFORMED:
2580 case SCIP_STAGE_INITPRESOLVE:
2581 case SCIP_STAGE_PRESOLVING:
2582 case SCIP_STAGE_EXITPRESOLVE:
2583 case SCIP_STAGE_PRESOLVED:
2584 case SCIP_STAGE_INITSOLVE:
2585 case SCIP_STAGE_SOLVING:
2586 case SCIP_STAGE_SOLVED:
2587 case SCIP_STAGE_EXITSOLVE:
2588 case SCIP_STAGE_FREETRANS:
2589 return scip->stat->nvaridx;
2590
2591 default:
2592 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2593 SCIPABORT();
2594 return 0; /*lint !e527*/
2595 } /*lint !e788*/
2596 }
2597
2598
2599 /** gets variables of the original or transformed problem along with the numbers of different variable types;
2600 * the returned problem space (original or transformed) corresponds to the given solution;
2601 * data may become invalid after calls to SCIPchgVarType(), SCIPfixVar(), SCIPaggregateVars(), and
2602 * SCIPmultiaggregateVar()
2603 *
2604 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2605 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2606 *
2607 * @pre This method can be called if @p scip is in one of the following stages:
2608 * - \ref SCIP_STAGE_PROBLEM
2609 * - \ref SCIP_STAGE_TRANSFORMED
2610 * - \ref SCIP_STAGE_INITPRESOLVE
2611 * - \ref SCIP_STAGE_PRESOLVING
2612 * - \ref SCIP_STAGE_EXITPRESOLVE
2613 * - \ref SCIP_STAGE_PRESOLVED
2614 * - \ref SCIP_STAGE_INITSOLVE
2615 * - \ref SCIP_STAGE_SOLVING
2616 * - \ref SCIP_STAGE_SOLVED
2617 */
2618 SCIP_RETCODE SCIPgetSolVarsData(
2619 SCIP* scip, /**< SCIP data structure */
2620 SCIP_SOL* sol, /**< primal solution that selects the problem space, NULL for current solution */
2621 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */
2622 int* nvars, /**< pointer to store number of variables or NULL if not needed */
2623 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */
2624 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */
2625 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */
2626 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */
2627 )
2628 {
2629 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetSolVarsData", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
2630
2631 if( scip->set->stage == SCIP_STAGE_PROBLEM || (sol != NULL && SCIPsolIsOriginal(sol)) )
2632 {
2633 if( vars != NULL )
2634 *vars = scip->origprob->vars;
2635 if( nvars != NULL )
2636 *nvars = scip->origprob->nvars;
2637 if( nbinvars != NULL )
2638 *nbinvars = scip->origprob->nbinvars;
2639 if( nintvars != NULL )
2640 *nintvars = scip->origprob->nintvars;
2641 if( nimplvars != NULL )
2642 *nimplvars = scip->origprob->nimplvars;
2643 if( ncontvars != NULL )
2644 *ncontvars = scip->origprob->ncontvars;
2645 }
2646 else
2647 {
2648 if( vars != NULL )
2649 *vars = scip->transprob->vars;
2650 if( nvars != NULL )
2651 *nvars = scip->transprob->nvars;
2652 if( nbinvars != NULL )
2653 *nbinvars = scip->transprob->nbinvars;
2654 if( nintvars != NULL )
2655 *nintvars = scip->transprob->nintvars;
2656 if( nimplvars != NULL )
2657 *nimplvars = scip->transprob->nimplvars;
2658 if( ncontvars != NULL )
2659 *ncontvars = scip->transprob->ncontvars;
2660 }
2661
2662 return SCIP_OKAY;
2663 }
2664
2665 /** returns variable of given name in the problem, or NULL if not existing
2666 *
2667 * @return variable of given name in the problem, or NULL if not existing
2668 *
2669 * @pre This method can be called if @p scip is in one of the following stages:
2670 * - \ref SCIP_STAGE_PROBLEM
2671 * - \ref SCIP_STAGE_TRANSFORMING
2672 * - \ref SCIP_STAGE_TRANSFORMED
2673 * - \ref SCIP_STAGE_INITPRESOLVE
2674 * - \ref SCIP_STAGE_PRESOLVING
2675 * - \ref SCIP_STAGE_EXITPRESOLVE
2676 * - \ref SCIP_STAGE_PRESOLVED
2677 * - \ref SCIP_STAGE_INITSOLVE
2678 * - \ref SCIP_STAGE_SOLVING
2679 * - \ref SCIP_STAGE_SOLVED
2680 * - \ref SCIP_STAGE_EXITSOLVE
2681 * - \ref SCIP_STAGE_FREETRANS
2682 */
2683 SCIP_VAR* SCIPfindVar(
2684 SCIP* scip, /**< SCIP data structure */
2685 const char* name /**< name of variable to find */
2686 )
2687 {
2688 SCIP_VAR* var;
2689
2690 assert(name != NULL);
2691
2692 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2693
2694 switch( scip->set->stage )
2695 {
2696 case SCIP_STAGE_PROBLEM:
2697 return SCIPprobFindVar(scip->origprob, name);
2698
2699 case SCIP_STAGE_TRANSFORMING:
2700 case SCIP_STAGE_TRANSFORMED:
2701 case SCIP_STAGE_INITPRESOLVE:
2702 case SCIP_STAGE_PRESOLVING:
2703 case SCIP_STAGE_EXITPRESOLVE:
2704 case SCIP_STAGE_PRESOLVED:
2705 case SCIP_STAGE_INITSOLVE:
2706 case SCIP_STAGE_SOLVING:
2707 case SCIP_STAGE_SOLVED:
2708 case SCIP_STAGE_EXITSOLVE:
2709 case SCIP_STAGE_FREETRANS:
2710 var = SCIPprobFindVar(scip->transprob, name);
2711 if( var == NULL )
2712 return SCIPprobFindVar(scip->origprob, name);
2713 else
2714 return var;
2715
2716 default:
2717 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2718 SCIPABORT();
2719 return NULL; /*lint !e527*/
2720 } /*lint !e788*/
2721 }
2722
2723 /** returns TRUE iff all potential variables exist in the problem, and FALSE, if there may be additional variables,
2724 * that will be added in pricing and improve the objective value
2725 *
2726 * @return TRUE, if all potential variables exist in the problem; FALSE, otherwise
2727 *
2728 * @pre This method can be called if @p scip is in one of the following stages:
2729 * - \ref SCIP_STAGE_TRANSFORMING
2730 * - \ref SCIP_STAGE_TRANSFORMED
2731 * - \ref SCIP_STAGE_INITPRESOLVE
2732 * - \ref SCIP_STAGE_PRESOLVING
2733 * - \ref SCIP_STAGE_EXITPRESOLVE
2734 * - \ref SCIP_STAGE_PRESOLVED
2735 * - \ref SCIP_STAGE_INITSOLVE
2736 * - \ref SCIP_STAGE_SOLVING
2737 * - \ref SCIP_STAGE_SOLVED
2738 * - \ref SCIP_STAGE_EXITSOLVE
2739 * - \ref SCIP_STAGE_FREETRANS
2740 */
2741 SCIP_Bool SCIPallVarsInProb(
2742 SCIP* scip /**< SCIP data structure */
2743 )
2744 {
2745 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPallVarsInProb", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2746
2747 return (scip->set->nactivepricers == 0);
2748 }
2749
2750 /** adds constraint to the problem; if constraint is only valid locally, it is added to the local subproblem of the
2751 * current node (and all of its subnodes); otherwise it is added to the global problem;
2752 * if a local constraint is added at the root node, it is automatically upgraded into a global constraint
2753 *
2754 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2755 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2756 *
2757 * @pre This method can be called if @p scip is in one of the following stages:
2758 * - \ref SCIP_STAGE_PROBLEM
2759 * - \ref SCIP_STAGE_TRANSFORMED
2760 * - \ref SCIP_STAGE_INITPRESOLVE
2761 * - \ref SCIP_STAGE_PRESOLVING
2762 * - \ref SCIP_STAGE_EXITPRESOLVE
2763 * - \ref SCIP_STAGE_PRESOLVED
2764 * - \ref SCIP_STAGE_INITSOLVE
2765 * - \ref SCIP_STAGE_SOLVING
2766 * - \ref SCIP_STAGE_EXITSOLVE
2767 */
2768 SCIP_RETCODE SCIPaddCons(
2769 SCIP* scip, /**< SCIP data structure */
2770 SCIP_CONS* cons /**< constraint to add */
2771 )
2772 {
2773 assert(cons != NULL);
2774
2775 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCons", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) );
2776
2777 switch( scip->set->stage )
2778 {
2779 case SCIP_STAGE_PROBLEM:
2780 {
2781 SCIP_CALL( SCIPprobAddCons(scip->origprob, scip->set, scip->stat, cons) );
2782
2783 if( scip->set->reopt_enable )
2784 {
2785 SCIP_CALL( SCIPreoptAddCons(scip->reopt, scip->set, scip->mem->probmem, cons) );
2786 }
2787 }
2788 return SCIP_OKAY;
2789
2790 case SCIP_STAGE_TRANSFORMED:
2791 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) );
2792 return SCIP_OKAY;
2793
2794 case SCIP_STAGE_INITPRESOLVE:
2795 case SCIP_STAGE_PRESOLVING:
2796 case SCIP_STAGE_EXITPRESOLVE:
2797 case SCIP_STAGE_PRESOLVED:
2798 case SCIP_STAGE_INITSOLVE:
2799 case SCIP_STAGE_SOLVING:
2800 assert( SCIPtreeGetCurrentDepth(scip->tree) >= 0 || scip->set->stage == SCIP_STAGE_PRESOLVED
2801 || scip->set->stage == SCIP_STAGE_INITSOLVE );
2802 if( SCIPtreeGetCurrentDepth(scip->tree) <= SCIPtreeGetEffectiveRootDepth(scip->tree) )
2803 SCIPconsSetLocal(cons, FALSE);
2804 if( SCIPconsIsGlobal(cons) )
2805 {
2806 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) );
2807 }
2808 else
2809 {
2810 assert(SCIPtreeGetCurrentDepth(scip->tree) > SCIPtreeGetEffectiveRootDepth(scip->tree));
2811 SCIP_CALL( SCIPnodeAddCons(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat,
2812 scip->tree, cons) );
2813 }
2814 return SCIP_OKAY;
2815
2816 case SCIP_STAGE_EXITSOLVE:
2817 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) );
2818 return SCIP_OKAY;
2819
2820 default:
2821 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2822 return SCIP_INVALIDCALL;
2823 } /*lint !e788*/
2824 }
2825
2826 /** globally removes constraint from all subproblems; removes constraint from the constraint set change data of the
2827 * node, where it was added, or from the problem, if it was a problem constraint
2828 *
2829 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2830 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2831 *
2832 * @pre This method can be called if @p scip is in one of the following stages:
2833 * - \ref SCIP_STAGE_PROBLEM
2834 * - \ref SCIP_STAGE_INITPRESOLVE
2835 * - \ref SCIP_STAGE_PRESOLVING
2836 * - \ref SCIP_STAGE_EXITPRESOLVE
2837 * - \ref SCIP_STAGE_INITSOLVE
2838 * - \ref SCIP_STAGE_SOLVING
2839 * - \ref SCIP_STAGE_EXITSOLVE
2840 */
2841 SCIP_RETCODE SCIPdelCons(
2842 SCIP* scip, /**< SCIP data structure */
2843 SCIP_CONS* cons /**< constraint to delete */
2844 )
2845 {
2846 assert(cons != NULL);
2847
2848 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelCons", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) );
2849
2850 switch( scip->set->stage )
2851 {
2852 case SCIP_STAGE_PROBLEM:
2853 assert(cons->addconssetchg == NULL);
2854 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->reopt) );
2855 return SCIP_OKAY;
2856
2857 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction
2858 * might be wrong
2859 */
2860 case SCIP_STAGE_INITPRESOLVE:
2861 case SCIP_STAGE_EXITPRESOLVE:
2862 assert(SCIPconsIsAdded(cons));
2863 /*lint -fallthrough*/
2864
2865 case SCIP_STAGE_PRESOLVING:
2866 case SCIP_STAGE_INITSOLVE:
2867 case SCIP_STAGE_SOLVING:
2868 case SCIP_STAGE_EXITSOLVE:
2869 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) );
2870 return SCIP_OKAY;
2871
2872 default:
2873 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2874 return SCIP_INVALIDCALL;
2875 } /*lint !e788*/
2876 }
2877
2878 /** returns original constraint of given name in the problem, or NULL if not existing
2879 *
2880 * @return original constraint of given name in the problem, or NULL if not existing
2881 *
2882 * @pre This method can be called if @p scip is in one of the following stages:
2883 * - \ref SCIP_STAGE_PROBLEM
2884 * - \ref SCIP_STAGE_TRANSFORMING
2885 * - \ref SCIP_STAGE_TRANSFORMED
2886 * - \ref SCIP_STAGE_INITPRESOLVE
2887 * - \ref SCIP_STAGE_PRESOLVING
2888 * - \ref SCIP_STAGE_EXITPRESOLVE
2889 * - \ref SCIP_STAGE_PRESOLVED
2890 * - \ref SCIP_STAGE_INITSOLVE
2891 * - \ref SCIP_STAGE_SOLVING
2892 * - \ref SCIP_STAGE_SOLVED
2893 * - \ref SCIP_STAGE_EXITSOLVE
2894 * - \ref SCIP_STAGE_FREETRANS
2895 */
2896 SCIP_CONS* SCIPfindOrigCons(
2897 SCIP* scip, /**< SCIP data structure */
2898 const char* name /**< name of constraint to find */
2899 )
2900 {
2901 assert(name != NULL);
2902
2903 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindOrigCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2904
2905 switch( scip->set->stage )
2906 {
2907 case SCIP_STAGE_PROBLEM:
2908 case SCIP_STAGE_TRANSFORMING:
2909 case SCIP_STAGE_TRANSFORMED:
2910 case SCIP_STAGE_INITPRESOLVE:
2911 case SCIP_STAGE_PRESOLVING:
2912 case SCIP_STAGE_EXITPRESOLVE:
2913 case SCIP_STAGE_PRESOLVED:
2914 case SCIP_STAGE_SOLVING:
2915 case SCIP_STAGE_SOLVED:
2916 case SCIP_STAGE_EXITSOLVE:
2917 case SCIP_STAGE_FREETRANS:
2918 return SCIPprobFindCons(scip->origprob, name);
2919
2920 default:
2921 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2922 SCIPABORT();
2923 return NULL; /*lint !e527*/
2924 } /*lint !e788*/
2925 }
2926
2927 /** returns constraint of given name in the problem, or NULL if not existing
2928 *
2929 * @return constraint of given name in the problem, or NULL if not existing
2930 *
2931 * @pre This method can be called if @p scip is in one of the following stages:
2932 * - \ref SCIP_STAGE_PROBLEM
2933 * - \ref SCIP_STAGE_TRANSFORMING
2934 * - \ref SCIP_STAGE_TRANSFORMED
2935 * - \ref SCIP_STAGE_INITPRESOLVE
2936 * - \ref SCIP_STAGE_PRESOLVING
2937 * - \ref SCIP_STAGE_EXITPRESOLVE
2938 * - \ref SCIP_STAGE_PRESOLVED
2939 * - \ref SCIP_STAGE_INITSOLVE
2940 * - \ref SCIP_STAGE_SOLVING
2941 * - \ref SCIP_STAGE_SOLVED
2942 * - \ref SCIP_STAGE_EXITSOLVE
2943 * - \ref SCIP_STAGE_FREETRANS
2944 */
2945 SCIP_CONS* SCIPfindCons(
2946 SCIP* scip, /**< SCIP data structure */
2947 const char* name /**< name of constraint to find */
2948 )
2949 {
2950 SCIP_CONS* cons;
2951
2952 assert(name != NULL);
2953
2954 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2955
2956 switch( scip->set->stage )
2957 {
2958 case SCIP_STAGE_PROBLEM:
2959 return SCIPprobFindCons(scip->origprob, name);
2960
2961 case SCIP_STAGE_TRANSFORMING:
2962 case SCIP_STAGE_TRANSFORMED:
2963 case SCIP_STAGE_INITPRESOLVE:
2964 case SCIP_STAGE_PRESOLVING:
2965 case SCIP_STAGE_EXITPRESOLVE:
2966 case SCIP_STAGE_PRESOLVED:
2967 case SCIP_STAGE_SOLVING:
2968 case SCIP_STAGE_SOLVED:
2969 case SCIP_STAGE_EXITSOLVE:
2970 case SCIP_STAGE_FREETRANS:
2971 cons = SCIPprobFindCons(scip->transprob, name);
2972 if( cons == NULL )
2973 return SCIPprobFindCons(scip->origprob, name);
2974 else
2975 return cons;
2976
2977 default:
2978 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2979 SCIPABORT();
2980 return NULL; /*lint !e527*/
2981 } /*lint !e788*/
2982 }
2983
2984 /** gets number of upgraded constraints
2985 *
2986 * @return number of upgraded constraints
2987 *
2988 * @pre This method can be called if @p scip is in one of the following stages:
2989 * - \ref SCIP_STAGE_PROBLEM
2990 * - \ref SCIP_STAGE_TRANSFORMED
2991 * - \ref SCIP_STAGE_INITPRESOLVE
2992 * - \ref SCIP_STAGE_PRESOLVING
2993 * - \ref SCIP_STAGE_PRESOLVED
2994 * - \ref SCIP_STAGE_EXITPRESOLVE
2995 * - \ref SCIP_STAGE_SOLVING
2996 * - \ref SCIP_STAGE_SOLVED
2997 */
2998 int SCIPgetNUpgrConss(
2999 SCIP* scip /**< SCIP data structure */
3000 )
3001 {
3002 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNUpgrConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3003
3004 switch( scip->set->stage )
3005 {
3006 case SCIP_STAGE_PROBLEM:
3007 return 0;
3008
3009 case SCIP_STAGE_TRANSFORMED:
3010 case SCIP_STAGE_INITPRESOLVE:
3011 case SCIP_STAGE_PRESOLVING:
3012 case SCIP_STAGE_EXITPRESOLVE:
3013 case SCIP_STAGE_PRESOLVED:
3014 case SCIP_STAGE_SOLVING:
3015 case SCIP_STAGE_SOLVED:
3016 return scip->stat->npresolupgdconss;
3017
3018 default:
3019 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3020 SCIPABORT();
3021 return 0; /*lint !e527*/
3022 } /*lint !e788*/
3023 }
3024
3025 /** gets total number of globally valid constraints currently in the problem
3026 *
3027 * @return total number of globally valid constraints currently in the problem
3028 *
3029 * @pre This method can be called if @p scip is in one of the following stages:
3030 * - \ref SCIP_STAGE_PROBLEM
3031 * - \ref SCIP_STAGE_TRANSFORMED
3032 * - \ref SCIP_STAGE_INITPRESOLVE
3033 * - \ref SCIP_STAGE_PRESOLVING
3034 * - \ref SCIP_STAGE_EXITPRESOLVE
3035 * - \ref SCIP_STAGE_PRESOLVED
3036 * - \ref SCIP_STAGE_INITSOLVE
3037 * - \ref SCIP_STAGE_SOLVING
3038 * - \ref SCIP_STAGE_SOLVED
3039 */
3040 int SCIPgetNConss(
3041 SCIP* scip /**< SCIP data structure */
3042 )
3043 {
3044 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3045
3046 switch( scip->set->stage )
3047 {
3048 case SCIP_STAGE_PROBLEM:
3049 return scip->origprob->nconss;
3050
3051 case SCIP_STAGE_TRANSFORMED:
3052 case SCIP_STAGE_INITPRESOLVE:
3053 case SCIP_STAGE_PRESOLVING:
3054 case SCIP_STAGE_EXITPRESOLVE:
3055 case SCIP_STAGE_PRESOLVED:
3056 case SCIP_STAGE_INITSOLVE:
3057 case SCIP_STAGE_SOLVING:
3058 case SCIP_STAGE_SOLVED:
3059 return scip->transprob->nconss;
3060
3061 default:
3062 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3063 SCIPABORT();
3064 return 0; /*lint !e527*/
3065 } /*lint !e788*/
3066 }
3067
3068 /** gets array of globally valid constraints currently in the problem
3069 *
3070 * @return array of globally valid constraints currently in the problem
3071 *
3072 * @pre This method can be called if @p scip is in one of the following stages:
3073 * - \ref SCIP_STAGE_PROBLEM
3074 * - \ref SCIP_STAGE_TRANSFORMED
3075 * - \ref SCIP_STAGE_INITPRESOLVE
3076 * - \ref SCIP_STAGE_PRESOLVING
3077 * - \ref SCIP_STAGE_EXITPRESOLVE
3078 * - \ref SCIP_STAGE_PRESOLVED
3079 * - \ref SCIP_STAGE_INITSOLVE
3080 * - \ref SCIP_STAGE_SOLVING
3081 * - \ref SCIP_STAGE_SOLVED
3082 *
3083 * @warning If your are using the method SCIPaddCons(), it can happen that the internal constraint array (which is
3084 * accessed via this method) gets resized. This can invalid the pointer which is returned by this method.
3085 */
3086 SCIP_CONS** SCIPgetConss(
3087 SCIP* scip /**< SCIP data structure */
3088 )
3089 {
3090 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3091
3092 switch( scip->set->stage )
3093 {
3094 case SCIP_STAGE_PROBLEM:
3095 return scip->origprob->conss;
3096
3097 case SCIP_STAGE_TRANSFORMED:
3098 case SCIP_STAGE_INITPRESOLVE:
3099 case SCIP_STAGE_PRESOLVING:
3100 case SCIP_STAGE_EXITPRESOLVE:
3101 case SCIP_STAGE_PRESOLVED:
3102 case SCIP_STAGE_INITSOLVE:
3103 case SCIP_STAGE_SOLVING:
3104 case SCIP_STAGE_SOLVED:
3105 return scip->transprob->conss;
3106
3107 default:
3108 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3109 SCIPABORT();
3110 return NULL; /*lint !e527*/
3111 } /*lint !e788*/
3112 }
3113
3114 /** gets total number of constraints in the original problem
3115 *
3116 * @return total number of constraints in the original problem
3117 *
3118 * @pre This method can be called if @p scip is in one of the following stages:
3119 * - \ref SCIP_STAGE_PROBLEM
3120 * - \ref SCIP_STAGE_TRANSFORMING
3121 * - \ref SCIP_STAGE_TRANSFORMED
3122 * - \ref SCIP_STAGE_INITPRESOLVE
3123 * - \ref SCIP_STAGE_PRESOLVING
3124 * - \ref SCIP_STAGE_EXITPRESOLVE
3125 * - \ref SCIP_STAGE_PRESOLVED
3126 * - \ref SCIP_STAGE_INITSOLVE
3127 * - \ref SCIP_STAGE_SOLVING
3128 * - \ref SCIP_STAGE_SOLVED
3129 * - \ref SCIP_STAGE_EXITSOLVE
3130 * - \ref SCIP_STAGE_FREETRANS
3131 */
3132 int SCIPgetNOrigConss(
3133 SCIP* scip /**< SCIP data structure */
3134 )
3135 {
3136 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigConss", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3137
3138 return scip->origprob->nconss;
3139 }
3140
3141 /** gets array of constraints in the original problem
3142 *
3143 * @return array of constraints in the original problem
3144 *
3145 * @pre This method can be called if @p scip is in one of the following stages:
3146 * - \ref SCIP_STAGE_PROBLEM
3147 * - \ref SCIP_STAGE_TRANSFORMING
3148 * - \ref SCIP_STAGE_TRANSFORMED
3149 * - \ref SCIP_STAGE_INITPRESOLVE
3150 * - \ref SCIP_STAGE_PRESOLVING
3151 * - \ref SCIP_STAGE_EXITPRESOLVE
3152 * - \ref SCIP_STAGE_PRESOLVED
3153 * - \ref SCIP_STAGE_INITSOLVE
3154 * - \ref SCIP_STAGE_SOLVING
3155 * - \ref SCIP_STAGE_SOLVED
3156 * - \ref SCIP_STAGE_EXITSOLVE
3157 * - \ref SCIP_STAGE_FREETRANS
3158 */
3159 SCIP_CONS** SCIPgetOrigConss(
3160 SCIP* scip /**< SCIP data structure */
3161 )
3162 {
3163 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigConss", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
3164
3165 return scip->origprob->conss;
3166 }
3167
3168 /** computes the number of check constraint in the current node (loop over all constraint handler and cumulates the
3169 * number of check constraints)
3170 *
3171 * @return returns the number of check constraints
3172 *
3173 * @pre This method can be called if @p scip is in one of the following stages:
3174 * - \ref SCIP_STAGE_TRANSFORMED
3175 * - \ref SCIP_STAGE_INITPRESOLVE
3176 * - \ref SCIP_STAGE_PRESOLVING
3177 * - \ref SCIP_STAGE_EXITPRESOLVE
3178 * - \ref SCIP_STAGE_PRESOLVED
3179 * - \ref SCIP_STAGE_INITSOLVE
3180 * - \ref SCIP_STAGE_SOLVING
3181 */
3182 int SCIPgetNCheckConss(
3183 SCIP* scip /**< SCIP data structure */
3184 )
3185 {
3186 SCIP_CONSHDLR** conshdlrs;
3187 int nconshdlrs;
3188 int ncheckconss;
3189 int c;
3190
3191 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCheckConss", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3192
3193 nconshdlrs = SCIPgetNConshdlrs(scip);
3194 conshdlrs = SCIPgetConshdlrs(scip);
3195 assert(conshdlrs != NULL);
3196
3197 ncheckconss = 0;
3198
3199 /* loop over all constraint handler and collect the number of constraints which need to be checked */
3200 for( c = 0; c < nconshdlrs; ++c )
3201 {
3202 assert(conshdlrs[c] != NULL);
3203 ncheckconss += SCIPconshdlrGetNCheckConss(conshdlrs[c]);
3204 }
3205
3206 return ncheckconss;
3207 }
3208
3209 /*
3210 * local subproblem methods
3211 */
3212
3213 /** adds a conflict to a given node or globally to the problem if @p node == NULL.
3214 *
3215 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3216 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3217 *
3218 * @pre this method can be called in one of the following stages of the SCIP solving process:
3219 * - \ref SCIP_STAGE_INITPRESOLVE
3220 * - \ref SCIP_STAGE_PRESOLVING
3221 * - \ref SCIP_STAGE_EXITPRESOLVE
3222 * - \ref SCIP_STAGE_SOLVING
3223 *
3224 * @note this method will release the constraint
3225 */
3226 SCIP_RETCODE SCIPaddConflict(
3227 SCIP* scip, /**< SCIP data structure */
3228 SCIP_NODE* node, /**< node to add conflict (or NULL if global) */
3229 SCIP_CONS* cons, /**< constraint representing the conflict */
3230 SCIP_NODE* validnode, /**< node at whichaddConf the constraint is valid (or NULL) */
3231 SCIP_CONFTYPE conftype, /**< type of the conflict */
3232 SCIP_Bool iscutoffinvolved /**< is a cutoff bound involved in this conflict */
3233 )
3234 {
3235 SCIP_Real primalbound;
3236
3237 assert(scip != NULL);
3238 assert(cons != NULL);
3239 assert(scip->conflictstore != NULL);
3240 assert(conftype != SCIP_CONFTYPE_BNDEXCEEDING || iscutoffinvolved);
3241
3242 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConflict", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3243
3244 if( iscutoffinvolved )
3245 primalbound = SCIPgetCutoffbound(scip);
3246 else
3247 primalbound = -SCIPinfinity(scip);
3248
3249 /* add a global conflict */
3250 if( node == NULL )
3251 {
3252 SCIP_CALL( SCIPaddCons(scip, cons) );
3253 }
3254 /* add a local conflict */
3255 else
3256 {
3257 SCIP_CALL( SCIPaddConsNode(scip, node, cons, validnode) );
3258 }
3259
3260 if( node == NULL || SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE )
3261 {
3262 /* add the conflict to the conflict store */
3263 SCIP_CALL( SCIPconflictstoreAddConflict(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->tree,
3264 scip->transprob, scip->reopt, cons, conftype, iscutoffinvolved, primalbound) );
3265 }
3266
3267 /* mark constraint to be a conflict */
3268 SCIPconsMarkConflict(cons);
3269
3270 SCIP_CALL( SCIPreleaseCons(scip, &cons) );
3271
3272 return SCIP_OKAY;
3273 }
3274
3275 /** tries to remove conflicts depending on an old cutoff bound if the improvement of the new incumbent is good enough
3276 *
3277 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3278 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3279 *
3280 * @pre this method can be called in one of the following stages of the SCIP solving process:
3281 * - \ref SCIP_STAGE_PRESOLVING
3282 * - \ref SCIP_STAGE_SOLVING
3283 */
3284 SCIP_RETCODE SCIPclearConflictStore(
3285 SCIP* scip, /**< SCIP data structure */
3286 SCIP_EVENT* event /**< event data */
3287 )
3288 {
3289 assert(scip != NULL);
3290 assert(event != NULL);
3291 assert(SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND);
3292 assert(SCIPeventGetSol(event) != NULL);
3293
3294 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearConflictStore", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3295
3296 SCIP_CALL( SCIPconflictstoreCleanNewIncumbent(scip->conflictstore, scip->set, scip->stat, scip->mem->probmem,
3297 scip->transprob, scip->reopt, scip->primal->cutoffbound) );
3298
3299 return SCIP_OKAY;
3300 }
3301
3302 /** adds constraint to the given node (and all of its subnodes), even if it is a global constraint;
3303 * It is sometimes desirable to add the constraint to a more local node (i.e., a node of larger depth) even if
3304 * the constraint is also valid higher in the tree, for example, if one wants to produce a constraint which is
3305 * only active in a small part of the tree although it is valid in a larger part.
3306 * In this case, one should pass the more global node where the constraint is valid as "validnode".
3307 * Note that the same constraint cannot be added twice to the branching tree with different "validnode" parameters.
3308 * If the constraint is valid at the same node as it is inserted (the usual case), one should pass NULL as "validnode".
3309 * If the "validnode" is the root node, it is automatically upgraded into a global constraint, but still only added to
3310 * the given node. If a local constraint is added to the root node, it is added to the global problem instead.
3311 *
3312 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3313 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3314 *
3315 * @pre this method can be called in one of the following stages of the SCIP solving process:
3316 * - \ref SCIP_STAGE_INITPRESOLVE
3317 * - \ref SCIP_STAGE_PRESOLVING
3318 * - \ref SCIP_STAGE_EXITPRESOLVE
3319 * - \ref SCIP_STAGE_SOLVING
3320 */
3321 SCIP_RETCODE SCIPaddConsNode(
3322 SCIP* scip, /**< SCIP data structure */
3323 SCIP_NODE* node, /**< node to add constraint to */
3324 SCIP_CONS* cons, /**< constraint to add */
3325 SCIP_NODE* validnode /**< node at which the constraint is valid, or NULL */
3326 )
3327 {
3328 assert(cons != NULL);
3329 assert(node != NULL);
3330
3331 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConsNode", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3332
3333 if( validnode != NULL )
3334 {
3335 int validdepth;
3336
3337 validdepth = SCIPnodeGetDepth(validnode);
3338 if( validdepth > SCIPnodeGetDepth(node) )
3339 {
3340 SCIPerrorMessage("cannot add constraint <%s> valid in depth %d to a node of depth %d\n",
3341 SCIPconsGetName(cons), validdepth, SCIPnodeGetDepth(node));
3342 return SCIP_INVALIDDATA;
3343 }
3344 if( cons->validdepth != -1 && cons->validdepth != validdepth )
3345 {
3346 SCIPerrorMessage("constraint <%s> is already marked to be valid in depth %d - cannot mark it to be valid in depth %d\n",
3347 SCIPconsGetName(cons), cons->validdepth, validdepth);
3348 return SCIP_INVALIDDATA;
3349 }
3350 if( validdepth <= SCIPtreeGetEffectiveRootDepth(scip->tree) )
3351 SCIPconsSetLocal(cons, FALSE);
3352 else
3353 cons->validdepth = validdepth;
3354 }
3355
3356 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) )
3357 {
3358 SCIPconsSetLocal(cons, FALSE);
3359 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) );
3360 }
3361 else
3362 {
3363 SCIP_CALL( SCIPnodeAddCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) );
3364 }
3365
3366 return SCIP_OKAY;
3367 }
3368
3369 /** adds constraint locally to the current node (and all of its subnodes), even if it is a global constraint;
3370 * It is sometimes desirable to add the constraint to a more local node (i.e., a node of larger depth) even if
3371 * the constraint is also valid higher in the tree, for example, if one wants to produce a constraint which is
3372 * only active in a small part of the tree although it is valid in a larger part.
3373 *
3374 * If the constraint is valid at the same node as it is inserted (the usual case), one should pass NULL as "validnode".
3375 * If the "validnode" is the root node, it is automatically upgraded into a global constraint, but still only added to
3376 * the given node. If a local constraint is added to the root node, it is added to the global problem instead.
3377 *
3378 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3379 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3380 *
3381 * @pre this method can be called in one of the following stages of the SCIP solving process:
3382 * - \ref SCIP_STAGE_INITPRESOLVE
3383 * - \ref SCIP_STAGE_PRESOLVING
3384 * - \ref SCIP_STAGE_EXITPRESOLVE
3385 * - \ref SCIP_STAGE_SOLVING
3386 *
3387 * @note The same constraint cannot be added twice to the branching tree with different "validnode" parameters. This is
3388 * the case due to internal data structures and performance issues. In such a case you should try to realize your
3389 * issue using the method SCIPdisableCons() and SCIPenableCons() and control these via the event system of SCIP.
3390 */
3391 SCIP_RETCODE SCIPaddConsLocal(
3392 SCIP* scip, /**< SCIP data structure */
3393 SCIP_CONS* cons, /**< constraint to add */
3394 SCIP_NODE* validnode /**< node at which the constraint is valid, or NULL */
3395 )
3396 {
3397 assert(cons != NULL);
3398
3399 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConsLocal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3400
3401 SCIP_CALL( SCIPaddConsNode(scip, SCIPtreeGetCurrentNode(scip->tree), cons, validnode) );
3402
3403 return SCIP_OKAY;
3404 }
3405
3406 /** disables constraint's separation, enforcing, and propagation capabilities at the given node (and all subnodes);
3407 * if the method is called at the root node, the constraint is globally deleted from the problem;
3408 * the constraint deletion is being remembered at the given node, s.t. after leaving the node's subtree, the constraint
3409 * is automatically enabled again, and after entering the node's subtree, it is automatically disabled;
3410 * this may improve performance because redundant checks on this constraint are avoided, but it consumes memory;
3411 * alternatively, use SCIPdisableCons()
3412 *
3413 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3414 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3415 *
3416 * @pre this method can be called in one of the following stages of the SCIP solving process:
3417 * - \ref SCIP_STAGE_INITPRESOLVE
3418 * - \ref SCIP_STAGE_PRESOLVING
3419 * - \ref SCIP_STAGE_EXITPRESOLVE
3420 * - \ref SCIP_STAGE_SOLVING
3421 */
3422 SCIP_RETCODE SCIPdelConsNode(
3423 SCIP* scip, /**< SCIP data structure */
3424 SCIP_NODE* node, /**< node to disable constraint in */
3425 SCIP_CONS* cons /**< constraint to locally delete */
3426 )
3427 {
3428 assert(cons != NULL);
3429
3430 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelConsNode", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3431
3432 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction
3433 * might be wrong
3434 */
3435 if( scip->set->stage == SCIP_STAGE_INITPRESOLVE || scip->set->stage == SCIP_STAGE_EXITPRESOLVE )
3436 assert(SCIPconsIsAdded(cons));
3437
3438 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) )
3439 {
3440 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) );
3441 }
3442 else
3443 {
3444 SCIP_CALL( SCIPnodeDelCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) );
3445 }
3446
3447 return SCIP_OKAY;
3448 }
3449
3450 /** disables constraint's separation, enforcing, and propagation capabilities at the current node (and all subnodes);
3451 * if the method is called during problem modification or at the root node, the constraint is globally deleted from
3452 * the problem;
3453 * the constraint deletion is being remembered at the current node, s.t. after leaving the current subtree, the
3454 * constraint is automatically enabled again, and after reentering the current node's subtree, it is automatically
3455 * disabled again;
3456 * this may improve performance because redundant checks on this constraint are avoided, but it consumes memory;
3457 * alternatively, use SCIPdisableCons()
3458 *
3459 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3460 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3461 *
3462 * @pre this method can be called in one of the following stages of the SCIP solving process:
3463 * - \ref SCIP_STAGE_PROBLEM
3464 * - \ref SCIP_STAGE_INITPRESOLVE
3465 * - \ref SCIP_STAGE_PRESOLVING
3466 * - \ref SCIP_STAGE_EXITPRESOLVE
3467 * - \ref SCIP_STAGE_SOLVING
3468 *
3469 * @note SCIP stage does not get changed
3470 *
3471 */
3472 SCIP_RETCODE SCIPdelConsLocal(
3473 SCIP* scip, /**< SCIP data structure */
3474 SCIP_CONS* cons /**< constraint to locally delete */
3475 )
3476 {
3477 SCIP_NODE* node;
3478
3479 assert(cons != NULL);
3480
3481 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelConsLocal", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3482
3483 switch( scip->set->stage )
3484 {
3485 case SCIP_STAGE_PROBLEM:
3486 assert(cons->addconssetchg == NULL);
3487 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->reopt) );
3488 return SCIP_OKAY;
3489
3490 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction
3491 * might be wrong
3492 */
3493 case SCIP_STAGE_INITPRESOLVE:
3494 case SCIP_STAGE_EXITPRESOLVE:
3495 assert(SCIPconsIsAdded(cons));
3496 /*lint -fallthrough*/
3497
3498 case SCIP_STAGE_PRESOLVING:
3499 case SCIP_STAGE_SOLVING:
3500 node = SCIPtreeGetCurrentNode(scip->tree);
3501
3502 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) )
3503 {
3504 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) );
3505 }
3506 else
3507 {
3508 SCIP_CALL( SCIPnodeDelCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) );
3509 }
3510 return SCIP_OKAY;
3511
3512 default:
3513 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3514 return SCIP_INVALIDCALL;
3515 } /*lint !e788*/
3516 }
3517
3518 /** gets estimate of best primal solution w.r.t. original problem contained in current subtree
3519 *
3520 * @return estimate of best primal solution w.r.t. original problem contained in current subtree
3521 *
3522 * @pre this method can be called in one of the following stages of the SCIP solving process:
3523 * - \ref SCIP_STAGE_SOLVING
3524 */
3525 SCIP_Real SCIPgetLocalOrigEstimate(
3526 SCIP* scip /**< SCIP data structure */
3527 )
3528 {
3529 SCIP_NODE* node;
3530
3531 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalOrigEstimate", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3532
3533 node = SCIPtreeGetCurrentNode(scip->tree);
3534 return node != NULL ? SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetEstimate(node)) : SCIP_INVALID;
3535 }
3536
3537 /** gets estimate of best primal solution w.r.t. transformed problem contained in current subtree
3538 *
3539 * @return estimate of best primal solution w.r.t. transformed problem contained in current subtree
3540 *
3541 * @pre this method can be called in one of the following stages of the SCIP solving process:
3542 * - \ref SCIP_STAGE_SOLVING
3543 */
3544 SCIP_Real SCIPgetLocalTransEstimate(
3545 SCIP* scip /**< SCIP data structure */
3546 )
3547 {
3548 SCIP_NODE* node;
3549
3550 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalTransEstimate", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3551
3552 node = SCIPtreeGetCurrentNode(scip->tree);
3553
3554 return node != NULL ? SCIPnodeGetEstimate(node) : SCIP_INVALID;
3555 }
3556
3557 /** gets dual bound of current node
3558 *
3559 * @return dual bound of current node
3560 *
3561 * @pre this method can be called in one of the following stages of the SCIP solving process:
3562 * - \ref SCIP_STAGE_SOLVING
3563 */
3564 SCIP_Real SCIPgetLocalDualbound(
3565 SCIP* scip /**< SCIP data structure */
3566 )
3567 {
3568 SCIP_NODE* node;
3569
3570 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3571
3572 node = SCIPtreeGetCurrentNode(scip->tree);
3573 return node != NULL ? SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetLowerbound(node)) : SCIP_INVALID;
3574 }
3575
3576 /** gets lower bound of current node in transformed problem
3577 *
3578 * @return lower bound of current node in transformed problem
3579 *
3580 * @pre this method can be called in one of the following stages of the SCIP solving process:
3581 * - \ref SCIP_STAGE_SOLVING
3582 */
3583 SCIP_Real SCIPgetLocalLowerbound(
3584 SCIP* scip /**< SCIP data structure */
3585 )
3586 {
3587 SCIP_NODE* node;
3588
3589 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3590
3591 node = SCIPtreeGetCurrentNode(scip->tree);
3592
3593 return node != NULL ? SCIPnodeGetLowerbound(node) : SCIP_INVALID;
3594 }
3595
3596 /** gets dual bound of given node
3597 *
3598 * @return dual bound of a given node
3599 *
3600 * @pre this method can be called in one of the following stages of the SCIP solving process:
3601 * - \ref SCIP_STAGE_SOLVING
3602 */
3603 SCIP_Real SCIPgetNodeDualbound(
3604 SCIP* scip, /**< SCIP data structure */
3605 SCIP_NODE* node /**< node to get dual bound for */
3606 )
3607 {
3608 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNodeDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3609
3610 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetLowerbound(node));
3611 }
3612
3613 /** gets lower bound of given node in transformed problem
3614 *
3615 * @return lower bound of given node in transformed problem
3616 *
3617 * @pre this method can be called in one of the following stages of the SCIP solving process:
3618 * - \ref SCIP_STAGE_SOLVING
3619 */
3620 SCIP_Real SCIPgetNodeLowerbound(
3621 SCIP* scip, /**< SCIP data structure */
3622 SCIP_NODE* node /**< node to get dual bound for */
3623 )
3624 {
3625 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNodeLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3626
3627 return SCIPnodeGetLowerbound(node);
3628 }
3629
3630 /** if given value is tighter (larger for minimization, smaller for maximization) than the current node's dual bound (in
3631 * original problem space), sets the current node's dual bound to the new value
3632 *
3633 * @note the given new bound has to be a dual bound, i.e., it has to be valid for the original problem.
3634 *
3635 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3636 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3637 *
3638 * @pre this method can be called in one of the following stages of the SCIP solving process:
3639 * - \ref SCIP_STAGE_PROBLEM
3640 * - \ref SCIP_STAGE_PRESOLVING
3641 * - \ref SCIP_STAGE_PRESOLVED
3642 * - \ref SCIP_STAGE_SOLVING
3643 */
3644 SCIP_RETCODE SCIPupdateLocalDualbound(
3645 SCIP* scip, /**< SCIP data structure */
3646 SCIP_Real newbound /**< new dual bound for the node (if it's tighter than the old one) */
3647 )
3648 {
3649 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateLocalDualbound", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3650
3651 switch( scip->set->stage )
3652 {
3653 case SCIP_STAGE_PROBLEM:
3654 /* since no root node, for which we could update the dual bound, has been create yet, update the dual bound stored in
3655 * the problem data
3656 */
3657 SCIPprobUpdateDualbound(scip->origprob, newbound);
3658 break;
3659
3660 case SCIP_STAGE_PRESOLVING:
3661 case SCIP_STAGE_PRESOLVED:
3662 /* since no root node, for which we could update the dual bound, has been create yet, update the dual bound stored in
3663 * the problem data
3664 */
3665 SCIPprobUpdateDualbound(scip->transprob, SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, newbound));
3666 break;
3667
3668 case SCIP_STAGE_SOLVING:
3669 SCIP_CALL( SCIPupdateNodeLowerbound(scip, SCIPtreeGetCurrentNode(scip->tree), SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, newbound)) );
3670 break;
3671
3672 default:
3673 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3674 SCIPABORT();
3675 return SCIP_INVALIDCALL; /*lint !e527*/
3676 } /*lint !e788*/
3677
3678 return SCIP_OKAY;
3679 }
3680
3681 /** if given value is larger than the current node's lower bound (in transformed problem), sets the current node's
3682 * lower bound to the new value
3683 *
3684 * @note the given new bound has to be a lower bound, i.e., it has to be valid for the transformed problem.
3685 *
3686 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3687 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3688 *
3689 * @pre this method can be called in one of the following stages of the SCIP solving process:
3690 * - \ref SCIP_STAGE_PRESOLVING
3691 * - \ref SCIP_STAGE_PRESOLVED
3692 * - \ref SCIP_STAGE_SOLVING
3693 */
3694 SCIP_RETCODE SCIPupdateLocalLowerbound(
3695 SCIP* scip, /**< SCIP data structure */
3696 SCIP_Real newbound /**< new lower bound for the node (if it's larger than the old one) */
3697 )
3698 {
3699 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateLocalLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3700
3701 switch( scip->set->stage )
3702 {
3703 case SCIP_STAGE_PRESOLVING:
3704 case SCIP_STAGE_PRESOLVED:
3705 /* since no root node, for which we could update the lower bound, has been created yet, update the dual bound stored
3706 * in the problem data
3707 */
3708 SCIPprobUpdateDualbound(scip->transprob, SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, newbound));
3709 break;
3710
3711 case SCIP_STAGE_SOLVING:
3712 SCIP_CALL( SCIPupdateNodeLowerbound(scip, SCIPtreeGetCurrentNode(scip->tree), newbound) );
3713 break;
3714
3715 default:
3716 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3717 SCIPABORT();
3718 return SCIP_INVALIDCALL; /*lint !e527*/
3719 } /*lint !e788*/
3720
3721 return SCIP_OKAY;
3722 }
3723
3724 /** if given value is tighter (larger for minimization, smaller for maximization) than the node's dual bound,
3725 * sets the node's dual bound to the new value
3726 *
3727 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3728 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3729 *
3730 * @pre this method can be called in one of the following stages of the SCIP solving process:
3731 * - \ref SCIP_STAGE_SOLVING
3732 */
3733 SCIP_RETCODE SCIPupdateNodeDualbound(
3734 SCIP* scip, /**< SCIP data structure */
3735 SCIP_NODE* node, /**< node to update dual bound for */
3736 SCIP_Real newbound /**< new dual bound for the node (if it's tighter than the old one) */
3737 )
3738 {
3739 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateNodeDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3740
3741 SCIP_CALL( SCIPupdateNodeLowerbound(scip, node, SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, newbound)) );
3742
3743 return SCIP_OKAY;
3744 }
3745
3746 /** if given value is larger than the node's lower bound (in transformed problem), sets the node's lower bound
3747 * to the new value
3748 *
3749 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3750 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3751 *
3752 * @pre this method can be called in one of the following stages of the SCIP solving process:
3753 * - \ref SCIP_STAGE_SOLVING
3754 */
3755 SCIP_RETCODE SCIPupdateNodeLowerbound(
3756 SCIP* scip, /**< SCIP data structure */
3757 SCIP_NODE* node, /**< node to update lower bound for */
3758 SCIP_Real newbound /**< new lower bound for the node (if it's larger than the old one) */
3759 )
3760 {
3761 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateNodeLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3762
3763 SCIPnodeUpdateLowerbound(node, scip->stat, scip->set, scip->tree, scip->transprob, scip->origprob, newbound);
3764
3765 /* if lowerbound exceeds the cutoffbound the node will be marked to be cutoff
3766 *
3767 * If the node is an inner node (,not a child node,) we need to cutoff the node manually if we exceed the
3768 * cutoffbound. This is only relevant if a user updates the lower bound; in the main solving process of SCIP the
3769 * lowerbound is only changed before branching and the given node is always a child node. Therefore, we only check
3770 * for a cutoff here in the user function instead of in SCIPnodeUpdateLowerbound().
3771 */
3772 if( SCIPisGE(scip, newbound, scip->primal->cutoffbound) )
3773 {
3774 SCIP_CALL( SCIPnodeCutoff(node, scip->set, scip->stat, scip->tree, scip->transprob, scip->origprob, scip->reopt,
3775 scip->lp, scip->mem->probmem) );
3776 }
3777
3778 return SCIP_OKAY;
3779 }
3780
3781 /** change the node selection priority of the given child
3782 *
3783 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3784 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3785 *
3786 * @pre this method can be called in one of the following stages of the SCIP solving process:
3787 * - \ref SCIP_STAGE_SOLVING
3788 */
3789 SCIP_RETCODE SCIPchgChildPrio(
3790 SCIP* scip, /**< SCIP data structure */
3791 SCIP_NODE* child, /**< child to update the node selection priority */
3792 SCIP_Real priority /**< node selection priority value */
3793 )
3794 {
3795 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgChildPrio", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3796
3797 if( SCIPnodeGetType(child) != SCIP_NODETYPE_CHILD )
3798 return SCIP_INVALIDDATA;
3799
3800 SCIPchildChgNodeselPrio(scip->tree, child, priority);
3801
3802 return SCIP_OKAY;
3803 }
3804