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