1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2021 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /**@file scip_sol.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for solutions
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 <string.h>
37 #if defined(_WIN32) || defined(_WIN64)
38 #else
39 #include <strings.h> /*lint --e{766}*/
40 #endif
41
42 #include "blockmemshell/memory.h"
43 #include "nlpi/type_nlpi.h"
44 #include "scip/cons.h"
45 #include "scip/cons_linear.h"
46 #include "scip/debug.h"
47 #include "scip/lp.h"
48 #include "scip/nlp.h"
49 #include "scip/primal.h"
50 #include "scip/prob.h"
51 #include "scip/pub_cons.h"
52 #include "scip/pub_fileio.h"
53 #include "scip/pub_message.h"
54 #include "scip/pub_misc.h"
55 #include "scip/pub_sol.h"
56 #include "scip/pub_var.h"
57 #include "scip/relax.h"
58 #include "scip/scip_cons.h"
59 #include "scip/scip_copy.h"
60 #include "scip/scip_general.h"
61 #include "scip/scip_mem.h"
62 #include "scip/scip_message.h"
63 #include "scip/scip_nlp.h"
64 #include "scip/scip_numerics.h"
65 #include "scip/scip_param.h"
66 #include "scip/scip_prob.h"
67 #include "scip/scip_sol.h"
68 #include "scip/scip_solve.h"
69 #include "scip/scip_solvingstats.h"
70 #include "scip/scip_var.h"
71 #include "scip/set.h"
72 #include "scip/sol.h"
73 #include "scip/struct_lp.h"
74 #include "scip/struct_mem.h"
75 #include "scip/struct_primal.h"
76 #include "scip/struct_prob.h"
77 #include "scip/struct_scip.h"
78 #include "scip/struct_set.h"
79 #include "scip/struct_stat.h"
80 #include "scip/struct_var.h"
81 #include "scip/tree.h"
82 #include "xml/xml.h"
83
84 /** checks solution for feasibility in original problem without adding it to the solution store; to improve the
85 * performance we use the following order when checking for violations:
86 *
87 * 1. variable bounds
88 * 2. constraint handlers with positive or zero priority that don't need constraints (e.g. integral constraint handler)
89 * 3. original constraints
90 * 4. constraint handlers with negative priority that don't need constraints (e.g. Benders' decomposition constraint handler)
91 */
92 static
checkSolOrig(SCIP * scip,SCIP_SOL * sol,SCIP_Bool * feasible,SCIP_Bool printreason,SCIP_Bool completely,SCIP_Bool checkbounds,SCIP_Bool checkintegrality,SCIP_Bool checklprows,SCIP_Bool checkmodifiable)93 SCIP_RETCODE checkSolOrig(
94 SCIP* scip, /**< SCIP data structure */
95 SCIP_SOL* sol, /**< primal CIP solution */
96 SCIP_Bool* feasible, /**< stores whether given solution is feasible */
97 SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
98 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */
99 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
100 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
101 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
102 SCIP_Bool checkmodifiable /**< have modifiable constraint to be checked? */
103 )
104 {
105 SCIP_RESULT result;
106 int v;
107 int c;
108 int h;
109
110 assert(scip != NULL);
111 assert(sol != NULL);
112 assert(feasible != NULL);
113
114 SCIP_CALL( SCIPcheckStage(scip, "checkSolOrig", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
115
116 *feasible = TRUE;
117
118 SCIPsolResetViolations(sol);
119
120 if( !printreason )
121 completely = FALSE;
122
123 /* check bounds */
124 if( checkbounds )
125 {
126 for( v = 0; v < scip->origprob->nvars; ++v )
127 {
128 SCIP_VAR* var;
129 SCIP_Real solval;
130 SCIP_Real lb;
131 SCIP_Real ub;
132
133 var = scip->origprob->vars[v];
134 solval = SCIPsolGetVal(sol, scip->set, scip->stat, var);
135
136 lb = SCIPvarGetLbOriginal(var);
137 ub = SCIPvarGetUbOriginal(var);
138
139 SCIPupdateSolBoundViolation(scip, sol, lb - solval, SCIPrelDiff(lb, solval));
140 SCIPupdateSolBoundViolation(scip, sol, solval - ub, SCIPrelDiff(solval, ub));
141
142 if( SCIPsetIsFeasLT(scip->set, solval, lb) || SCIPsetIsFeasGT(scip->set, solval, ub) )
143 {
144 *feasible = FALSE;
145
146 if( printreason )
147 {
148 SCIPmessagePrintInfo(scip->messagehdlr, "solution violates original bounds of variable <%s> [%g,%g] solution value <%g>\n",
149 SCIPvarGetName(var), lb, ub, solval);
150 }
151
152 if( !completely )
153 return SCIP_OKAY;
154 }
155 }
156 }
157
158 /* call constraint handlers with positive or zero check priority that don't need constraints */
159 for( h = 0; h < scip->set->nconshdlrs; ++h )
160 {
161 if( SCIPconshdlrGetCheckPriority(scip->set->conshdlrs[h]) >= 0 )
162 {
163 if( !SCIPconshdlrNeedsCons(scip->set->conshdlrs[h]) )
164 {
165 SCIP_CALL( SCIPconshdlrCheck(scip->set->conshdlrs[h], scip->mem->probmem, scip->set, scip->stat, sol,
166 checkintegrality, checklprows, printreason, completely, &result) );
167
168 if( result != SCIP_FEASIBLE )
169 {
170 *feasible = FALSE;
171
172 if( !completely )
173 return SCIP_OKAY;
174 }
175 }
176 }
177 /* constraint handlers are sorted by priority, so we can break when reaching the first one with negative priority */
178 else
179 break;
180 }
181
182 /* check original constraints
183 *
184 * in general modifiable constraints can not be checked, because the variables to fulfill them might be missing in
185 * the original problem; however, if the solution comes from a heuristic during presolving modifiable constraints
186 * have to be checked;
187 */
188 for( c = 0; c < scip->origprob->nconss; ++c )
189 {
190 if( SCIPconsIsChecked(scip->origprob->conss[c]) && (checkmodifiable || !SCIPconsIsModifiable(scip->origprob->conss[c])) )
191 {
192 /* check solution */
193 SCIP_CALL( SCIPconsCheck(scip->origprob->conss[c], scip->set, sol,
194 checkintegrality, checklprows, printreason, &result) );
195
196 if( result != SCIP_FEASIBLE )
197 {
198 *feasible = FALSE;
199
200 if( !completely )
201 return SCIP_OKAY;
202 }
203 }
204 }
205
206 /* call constraint handlers with negative check priority that don't need constraints;
207 * continue with the first constraint handler with negative priority which caused us to break in the above loop */
208 for( ; h < scip->set->nconshdlrs; ++h )
209 {
210 assert(SCIPconshdlrGetCheckPriority(scip->set->conshdlrs[h]) < 0);
211 if( !SCIPconshdlrNeedsCons(scip->set->conshdlrs[h]) )
212 {
213 SCIP_CALL( SCIPconshdlrCheck(scip->set->conshdlrs[h], scip->mem->probmem, scip->set, scip->stat, sol,
214 checkintegrality, checklprows, printreason, completely, &result) );
215
216 if( result != SCIP_FEASIBLE )
217 {
218 *feasible = FALSE;
219
220 if( !completely )
221 return SCIP_OKAY;
222 }
223 }
224 }
225
226 return SCIP_OKAY;
227 }
228
229 /** update integrality violation of a solution */
SCIPupdateSolIntegralityViolation(SCIP * scip,SCIP_SOL * sol,SCIP_Real absviol)230 void SCIPupdateSolIntegralityViolation(
231 SCIP* scip, /**< SCIP data structure */
232 SCIP_SOL* sol, /**< primal CIP solution */
233 SCIP_Real absviol /**< absolute violation */
234 )
235 {
236 if( SCIPprimalUpdateViolations(scip->origprimal) )
237 SCIPsolUpdateIntegralityViolation(sol, absviol);
238 }
239
240 /** update bound violation of a solution */
SCIPupdateSolBoundViolation(SCIP * scip,SCIP_SOL * sol,SCIP_Real absviol,SCIP_Real relviol)241 void SCIPupdateSolBoundViolation(
242 SCIP* scip, /**< SCIP data structure */
243 SCIP_SOL* sol, /**< primal CIP solution */
244 SCIP_Real absviol, /**< absolute violation */
245 SCIP_Real relviol /**< relative violation */
246 )
247 {
248 if( SCIPprimalUpdateViolations(scip->origprimal) )
249 SCIPsolUpdateBoundViolation(sol, absviol, relviol);
250 }
251
252 /** update LP row violation of a solution */
SCIPupdateSolLPRowViolation(SCIP * scip,SCIP_SOL * sol,SCIP_Real absviol,SCIP_Real relviol)253 void SCIPupdateSolLPRowViolation(
254 SCIP* scip, /**< SCIP data structure */
255 SCIP_SOL* sol, /**< primal CIP solution */
256 SCIP_Real absviol, /**< absolute violation */
257 SCIP_Real relviol /**< relative violation */
258 )
259 {
260 if( SCIPprimalUpdateViolations(scip->origprimal) )
261 SCIPsolUpdateLPRowViolation(sol, absviol, relviol);
262 }
263
264 /** update constraint violation of a solution */
SCIPupdateSolConsViolation(SCIP * scip,SCIP_SOL * sol,SCIP_Real absviol,SCIP_Real relviol)265 void SCIPupdateSolConsViolation(
266 SCIP* scip, /**< SCIP data structure */
267 SCIP_SOL* sol, /**< primal CIP solution */
268 SCIP_Real absviol, /**< absolute violation */
269 SCIP_Real relviol /**< relative violation */
270 )
271 {
272 if( SCIPprimalUpdateViolations(scip->origprimal) )
273 SCIPsolUpdateConsViolation(sol, absviol, relviol);
274 }
275
276 /** update LP row and constraint violations of a solution */
SCIPupdateSolLPConsViolation(SCIP * scip,SCIP_SOL * sol,SCIP_Real absviol,SCIP_Real relviol)277 void SCIPupdateSolLPConsViolation(
278 SCIP* scip, /**< SCIP data structure */
279 SCIP_SOL* sol, /**< primal CIP solution */
280 SCIP_Real absviol, /**< absolute violation */
281 SCIP_Real relviol /**< relative violation */
282 )
283 {
284 if( SCIPprimalUpdateViolations(scip->origprimal) )
285 SCIPsolUpdateLPConsViolation(sol, absviol, relviol);
286 }
287
288 /** allow violation updates */
SCIPactivateSolViolationUpdates(SCIP * scip)289 void SCIPactivateSolViolationUpdates(
290 SCIP* scip /**< SCIP data structure */
291 )
292 {
293 SCIPprimalSetUpdateViolations(scip->origprimal, TRUE);
294 }
295
296 /** disallow violation updates */
SCIPdeactivateSolViolationUpdates(SCIP * scip)297 void SCIPdeactivateSolViolationUpdates(
298 SCIP* scip /**< SCIP data structure */
299 )
300 {
301 SCIPprimalSetUpdateViolations(scip->origprimal, FALSE);
302 }
303
304 /** creates a primal solution, initialized to zero
305 *
306 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
307 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
308 *
309 * @pre This method can be called if SCIP is in one of the following stages:
310 * - \ref SCIP_STAGE_PROBLEM
311 * - \ref SCIP_STAGE_TRANSFORMING
312 * - \ref SCIP_STAGE_TRANSFORMED
313 * - \ref SCIP_STAGE_INITPRESOLVE
314 * - \ref SCIP_STAGE_PRESOLVING
315 * - \ref SCIP_STAGE_EXITPRESOLVE
316 * - \ref SCIP_STAGE_PRESOLVED
317 * - \ref SCIP_STAGE_INITSOLVE
318 * - \ref SCIP_STAGE_SOLVING
319 */
SCIPcreateSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)320 SCIP_RETCODE SCIPcreateSol(
321 SCIP* scip, /**< SCIP data structure */
322 SCIP_SOL** sol, /**< pointer to store the solution */
323 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
324 )
325 {
326 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
327
328 switch( scip->set->stage )
329 {
330 case SCIP_STAGE_PROBLEM:
331 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->origprimal, NULL, heur) );
332 return SCIP_OKAY;
333
334 case SCIP_STAGE_TRANSFORMING:
335 case SCIP_STAGE_TRANSFORMED:
336 case SCIP_STAGE_INITPRESOLVE:
337 case SCIP_STAGE_PRESOLVING:
338 case SCIP_STAGE_EXITPRESOLVE:
339 case SCIP_STAGE_PRESOLVED:
340 case SCIP_STAGE_INITSOLVE:
341 case SCIP_STAGE_SOLVING:
342 SCIP_CALL( SCIPsolCreate(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, heur) );
343 return SCIP_OKAY;
344
345 case SCIP_STAGE_SOLVED:
346 case SCIP_STAGE_EXITSOLVE:
347 case SCIP_STAGE_FREETRANS:
348 default:
349 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
350 return SCIP_INVALIDDATA;
351 } /*lint !e788*/
352 }
353
354 /** creates a primal solution, initialized to the current LP solution
355 *
356 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
357 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
358 *
359 * @pre This method can be called if SCIP is in one of the following stages:
360 * - \ref SCIP_STAGE_SOLVING
361 */
SCIPcreateLPSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)362 SCIP_RETCODE SCIPcreateLPSol(
363 SCIP* scip, /**< SCIP data structure */
364 SCIP_SOL** sol, /**< pointer to store the solution */
365 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
366 )
367 {
368 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
369
370 if( !SCIPtreeHasCurrentNodeLP(scip->tree) )
371 {
372 SCIPerrorMessage("LP solution does not exist\n");
373 return SCIP_INVALIDCALL;
374 }
375
376 SCIP_CALL( SCIPsolCreateLPSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal,
377 scip->tree, scip->lp, heur) );
378
379 return SCIP_OKAY;
380 }
381
382 /** creates a primal solution, initialized to the current NLP solution
383 *
384 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
385 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
386 *
387 * @pre This method can be called if SCIP is in one of the following stages:
388 * - \ref SCIP_STAGE_SOLVING
389 */
SCIPcreateNLPSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)390 SCIP_RETCODE SCIPcreateNLPSol(
391 SCIP* scip, /**< SCIP data structure */
392 SCIP_SOL** sol, /**< pointer to store the solution */
393 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
394 )
395 {
396 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
397
398 if( !SCIPisNLPConstructed(scip) )
399 {
400 SCIPerrorMessage("NLP does not exist\n");
401 return SCIP_INVALIDCALL;
402 }
403 assert(scip->nlp != NULL);
404
405 if( !SCIPnlpHasSolution(scip->nlp) )
406 {
407 SCIPerrorMessage("NLP solution does not exist\n");
408 return SCIP_INVALIDCALL;
409 }
410
411 SCIP_CALL( SCIPsolCreateNLPSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp,
412 heur) );
413
414 return SCIP_OKAY;
415 }
416
417 /** creates a primal solution, initialized to the current relaxation solution
418 *
419 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
420 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
421 *
422 * @pre This method can be called if SCIP is in one of the following stages:
423 * - \ref SCIP_STAGE_SOLVING
424 */
SCIPcreateRelaxSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)425 SCIP_RETCODE SCIPcreateRelaxSol(
426 SCIP* scip, /**< SCIP data structure */
427 SCIP_SOL** sol, /**< pointer to store the solution */
428 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
429 )
430 {
431 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateRelaxSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
432
433 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
434 {
435 SCIPerrorMessage("relaxation solution is not valid\n");
436 return SCIP_INVALIDCALL;
437 }
438
439 SCIP_CALL( SCIPsolCreateRelaxSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->relaxation, heur) );
440
441 return SCIP_OKAY;
442 }
443
444 /** creates a primal solution, initialized to the current pseudo solution
445 *
446 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
447 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
448 *
449 * @pre This method can be called if SCIP is in one of the following stages:
450 * - \ref SCIP_STAGE_SOLVING
451 */
SCIPcreatePseudoSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)452 SCIP_RETCODE SCIPcreatePseudoSol(
453 SCIP* scip, /**< SCIP data structure */
454 SCIP_SOL** sol, /**< pointer to store the solution */
455 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
456 )
457 {
458 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreatePseudoSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
459
460 SCIP_CALL( SCIPsolCreatePseudoSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal,
461 scip->tree, scip->lp, heur) );
462
463 return SCIP_OKAY;
464 }
465
466 /** creates a primal solution, initialized to the current LP or pseudo solution, depending on whether the LP was solved
467 * at the current node
468 *
469 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
470 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
471 *
472 * @pre This method can be called if SCIP is in one of the following stages:
473 * - \ref SCIP_STAGE_SOLVING
474 */
SCIPcreateCurrentSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)475 SCIP_RETCODE SCIPcreateCurrentSol(
476 SCIP* scip, /**< SCIP data structure */
477 SCIP_SOL** sol, /**< pointer to store the solution */
478 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
479 )
480 {
481 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
482
483 SCIP_CALL( SCIPsolCreateCurrentSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal,
484 scip->tree, scip->lp, heur) );
485
486 return SCIP_OKAY;
487 }
488
489 /** creates a partial primal solution, initialized to unknown values
490 *
491 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
492 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
493 *
494 * @pre This method can be called if SCIP is in one of the following stages:
495 * - \ref SCIP_STAGE_PROBLEM
496 */
SCIPcreatePartialSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)497 SCIP_RETCODE SCIPcreatePartialSol(
498 SCIP* scip, /**< SCIP data structure */
499 SCIP_SOL** sol, /**< pointer to store the solution */
500 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
501 )
502 {
503 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreatePartialSol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
504
505 SCIP_CALL( SCIPsolCreatePartial(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal, heur) );
506
507 return SCIP_OKAY;
508 }
509
510 /** creates a primal solution, initialized to unknown values
511 *
512 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
513 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
514 *
515 * @pre This method can be called if SCIP is in one of the following stages:
516 * - \ref SCIP_STAGE_TRANSFORMING
517 * - \ref SCIP_STAGE_TRANSFORMED
518 * - \ref SCIP_STAGE_INITPRESOLVE
519 * - \ref SCIP_STAGE_PRESOLVING
520 * - \ref SCIP_STAGE_EXITPRESOLVE
521 * - \ref SCIP_STAGE_PRESOLVED
522 * - \ref SCIP_STAGE_INITSOLVE
523 * - \ref SCIP_STAGE_SOLVING
524 */
SCIPcreateUnknownSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)525 SCIP_RETCODE SCIPcreateUnknownSol(
526 SCIP* scip, /**< SCIP data structure */
527 SCIP_SOL** sol, /**< pointer to store the solution */
528 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
529 )
530 {
531 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateUnknownSol", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
532
533 SCIP_CALL( SCIPsolCreateUnknown(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, heur) );
534
535 return SCIP_OKAY;
536 }
537
538 /** creates a primal solution living in the original problem space, initialized to zero;
539 * a solution in original space allows to set original variables to values that would be invalid in the
540 * transformed problem due to preprocessing fixings or aggregations
541 *
542 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
543 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
544 *
545 * @pre This method can be called if SCIP is in one of the following stages:
546 * - \ref SCIP_STAGE_PROBLEM
547 * - \ref SCIP_STAGE_TRANSFORMING
548 * - \ref SCIP_STAGE_TRANSFORMED
549 * - \ref SCIP_STAGE_INITPRESOLVE
550 * - \ref SCIP_STAGE_PRESOLVING
551 * - \ref SCIP_STAGE_EXITPRESOLVE
552 * - \ref SCIP_STAGE_PRESOLVED
553 * - \ref SCIP_STAGE_INITSOLVE
554 * - \ref SCIP_STAGE_SOLVING
555 * - \ref SCIP_STAGE_SOLVED
556 */
SCIPcreateOrigSol(SCIP * scip,SCIP_SOL ** sol,SCIP_HEUR * heur)557 SCIP_RETCODE SCIPcreateOrigSol(
558 SCIP* scip, /**< SCIP data structure */
559 SCIP_SOL** sol, /**< pointer to store the solution */
560 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
561 )
562 {
563 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateOrigSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
564
565 switch( scip->set->stage )
566 {
567 case SCIP_STAGE_PROBLEM:
568 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->origprimal, NULL, heur) );
569 return SCIP_OKAY;
570
571 case SCIP_STAGE_TRANSFORMING:
572 case SCIP_STAGE_TRANSFORMED:
573 case SCIP_STAGE_INITPRESOLVE:
574 case SCIP_STAGE_PRESOLVING:
575 case SCIP_STAGE_EXITPRESOLVE:
576 case SCIP_STAGE_PRESOLVED:
577 case SCIP_STAGE_INITSOLVE:
578 case SCIP_STAGE_SOLVING:
579 case SCIP_STAGE_SOLVED:
580 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->primal, scip->tree, heur) );
581 return SCIP_OKAY;
582
583 case SCIP_STAGE_EXITSOLVE:
584 case SCIP_STAGE_FREETRANS:
585 default:
586 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
587 return SCIP_INVALIDCALL;
588 } /*lint !e788*/
589 }
590
591 /** creates a copy of a primal solution; note that a copy of a linked solution is also linked and needs to be unlinked
592 * if it should stay unaffected from changes in the LP or pseudo solution
593 *
594 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
595 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
596 *
597 * @pre This method can be called if SCIP is in one of the following stages:
598 * - \ref SCIP_STAGE_PROBLEM
599 * - \ref SCIP_STAGE_FREETRANS
600 * - \ref SCIP_STAGE_TRANSFORMING
601 * - \ref SCIP_STAGE_TRANSFORMED
602 * - \ref SCIP_STAGE_INITPRESOLVE
603 * - \ref SCIP_STAGE_PRESOLVING
604 * - \ref SCIP_STAGE_EXITPRESOLVE
605 * - \ref SCIP_STAGE_PRESOLVED
606 * - \ref SCIP_STAGE_INITSOLVE
607 * - \ref SCIP_STAGE_SOLVING
608 * - \ref SCIP_STAGE_SOLVED
609 */
SCIPcreateSolCopy(SCIP * scip,SCIP_SOL ** sol,SCIP_SOL * sourcesol)610 SCIP_RETCODE SCIPcreateSolCopy(
611 SCIP* scip, /**< SCIP data structure */
612 SCIP_SOL** sol, /**< pointer to store the solution */
613 SCIP_SOL* sourcesol /**< primal CIP solution to copy */
614 )
615 {
616 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSolCopy", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
617
618 /* check if we want to copy the current solution, which is the same as creating a current solution */
619 if( sourcesol == NULL )
620 {
621 SCIP_CALL( SCIPcreateCurrentSol(scip, sol, NULL) );
622 }
623 else
624 {
625 SCIP_CALL( SCIPsolCopy(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, sourcesol) );
626 }
627
628 return SCIP_OKAY;
629 }
630
631 /** creates a copy of a solution in the original primal solution space
632 *
633 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
634 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
635 *
636 * @pre This method can be called if SCIP is in one of the following stages:
637 * - \ref SCIP_STAGE_PROBLEM
638 * - \ref SCIP_STAGE_TRANSFORMING
639 * - \ref SCIP_STAGE_TRANSFORMED
640 * - \ref SCIP_STAGE_INITPRESOLVE
641 * - \ref SCIP_STAGE_PRESOLVING
642 * - \ref SCIP_STAGE_EXITPRESOLVE
643 * - \ref SCIP_STAGE_PRESOLVED
644 * - \ref SCIP_STAGE_INITSOLVE
645 * - \ref SCIP_STAGE_SOLVING
646 * - \ref SCIP_STAGE_SOLVED
647 * - \ref SCIP_STAGE_EXITSOLVE
648 * - \ref SCIP_STAGE_FREETRANS
649 */
SCIPcreateSolCopyOrig(SCIP * scip,SCIP_SOL ** sol,SCIP_SOL * sourcesol)650 SCIP_RETCODE SCIPcreateSolCopyOrig(
651 SCIP* scip, /**< SCIP data structure */
652 SCIP_SOL** sol, /**< pointer to store the solution */
653 SCIP_SOL* sourcesol /**< primal CIP solution to copy */
654 )
655 {
656 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSolCopyOrig", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
657
658 /* check if we want to copy the current solution, which is the same as creating a current solution */
659 if( sourcesol == NULL )
660 {
661 SCIP_CALL( SCIPcreateCurrentSol(scip, sol, NULL) );
662 }
663 else
664 {
665 switch( scip->set->stage )
666 {
667 case SCIP_STAGE_PROBLEM:
668 case SCIP_STAGE_FREETRANS:
669 case SCIP_STAGE_SOLVED:
670 case SCIP_STAGE_TRANSFORMING:
671 case SCIP_STAGE_TRANSFORMED:
672 case SCIP_STAGE_INITPRESOLVE:
673 case SCIP_STAGE_PRESOLVING:
674 case SCIP_STAGE_EXITPRESOLVE:
675 case SCIP_STAGE_PRESOLVED:
676 case SCIP_STAGE_INITSOLVE:
677 case SCIP_STAGE_SOLVING:
678 SCIP_CALL( SCIPsolCopy(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal, sourcesol) );
679 break;
680 default:
681 assert(FALSE); /*lint !e506*/
682 } /*lint !e788*/
683 }
684
685 return SCIP_OKAY;
686 }
687
688 /** helper method that sets up and solves the sub-SCIP for removing infinite values from solutions */
689 static
setupAndSolveFiniteSolSubscip(SCIP * scip,SCIP * subscip,SCIP_VAR ** origvars,int norigvars,SCIP_Real * solvals,SCIP_Bool * success)690 SCIP_RETCODE setupAndSolveFiniteSolSubscip(
691 SCIP* scip, /**< SCIP data structure */
692 SCIP* subscip, /**< SCIP data structure of sub-SCIP*/
693 SCIP_VAR** origvars, /**< original problem variables of main SCIP */
694 int norigvars, /**< number of original problem variables of main SCIP */
695 SCIP_Real* solvals, /**< array with solution values of variables; infinite ones are replaced */
696 SCIP_Bool* success /**< pointer to store if removing infinite values was successful */
697 )
698 {
699 SCIP_HASHMAP* varmap;
700 SCIP_VAR* varcopy;
701 SCIP_Real fixval;
702 SCIP_Bool valid;
703 SCIP_SOL* bestsol;
704 int v;
705
706 assert(scip != NULL);
707 assert(subscip != NULL);
708 assert(origvars != NULL);
709 assert(solvals != NULL);
710 assert(success != NULL);
711
712 /* copy the original problem to the sub-SCIP */
713 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(scip), norigvars) );
714 SCIP_CALL( SCIPcopyOrig(scip, subscip, varmap, NULL, "removeinffixings", TRUE, FALSE, TRUE, &valid) );
715
716 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", (int)SCIP_VERBLEVEL_NONE) );
717
718 /* in the sub-SCIP, we try to minimize the absolute values of all variables with infinite values in the solution
719 * and fix all other variables to the value they have in the solution
720 */
721 for( v = 0; v < norigvars; ++v )
722 {
723 varcopy = (SCIP_VAR*) SCIPhashmapGetImage(varmap, (void*)origvars[v]);
724 assert(varcopy != NULL);
725
726 fixval = solvals[v];
727
728 if( SCIPisInfinity(scip, fixval) || SCIPisInfinity(scip, -fixval) )
729 {
730 /* If a variable with a finite finite lower bound was set to +infinity, we just change its objective to 1.0
731 * to minimize its value; if a variable with a finite finite upper bound was set to -infinity, we just
732 * change its objective to -1.0 to maximize its value; if a variable is free, we split the variable into
733 * positive and negative part by creating two new non-negative variables and one constraint linking those
734 * variables.
735 */
736 if( SCIPisInfinity(scip, fixval) && !SCIPisInfinity(scip, -SCIPvarGetLbLocal(varcopy)) )
737 {
738 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, 1.0) );
739 }
740 else if( SCIPisInfinity(scip, -fixval) && !SCIPisInfinity(scip, SCIPvarGetUbLocal(varcopy)) )
741 {
742 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, -1.0) );
743 }
744 else
745 {
746 char name[SCIP_MAXSTRLEN];
747 SCIP_VAR* posvar;
748 SCIP_VAR* negvar;
749 SCIP_CONS* linkcons;
750
751 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "run");
752 SCIP_CALL( SCIPcreateVar(subscip, &posvar, name, 0.0, SCIPinfinity(scip), 1.0,
753 SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
754 SCIP_CALL( SCIPaddVar(subscip, posvar) );
755
756 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "neg");
757 SCIP_CALL( SCIPcreateVar(subscip, &negvar, name, 0.0, SCIPinfinity(scip), 1.0,
758 SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
759 SCIP_CALL( SCIPaddVar(subscip, negvar) );
760
761 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "linkcons");
762 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &linkcons, name, 0, NULL, NULL, 0.0, 0.0 ) );
763 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, varcopy, 1.0) );
764 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, posvar, -1.0) );
765 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, negvar, 1.0) );
766 SCIP_CALL( SCIPaddCons(subscip, linkcons) );
767
768 SCIP_CALL( SCIPreleaseCons(subscip, &linkcons) );
769 SCIP_CALL( SCIPreleaseVar(subscip, &posvar) );
770 SCIP_CALL( SCIPreleaseVar(subscip, &negvar) );
771
772 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, 0.0) );
773 }
774 }
775 else
776 {
777 SCIP_Bool infeasible;
778 SCIP_Bool fixed;
779
780 if( SCIPisFeasLT(scip, solvals[v], SCIPvarGetLbLocal(varcopy)) || SCIPisFeasGT(scip, solvals[v], SCIPvarGetUbLocal(varcopy)) )
781 {
782 SCIP_CALL( SCIPchgVarType(subscip, varcopy, SCIP_VARTYPE_CONTINUOUS, &infeasible) );
783 assert(!infeasible);
784 }
785
786 /* fix variable to its value in the solution */
787 SCIP_CALL( SCIPfixVar(subscip, varcopy, fixval, &infeasible, &fixed) );
788 assert(!infeasible);
789 }
790 }
791
792 SCIP_CALL( SCIPsolve(subscip) );
793
794 bestsol = SCIPgetBestSol(subscip);
795
796 if( bestsol != NULL )
797 {
798 /* change the stored solution values for variables fixed to infinite values */
799 for( v = 0; v < norigvars; ++v )
800 {
801 varcopy = (SCIP_VAR*) SCIPhashmapGetImage(varmap, (void*)origvars[v]);
802 assert(varcopy != NULL);
803
804 if( (SCIPisInfinity(scip, solvals[v]) || SCIPisInfinity(scip, -solvals[v])) )
805 {
806 solvals[v] = SCIPgetSolVal(subscip, bestsol, varcopy);
807 }
808 }
809 }
810 else
811 {
812 *success = FALSE;
813 }
814
815 SCIPhashmapFree(&varmap);
816
817 return SCIP_OKAY;
818 }
819
820
821 /** creates a copy of a primal solution, thereby replacing infinite fixings of variables by finite values;
822 * the copy is always defined in the original variable space;
823 * success indicates whether the objective value of the solution was changed by removing infinite values
824 *
825 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
826 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
827 *
828 * @pre This method can be called if SCIP is in one of the following stages:
829 * - \ref SCIP_STAGE_PROBLEM
830 * - \ref SCIP_STAGE_TRANSFORMING
831 * - \ref SCIP_STAGE_TRANSFORMED
832 * - \ref SCIP_STAGE_INITPRESOLVE
833 * - \ref SCIP_STAGE_PRESOLVING
834 * - \ref SCIP_STAGE_EXITPRESOLVE
835 * - \ref SCIP_STAGE_PRESOLVED
836 * - \ref SCIP_STAGE_INITSOLVE
837 * - \ref SCIP_STAGE_SOLVING
838 * - \ref SCIP_STAGE_SOLVED
839 * - \ref SCIP_STAGE_EXITSOLVE
840 */
SCIPcreateFiniteSolCopy(SCIP * scip,SCIP_SOL ** sol,SCIP_SOL * sourcesol,SCIP_Bool * success)841 SCIP_RETCODE SCIPcreateFiniteSolCopy(
842 SCIP* scip, /**< SCIP data structure */
843 SCIP_SOL** sol, /**< pointer to store the solution */
844 SCIP_SOL* sourcesol, /**< primal CIP solution to copy */
845 SCIP_Bool* success /**< does the finite solution have the same objective value? */
846 )
847 {
848 SCIP_VAR** fixedvars;
849 SCIP_VAR** origvars;
850 SCIP_Real* solvals;
851 SCIP_VAR* var;
852 int nfixedvars;
853 int norigvars;
854 int v;
855
856 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateFiniteSolCopy", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
857
858 assert(scip != NULL);
859 assert(sol != NULL);
860 assert(sourcesol != NULL);
861 assert(success != NULL);
862
863 *success = TRUE;
864 *sol = NULL;
865
866 fixedvars = SCIPgetFixedVars(scip);
867 nfixedvars = SCIPgetNFixedVars(scip);
868 assert(fixedvars != NULL || nfixedvars == 0);
869
870 /* get original variables and their values in the optimal solution */
871 SCIP_CALL( SCIPgetOrigVarsData(scip, &origvars, &norigvars, NULL, NULL, NULL, NULL) );
872 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, norigvars) );
873 SCIP_CALL( SCIPgetSolVals(scip, sourcesol, norigvars, origvars, solvals) );
874
875 /* check whether there are variables fixed to an infinite value */
876 for( v = 0; v < nfixedvars; ++v )
877 {
878 var = fixedvars[v]; /*lint !e613*/
879
880 /* skip (multi-)aggregated variables */
881 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_FIXED )
882 continue;
883
884 assert(SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
885
886 if( (SCIPisInfinity(scip, SCIPvarGetLbGlobal(var)) || SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var))) )
887 {
888 SCIPdebugMsg(scip, "var <%s> is fixed to infinite value %g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var));
889 break;
890 }
891 }
892
893 /* there were variables fixed to infinite values */
894 if( v < nfixedvars )
895 {
896 SCIP* subscip;
897 SCIP_RETCODE retcode;
898
899 /* if one of the variables was fixed to infinity in the original problem, we stop here */
900 for( v = 0; v < norigvars; ++v )
901 {
902 var = origvars[v];
903
904 if( SCIPisInfinity(scip, SCIPvarGetLbOriginal(var)) || SCIPisInfinity(scip, -SCIPvarGetUbOriginal(var)) )
905 {
906 assert(SCIPisEQ(scip, SCIPvarGetLbOriginal(var), SCIPvarGetUbOriginal(var)));
907
908 SCIPdebugMsg(scip, "--> var <%s> is fixed to infinite value %g in the original problem, stop making solution finite\n",
909 SCIPvarGetName(var), SCIPvarGetLbOriginal(var));
910
911 *success = FALSE;
912
913 goto TERMINATE;
914 }
915 }
916
917 /* create sub-SCIP */
918 SCIP_CALL( SCIPcreate(&subscip) );
919
920 retcode = setupAndSolveFiniteSolSubscip(scip, subscip, origvars, norigvars, solvals, success);
921
922 /* free sub-SCIP */
923 SCIP_CALL( SCIPfree(&subscip) );
924
925 SCIP_CALL( retcode );
926 }
927
928 /* create original solution and set the solution values */
929 if( *success )
930 {
931 SCIP_CALL( SCIPcreateOrigSol(scip, sol, NULL) );
932 for( v = 0; v < norigvars; ++v )
933 {
934 SCIP_CALL( SCIPsetSolVal(scip, *sol, origvars[v], solvals[v]) );
935 }
936 }
937
938 #ifdef SCIP_DEBUG
939 SCIPdebugMsg(scip, "created finites solution copy:\n");
940 SCIP_CALL( SCIPprintSol(scip, *sol, NULL, FALSE) );
941 #endif
942
943 /* the solution of the sub-SCIP should have the same objective value */
944 if( *success && !SCIPisEQ(scip, SCIPgetSolOrigObj(scip, *sol), SCIPgetSolOrigObj(scip, sourcesol)) )
945 {
946 /* @todo how should we avoid numerical trobles here for large objective values? */
947 if( (SCIPgetSolOrigObj(scip, *sol) / SCIPepsilon(scip)) < 1e+15 ||
948 REALABS(SCIPgetSolOrigObj(scip, *sol) - SCIPgetSolOrigObj(scip, sourcesol)) > 1e-12 * SCIPgetSolOrigObj(scip, *sol) )
949 *success = FALSE;
950 }
951
952 TERMINATE:
953 SCIPfreeBufferArray(scip, &solvals);
954
955 return SCIP_OKAY;
956 }
957
958 /** frees primal CIP solution
959 *
960 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
961 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
962 *
963 * @pre This method can be called if SCIP is in one of the following stages:
964 * - \ref SCIP_STAGE_PROBLEM
965 * - \ref SCIP_STAGE_TRANSFORMING
966 * - \ref SCIP_STAGE_TRANSFORMED
967 * - \ref SCIP_STAGE_INITPRESOLVE
968 * - \ref SCIP_STAGE_PRESOLVING
969 * - \ref SCIP_STAGE_EXITPRESOLVE
970 * - \ref SCIP_STAGE_PRESOLVED
971 * - \ref SCIP_STAGE_INITSOLVE
972 * - \ref SCIP_STAGE_SOLVING
973 * - \ref SCIP_STAGE_SOLVED
974 * - \ref SCIP_STAGE_EXITSOLVE
975 * - \ref SCIP_STAGE_FREETRANS
976 */
SCIPfreeSol(SCIP * scip,SCIP_SOL ** sol)977 SCIP_RETCODE SCIPfreeSol(
978 SCIP* scip, /**< SCIP data structure */
979 SCIP_SOL** sol /**< pointer to the solution */
980 )
981 {
982 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
983
984 switch( scip->set->stage )
985 {
986 case SCIP_STAGE_PROBLEM:
987 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->origprimal) );
988 break;
989 case SCIP_STAGE_FREETRANS:
990 case SCIP_STAGE_TRANSFORMED:
991 case SCIP_STAGE_INITPRESOLVE:
992 case SCIP_STAGE_PRESOLVING:
993 case SCIP_STAGE_EXITPRESOLVE:
994 case SCIP_STAGE_PRESOLVED:
995 case SCIP_STAGE_SOLVING:
996 case SCIP_STAGE_TRANSFORMING:
997 case SCIP_STAGE_INITSOLVE:
998 case SCIP_STAGE_SOLVED:
999 case SCIP_STAGE_EXITSOLVE:
1000 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->primal) );
1001 break;
1002 default:
1003 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
1004 return SCIP_INVALIDCALL;
1005 } /*lint !e788*/
1006
1007 return SCIP_OKAY;
1008 }
1009
1010 /** links a primal solution to the current LP solution
1011 *
1012 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1013 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1014 *
1015 * @pre This method can be called if SCIP is in one of the following stages:
1016 * - \ref SCIP_STAGE_SOLVING
1017 */
SCIPlinkLPSol(SCIP * scip,SCIP_SOL * sol)1018 SCIP_RETCODE SCIPlinkLPSol(
1019 SCIP* scip, /**< SCIP data structure */
1020 SCIP_SOL* sol /**< primal solution */
1021 )
1022 {
1023 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1024
1025 if( !SCIPlpIsSolved(scip->lp) )
1026 {
1027 SCIPerrorMessage("LP solution does not exist\n");
1028 return SCIP_INVALIDCALL;
1029 }
1030
1031 SCIP_CALL( SCIPsolLinkLPSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) );
1032
1033 return SCIP_OKAY;
1034 }
1035
1036 /** links a primal solution to the current NLP solution
1037 *
1038 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1039 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1040 *
1041 * @pre This method can be called if SCIP is in one of the following stages:
1042 * - \ref SCIP_STAGE_SOLVING
1043 */
SCIPlinkNLPSol(SCIP * scip,SCIP_SOL * sol)1044 SCIP_RETCODE SCIPlinkNLPSol(
1045 SCIP* scip, /**< SCIP data structure */
1046 SCIP_SOL* sol /**< primal solution */
1047 )
1048 {
1049 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkNLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1050
1051 if( scip->nlp == NULL )
1052 {
1053 SCIPerrorMessage("NLP does not exist\n");
1054 return SCIP_INVALIDCALL;
1055 }
1056
1057 if( SCIPnlpGetSolstat(scip->nlp) > SCIP_NLPSOLSTAT_FEASIBLE )
1058 {
1059 SCIPerrorMessage("NLP solution does not exist\n");
1060 return SCIP_INVALIDCALL;
1061 }
1062
1063 SCIP_CALL( SCIPsolLinkNLPSol(sol, scip->stat, scip->tree, scip->nlp) );
1064
1065 return SCIP_OKAY;
1066 }
1067
1068 /** links a primal solution to the current relaxation solution
1069 *
1070 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1071 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1072 *
1073 * @pre This method can be called if SCIP is in one of the following stages:
1074 * - \ref SCIP_STAGE_SOLVING
1075 */
SCIPlinkRelaxSol(SCIP * scip,SCIP_SOL * sol)1076 SCIP_RETCODE SCIPlinkRelaxSol(
1077 SCIP* scip, /**< SCIP data structure */
1078 SCIP_SOL* sol /**< primal solution */
1079 )
1080 {
1081 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkRelaxSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1082
1083 if( !SCIPrelaxationIsSolValid(scip->relaxation) )
1084 {
1085 SCIPerrorMessage("relaxation solution is not valid\n");
1086 return SCIP_INVALIDCALL;
1087 }
1088
1089 SCIP_CALL( SCIPsolLinkRelaxSol(sol, scip->set, scip->stat, scip->tree, scip->relaxation) );
1090
1091 return SCIP_OKAY;
1092 }
1093
1094 /** links a primal solution to the current pseudo solution
1095 *
1096 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1097 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1098 *
1099 * @pre This method can be called if SCIP is in one of the following stages:
1100 * - \ref SCIP_STAGE_PRESOLVING
1101 * - \ref SCIP_STAGE_SOLVING
1102 */
SCIPlinkPseudoSol(SCIP * scip,SCIP_SOL * sol)1103 SCIP_RETCODE SCIPlinkPseudoSol(
1104 SCIP* scip, /**< SCIP data structure */
1105 SCIP_SOL* sol /**< primal solution */
1106 )
1107 {
1108 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkPseudoSol", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1109
1110 SCIP_CALL( SCIPsolLinkPseudoSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) );
1111
1112 return SCIP_OKAY;
1113 }
1114
1115 /** links a primal solution to the current LP or pseudo solution
1116 *
1117 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1118 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1119 *
1120 * @pre This method can be called if SCIP is in one of the following stages:
1121 * - \ref SCIP_STAGE_SOLVING
1122 */
SCIPlinkCurrentSol(SCIP * scip,SCIP_SOL * sol)1123 SCIP_RETCODE SCIPlinkCurrentSol(
1124 SCIP* scip, /**< SCIP data structure */
1125 SCIP_SOL* sol /**< primal solution */
1126 )
1127 {
1128 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1129
1130 SCIP_CALL( SCIPsolLinkCurrentSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) );
1131
1132 return SCIP_OKAY;
1133 }
1134
1135 /** clears a primal solution
1136 *
1137 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1138 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1139 *
1140 * @pre This method can be called if SCIP is in one of the following stages:
1141 * - \ref SCIP_STAGE_PROBLEM
1142 * - \ref SCIP_STAGE_TRANSFORMING
1143 * - \ref SCIP_STAGE_TRANSFORMED
1144 * - \ref SCIP_STAGE_INITPRESOLVE
1145 * - \ref SCIP_STAGE_PRESOLVING
1146 * - \ref SCIP_STAGE_EXITPRESOLVE
1147 * - \ref SCIP_STAGE_PRESOLVED
1148 * - \ref SCIP_STAGE_INITSOLVE
1149 * - \ref SCIP_STAGE_SOLVING
1150 * - \ref SCIP_STAGE_SOLVED
1151 * - \ref SCIP_STAGE_EXITSOLVE
1152 * - \ref SCIP_STAGE_FREETRANS
1153 */
SCIPclearSol(SCIP * scip,SCIP_SOL * sol)1154 SCIP_RETCODE SCIPclearSol(
1155 SCIP* scip, /**< SCIP data structure */
1156 SCIP_SOL* sol /**< primal solution */
1157 )
1158 {
1159 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1160
1161 SCIP_CALL( SCIPsolClear(sol, scip->stat, scip->tree) );
1162
1163 return SCIP_OKAY;
1164 }
1165
1166 /** stores solution values of variables in solution's own array
1167 *
1168 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1169 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1170 *
1171 * @pre This method can be called if SCIP is in one of the following stages:
1172 * - \ref SCIP_STAGE_TRANSFORMING
1173 * - \ref SCIP_STAGE_TRANSFORMED
1174 * - \ref SCIP_STAGE_PRESOLVING
1175 * - \ref SCIP_STAGE_PRESOLVED
1176 * - \ref SCIP_STAGE_INITSOLVE
1177 * - \ref SCIP_STAGE_SOLVING
1178 * - \ref SCIP_STAGE_SOLVED
1179 * - \ref SCIP_STAGE_EXITSOLVE
1180 * - \ref SCIP_STAGE_FREETRANS
1181 */
SCIPunlinkSol(SCIP * scip,SCIP_SOL * sol)1182 SCIP_RETCODE SCIPunlinkSol(
1183 SCIP* scip, /**< SCIP data structure */
1184 SCIP_SOL* sol /**< primal solution */
1185 )
1186 {
1187 SCIP_CALL( SCIPcheckStage(scip, "SCIPunlinkSol", FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1188
1189 SCIP_CALL( SCIPsolUnlink(sol, scip->set, scip->transprob) );
1190
1191 return SCIP_OKAY;
1192 }
1193
1194 /** sets value of variable in primal CIP solution
1195 *
1196 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1197 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1198 *
1199 * @pre This method can be called if SCIP is in one of the following stages:
1200 * - \ref SCIP_STAGE_PROBLEM
1201 * - \ref SCIP_STAGE_TRANSFORMING
1202 * - \ref SCIP_STAGE_TRANSFORMED
1203 * - \ref SCIP_STAGE_INITPRESOLVE
1204 * - \ref SCIP_STAGE_PRESOLVING
1205 * - \ref SCIP_STAGE_EXITPRESOLVE
1206 * - \ref SCIP_STAGE_PRESOLVED
1207 * - \ref SCIP_STAGE_INITSOLVE
1208 * - \ref SCIP_STAGE_SOLVING
1209 * - \ref SCIP_STAGE_SOLVED
1210 * - \ref SCIP_STAGE_EXITSOLVE
1211 * - \ref SCIP_STAGE_FREETRANS
1212 */
SCIPsetSolVal(SCIP * scip,SCIP_SOL * sol,SCIP_VAR * var,SCIP_Real val)1213 SCIP_RETCODE SCIPsetSolVal(
1214 SCIP* scip, /**< SCIP data structure */
1215 SCIP_SOL* sol, /**< primal solution */
1216 SCIP_VAR* var, /**< variable to add to solution */
1217 SCIP_Real val /**< solution value of variable */
1218 )
1219 {
1220 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1221
1222 assert( var->scip == scip );
1223
1224 if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) )
1225 {
1226 SCIPerrorMessage("cannot set value of transformed variable <%s> in original space solution\n",
1227 SCIPvarGetName(var));
1228 return SCIP_INVALIDCALL;
1229 }
1230
1231 SCIP_CALL( SCIPsolSetVal(sol, scip->set, scip->stat, scip->tree, var, val) );
1232
1233 return SCIP_OKAY;
1234 }
1235
1236 /** sets values of multiple variables in primal CIP solution
1237 *
1238 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1239 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1240 *
1241 * @pre This method can be called if SCIP is in one of the following stages:
1242 * - \ref SCIP_STAGE_PROBLEM
1243 * - \ref SCIP_STAGE_TRANSFORMING
1244 * - \ref SCIP_STAGE_TRANSFORMED
1245 * - \ref SCIP_STAGE_INITPRESOLVE
1246 * - \ref SCIP_STAGE_PRESOLVING
1247 * - \ref SCIP_STAGE_EXITPRESOLVE
1248 * - \ref SCIP_STAGE_PRESOLVED
1249 * - \ref SCIP_STAGE_INITSOLVE
1250 * - \ref SCIP_STAGE_SOLVING
1251 * - \ref SCIP_STAGE_SOLVED
1252 * - \ref SCIP_STAGE_EXITSOLVE
1253 * - \ref SCIP_STAGE_FREETRANS
1254 */
SCIPsetSolVals(SCIP * scip,SCIP_SOL * sol,int nvars,SCIP_VAR ** vars,SCIP_Real * vals)1255 SCIP_RETCODE SCIPsetSolVals(
1256 SCIP* scip, /**< SCIP data structure */
1257 SCIP_SOL* sol, /**< primal solution */
1258 int nvars, /**< number of variables to set solution value for */
1259 SCIP_VAR** vars, /**< array with variables to add to solution */
1260 SCIP_Real* vals /**< array with solution values of variables */
1261 )
1262 {
1263 int v;
1264
1265 assert(nvars == 0 || vars != NULL);
1266 assert(nvars == 0 || vals != NULL);
1267
1268 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetSolVals", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1269
1270 if( SCIPsolIsOriginal(sol) )
1271 {
1272 for( v = 0; v < nvars; ++v )
1273 {
1274 if( SCIPvarIsTransformed(vars[v]) )
1275 {
1276 SCIPerrorMessage("cannot set value of transformed variable <%s> in original space solution\n",
1277 SCIPvarGetName(vars[v]));
1278 return SCIP_INVALIDCALL;
1279 }
1280 }
1281 }
1282
1283 for( v = 0; v < nvars; ++v )
1284 {
1285 SCIP_CALL( SCIPsolSetVal(sol, scip->set, scip->stat, scip->tree, vars[v], vals[v]) );
1286 }
1287
1288 return SCIP_OKAY;
1289 }
1290
1291 /** increases value of variable in primal CIP solution
1292 *
1293 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1294 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1295 *
1296 * @pre This method can be called if SCIP is in one of the following stages:
1297 * - \ref SCIP_STAGE_PROBLEM
1298 * - \ref SCIP_STAGE_TRANSFORMING
1299 * - \ref SCIP_STAGE_TRANSFORMED
1300 * - \ref SCIP_STAGE_INITPRESOLVE
1301 * - \ref SCIP_STAGE_PRESOLVING
1302 * - \ref SCIP_STAGE_EXITPRESOLVE
1303 * - \ref SCIP_STAGE_PRESOLVED
1304 * - \ref SCIP_STAGE_INITSOLVE
1305 * - \ref SCIP_STAGE_SOLVING
1306 * - \ref SCIP_STAGE_SOLVED
1307 * - \ref SCIP_STAGE_EXITSOLVE
1308 * - \ref SCIP_STAGE_FREETRANS
1309 */
SCIPincSolVal(SCIP * scip,SCIP_SOL * sol,SCIP_VAR * var,SCIP_Real incval)1310 SCIP_RETCODE SCIPincSolVal(
1311 SCIP* scip, /**< SCIP data structure */
1312 SCIP_SOL* sol, /**< primal solution */
1313 SCIP_VAR* var, /**< variable to increase solution value for */
1314 SCIP_Real incval /**< increment for solution value of variable */
1315 )
1316 {
1317 SCIP_CALL( SCIPcheckStage(scip, "SCIPincSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1318
1319 assert( var->scip == scip );
1320
1321 if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) )
1322 {
1323 SCIPerrorMessage("cannot increase value of transformed variable <%s> in original space solution\n",
1324 SCIPvarGetName(var));
1325 return SCIP_INVALIDCALL;
1326 }
1327
1328 SCIP_CALL( SCIPsolIncVal(sol, scip->set, scip->stat, scip->tree, var, incval) );
1329
1330 return SCIP_OKAY;
1331 }
1332
1333 /** returns value of variable in primal CIP solution, or in current LP/pseudo solution
1334 *
1335 * @return value of variable in primal CIP solution, or in current LP/pseudo solution
1336 *
1337 * @pre In case the solution pointer @p sol is @b NULL, that means it is asked for the LP or pseudo solution, this method
1338 * can only be called if @p scip is in the solving stage \ref SCIP_STAGE_SOLVING. In any other case, this method
1339 * can be called if @p scip is in one of the following stages:
1340 * - \ref SCIP_STAGE_PROBLEM
1341 * - \ref SCIP_STAGE_TRANSFORMING
1342 * - \ref SCIP_STAGE_TRANSFORMED
1343 * - \ref SCIP_STAGE_INITPRESOLVE
1344 * - \ref SCIP_STAGE_PRESOLVING
1345 * - \ref SCIP_STAGE_EXITPRESOLVE
1346 * - \ref SCIP_STAGE_PRESOLVED
1347 * - \ref SCIP_STAGE_INITSOLVE
1348 * - \ref SCIP_STAGE_SOLVING
1349 * - \ref SCIP_STAGE_SOLVED
1350 * - \ref SCIP_STAGE_EXITSOLVE
1351 * - \ref SCIP_STAGE_FREETRANS
1352 */
SCIPgetSolVal(SCIP * scip,SCIP_SOL * sol,SCIP_VAR * var)1353 SCIP_Real SCIPgetSolVal(
1354 SCIP* scip, /**< SCIP data structure */
1355 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */
1356 SCIP_VAR* var /**< variable to get value for */
1357 )
1358 {
1359 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1360
1361 assert( var->scip == scip );
1362
1363 if( sol != NULL )
1364 return SCIPsolGetVal(sol, scip->set, scip->stat, var);
1365
1366 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolVal(sol==NULL)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1367
1368 return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree));
1369 }
1370
1371 /** gets values of multiple variables in primal CIP solution
1372 *
1373 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1374 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1375 *
1376 * @pre This method can be called if SCIP is in one of the following stages:
1377 * - \ref SCIP_STAGE_PROBLEM
1378 * - \ref SCIP_STAGE_TRANSFORMING
1379 * - \ref SCIP_STAGE_TRANSFORMED
1380 * - \ref SCIP_STAGE_INITPRESOLVE
1381 * - \ref SCIP_STAGE_PRESOLVING
1382 * - \ref SCIP_STAGE_EXITPRESOLVE
1383 * - \ref SCIP_STAGE_PRESOLVED
1384 * - \ref SCIP_STAGE_INITSOLVE
1385 * - \ref SCIP_STAGE_SOLVING
1386 * - \ref SCIP_STAGE_SOLVED
1387 * - \ref SCIP_STAGE_EXITSOLVE
1388 * - \ref SCIP_STAGE_FREETRANS
1389 */
SCIPgetSolVals(SCIP * scip,SCIP_SOL * sol,int nvars,SCIP_VAR ** vars,SCIP_Real * vals)1390 SCIP_RETCODE SCIPgetSolVals(
1391 SCIP* scip, /**< SCIP data structure */
1392 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */
1393 int nvars, /**< number of variables to get solution value for */
1394 SCIP_VAR** vars, /**< array with variables to get value for */
1395 SCIP_Real* vals /**< array to store solution values of variables */
1396 )
1397 {
1398 assert(nvars == 0 || vars != NULL);
1399 assert(nvars == 0 || vals != NULL);
1400
1401 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetSolVals", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1402
1403 if( sol != NULL )
1404 {
1405 int v;
1406
1407 for( v = 0; v < nvars; ++v )
1408 vals[v] = SCIPsolGetVal(sol, scip->set, scip->stat, vars[v]);
1409 }
1410 else
1411 {
1412 SCIP_CALL( SCIPgetVarSols(scip, nvars, vars, vals) );
1413 }
1414
1415 return SCIP_OKAY;
1416 }
1417
1418 /** returns objective value of primal CIP solution w.r.t. original problem, or current LP/pseudo objective value
1419 *
1420 * @return objective value of primal CIP solution w.r.t. original problem, or current LP/pseudo objective value
1421 *
1422 * @pre This method can be called if SCIP is in one of the following stages:
1423 * - \ref SCIP_STAGE_PROBLEM
1424 * - \ref SCIP_STAGE_TRANSFORMING
1425 * - \ref SCIP_STAGE_TRANSFORMED
1426 * - \ref SCIP_STAGE_INITPRESOLVE
1427 * - \ref SCIP_STAGE_PRESOLVING
1428 * - \ref SCIP_STAGE_EXITPRESOLVE
1429 * - \ref SCIP_STAGE_PRESOLVED
1430 * - \ref SCIP_STAGE_INITSOLVE
1431 * - \ref SCIP_STAGE_SOLVING
1432 * - \ref SCIP_STAGE_SOLVED
1433 * - \ref SCIP_STAGE_EXITSOLVE
1434 * - \ref SCIP_STAGE_FREETRANS
1435 */
SCIPgetSolOrigObj(SCIP * scip,SCIP_SOL * sol)1436 SCIP_Real SCIPgetSolOrigObj(
1437 SCIP* scip, /**< SCIP data structure */
1438 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo objective value */
1439 )
1440 {
1441 /* for original solutions, an original objective value is already available in SCIP_STAGE_PROBLEM
1442 * for all other solutions, we should be at least in SCIP_STAGE_TRANSFORMING
1443 */
1444 if( sol != NULL && SCIPsolIsOriginal(sol) )
1445 {
1446 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1447
1448 return SCIPsolGetOrigObj(sol);
1449 }
1450
1451 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1452
1453 if( sol != NULL )
1454 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
1455 else
1456 {
1457 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj(sol==NULL)", \
1458 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1459 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
1460 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPlpGetObjval(scip->lp, scip->set, scip->transprob));
1461 else
1462 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPlpGetPseudoObjval(scip->lp, scip->set, scip->transprob));
1463 }
1464 }
1465
1466 /** returns transformed objective value of primal CIP solution, or transformed current LP/pseudo objective value
1467 *
1468 * @return transformed objective value of primal CIP solution, or transformed current LP/pseudo objective value
1469 *
1470 * @pre This method can be called if SCIP is in one of the following stages:
1471 * - \ref SCIP_STAGE_TRANSFORMING
1472 * - \ref SCIP_STAGE_TRANSFORMED
1473 * - \ref SCIP_STAGE_INITPRESOLVE
1474 * - \ref SCIP_STAGE_PRESOLVING
1475 * - \ref SCIP_STAGE_EXITPRESOLVE
1476 * - \ref SCIP_STAGE_PRESOLVED
1477 * - \ref SCIP_STAGE_INITSOLVE
1478 * - \ref SCIP_STAGE_SOLVING
1479 * - \ref SCIP_STAGE_SOLVED
1480 * - \ref SCIP_STAGE_EXITSOLVE
1481 * - \ref SCIP_STAGE_FREETRANS
1482 */
SCIPgetSolTransObj(SCIP * scip,SCIP_SOL * sol)1483 SCIP_Real SCIPgetSolTransObj(
1484 SCIP* scip, /**< SCIP data structure */
1485 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo objective value */
1486 )
1487 {
1488 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTransObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1489
1490 if( sol != NULL )
1491 return SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob);
1492 else
1493 {
1494 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTransObj(sol==NULL)", \
1495 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1496 if( SCIPtreeHasCurrentNodeLP(scip->tree) )
1497 return SCIPlpGetObjval(scip->lp, scip->set, scip->transprob);
1498 else
1499 return SCIPlpGetPseudoObjval(scip->lp, scip->set, scip->transprob);
1500 }
1501 }
1502
1503 /** recomputes the objective value of an original solution, e.g., when transferring solutions
1504 * from the solution pool (objective coefficients might have changed in the meantime)
1505 *
1506 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1507 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1508 *
1509 * @pre This method can be called if SCIP is in one of the following stages:
1510 * - \ref SCIP_STAGE_PRESOLVING
1511 * - \ref SCIP_STAGE_SOLVING
1512 *
1513 */
SCIPrecomputeSolObj(SCIP * scip,SCIP_SOL * sol)1514 SCIP_RETCODE SCIPrecomputeSolObj(
1515 SCIP* scip,
1516 SCIP_SOL* sol
1517 )
1518 {
1519 assert(scip != NULL);
1520
1521 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecomputeSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1522
1523 SCIPsolRecomputeObj(sol, scip->set, scip->stat, scip->origprob);
1524
1525 return SCIP_OKAY;
1526 }
1527
1528 /** maps original space objective value into transformed objective value
1529 *
1530 * @return transformed objective value
1531 *
1532 * @pre This method can be called if SCIP is in one of the following stages:
1533 * - \ref SCIP_STAGE_TRANSFORMING
1534 * - \ref SCIP_STAGE_TRANSFORMED
1535 * - \ref SCIP_STAGE_INITPRESOLVE
1536 * - \ref SCIP_STAGE_PRESOLVING
1537 * - \ref SCIP_STAGE_EXITPRESOLVE
1538 * - \ref SCIP_STAGE_PRESOLVED
1539 * - \ref SCIP_STAGE_INITSOLVE
1540 * - \ref SCIP_STAGE_SOLVING
1541 * - \ref SCIP_STAGE_SOLVED
1542 */
SCIPtransformObj(SCIP * scip,SCIP_Real obj)1543 SCIP_Real SCIPtransformObj(
1544 SCIP* scip, /**< SCIP data structure */
1545 SCIP_Real obj /**< original space objective value to transform */
1546 )
1547 {
1548 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPtransformObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1549
1550 return SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, obj);
1551 }
1552
1553 /** maps transformed objective value into original space
1554 *
1555 * @return objective value into original space
1556 *
1557 * @pre This method can be called if SCIP is in one of the following stages:
1558 * - \ref SCIP_STAGE_TRANSFORMING
1559 * - \ref SCIP_STAGE_TRANSFORMED
1560 * - \ref SCIP_STAGE_INITPRESOLVE
1561 * - \ref SCIP_STAGE_PRESOLVING
1562 * - \ref SCIP_STAGE_EXITPRESOLVE
1563 * - \ref SCIP_STAGE_PRESOLVED
1564 * - \ref SCIP_STAGE_INITSOLVE
1565 * - \ref SCIP_STAGE_SOLVING
1566 * - \ref SCIP_STAGE_SOLVED
1567 */
SCIPretransformObj(SCIP * scip,SCIP_Real obj)1568 SCIP_Real SCIPretransformObj(
1569 SCIP* scip, /**< SCIP data structure */
1570 SCIP_Real obj /**< transformed objective value to retransform in original space */
1571 )
1572 {
1573 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPretransformObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1574
1575 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, obj);
1576 }
1577
1578 /** gets clock time, when this solution was found
1579 *
1580 * @return clock time, when this solution was found
1581 *
1582 * @pre This method can be called if SCIP is in one of the following stages:
1583 * - \ref SCIP_STAGE_TRANSFORMING
1584 * - \ref SCIP_STAGE_TRANSFORMED
1585 * - \ref SCIP_STAGE_INITPRESOLVE
1586 * - \ref SCIP_STAGE_PRESOLVING
1587 * - \ref SCIP_STAGE_EXITPRESOLVE
1588 * - \ref SCIP_STAGE_PRESOLVED
1589 * - \ref SCIP_STAGE_INITSOLVE
1590 * - \ref SCIP_STAGE_SOLVING
1591 * - \ref SCIP_STAGE_SOLVED
1592 * - \ref SCIP_STAGE_EXITSOLVE
1593 * - \ref SCIP_STAGE_FREETRANS
1594 */
SCIPgetSolTime(SCIP * scip,SCIP_SOL * sol)1595 SCIP_Real SCIPgetSolTime(
1596 SCIP* scip, /**< SCIP data structure */
1597 SCIP_SOL* sol /**< primal solution */
1598 )
1599 {
1600 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTime", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1601
1602 return SCIPsolGetTime(sol);
1603 }
1604
1605 /** gets branch and bound run number, where this solution was found
1606 *
1607 * @return branch and bound run number, where this solution was found
1608 *
1609 * @pre This method can be called if SCIP is in one of the following stages:
1610 * - \ref SCIP_STAGE_TRANSFORMING
1611 * - \ref SCIP_STAGE_TRANSFORMED
1612 * - \ref SCIP_STAGE_INITPRESOLVE
1613 * - \ref SCIP_STAGE_PRESOLVING
1614 * - \ref SCIP_STAGE_EXITPRESOLVE
1615 * - \ref SCIP_STAGE_PRESOLVED
1616 * - \ref SCIP_STAGE_INITSOLVE
1617 * - \ref SCIP_STAGE_SOLVING
1618 * - \ref SCIP_STAGE_SOLVED
1619 * - \ref SCIP_STAGE_EXITSOLVE
1620 * - \ref SCIP_STAGE_FREETRANS
1621 */
SCIPgetSolRunnum(SCIP * scip,SCIP_SOL * sol)1622 int SCIPgetSolRunnum(
1623 SCIP* scip, /**< SCIP data structure */
1624 SCIP_SOL* sol /**< primal solution */
1625 )
1626 {
1627 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolRunnum", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1628
1629 return SCIPsolGetRunnum(sol);
1630 }
1631
1632 /** gets node number of the specific branch and bound run, where this solution was found
1633 *
1634 * @return node number of the specific branch and bound run, where this solution was found
1635 *
1636 * @pre This method can be called if SCIP is in one of the following stages:
1637 * - \ref SCIP_STAGE_TRANSFORMING
1638 * - \ref SCIP_STAGE_TRANSFORMED
1639 * - \ref SCIP_STAGE_INITPRESOLVE
1640 * - \ref SCIP_STAGE_PRESOLVING
1641 * - \ref SCIP_STAGE_EXITPRESOLVE
1642 * - \ref SCIP_STAGE_PRESOLVED
1643 * - \ref SCIP_STAGE_INITSOLVE
1644 * - \ref SCIP_STAGE_SOLVING
1645 * - \ref SCIP_STAGE_SOLVED
1646 * - \ref SCIP_STAGE_EXITSOLVE
1647 * - \ref SCIP_STAGE_FREETRANS
1648 */
SCIPgetSolNodenum(SCIP * scip,SCIP_SOL * sol)1649 SCIP_Longint SCIPgetSolNodenum(
1650 SCIP* scip, /**< SCIP data structure */
1651 SCIP_SOL* sol /**< primal solution */
1652 )
1653 {
1654 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolNodenum", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1655
1656 return SCIPsolGetNodenum(sol);
1657 }
1658
1659 /** gets heuristic, that found this solution (or NULL if it's from the tree)
1660 *
1661 * @return heuristic, that found this solution (or NULL if it's from the tree)
1662 *
1663 * @pre This method can be called if SCIP is in one of the following stages:
1664 * - \ref SCIP_STAGE_TRANSFORMING
1665 * - \ref SCIP_STAGE_TRANSFORMED
1666 * - \ref SCIP_STAGE_INITPRESOLVE
1667 * - \ref SCIP_STAGE_PRESOLVING
1668 * - \ref SCIP_STAGE_EXITPRESOLVE
1669 * - \ref SCIP_STAGE_PRESOLVED
1670 * - \ref SCIP_STAGE_INITSOLVE
1671 * - \ref SCIP_STAGE_SOLVING
1672 * - \ref SCIP_STAGE_SOLVED
1673 * - \ref SCIP_STAGE_EXITSOLVE
1674 * - \ref SCIP_STAGE_FREETRANS
1675 */
SCIPgetSolHeur(SCIP * scip,SCIP_SOL * sol)1676 SCIP_HEUR* SCIPgetSolHeur(
1677 SCIP* scip, /**< SCIP data structure */
1678 SCIP_SOL* sol /**< primal solution */
1679 )
1680 {
1681 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolHeur", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1682
1683 return SCIPsolGetHeur(sol);
1684 }
1685
1686 /** returns whether two given solutions are exactly equal
1687 *
1688 * @return returns whether two given solutions are exactly equal
1689 *
1690 * @pre This method can be called if SCIP is in one of the following stages:
1691 * - \ref SCIP_STAGE_PROBLEM
1692 * - \ref SCIP_STAGE_TRANSFORMING
1693 * - \ref SCIP_STAGE_TRANSFORMED
1694 * - \ref SCIP_STAGE_INITPRESOLVE
1695 * - \ref SCIP_STAGE_PRESOLVING
1696 * - \ref SCIP_STAGE_EXITPRESOLVE
1697 * - \ref SCIP_STAGE_PRESOLVED
1698 * - \ref SCIP_STAGE_INITSOLVE
1699 * - \ref SCIP_STAGE_SOLVING
1700 * - \ref SCIP_STAGE_SOLVED
1701 * - \ref SCIP_STAGE_EXITSOLVE
1702 * - \ref SCIP_STAGE_FREETRANS
1703 */
SCIPareSolsEqual(SCIP * scip,SCIP_SOL * sol1,SCIP_SOL * sol2)1704 SCIP_Bool SCIPareSolsEqual(
1705 SCIP* scip, /**< SCIP data structure */
1706 SCIP_SOL* sol1, /**< first primal CIP solution */
1707 SCIP_SOL* sol2 /**< second primal CIP solution */
1708 )
1709 {
1710 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPareSolsEqual", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
1711
1712 return SCIPsolsAreEqual(sol1, sol2, scip->set, scip->stat, scip->origprob, scip->transprob);
1713 }
1714
1715 /** adjusts solution values of implicit integer variables in handed solution. Solution objective value is not
1716 * deteriorated by this method.
1717 *
1718 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1719 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1720 *
1721 * @pre This method can be called if SCIP is in one of the following stages:
1722 * - \ref SCIP_STAGE_SOLVING
1723 */
SCIPadjustImplicitSolVals(SCIP * scip,SCIP_SOL * sol,SCIP_Bool uselprows)1724 SCIP_RETCODE SCIPadjustImplicitSolVals(
1725 SCIP* scip, /**< SCIP data structure */
1726 SCIP_SOL* sol, /**< primal CIP solution */
1727 SCIP_Bool uselprows /**< should LP row information be considered for none-objective variables */
1728 )
1729 {
1730 assert(scip != NULL);
1731 SCIP_CALL( SCIPcheckStage(scip, "SCIPadjustImplicitSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1732
1733 assert(sol != NULL);
1734 SCIP_CALL( SCIPsolAdjustImplicitSolVals(sol, scip->set, scip->stat, scip->transprob, scip->tree, uselprows) );
1735
1736 return SCIP_OKAY;
1737 }
1738
1739 /** outputs non-zero variables of solution in original problem space to the given file stream
1740 *
1741 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1742 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1743 *
1744 * @pre In case the solution pointer @p sol is NULL (asking for the current LP/pseudo solution), this method can be
1745 * called if @p scip is in one of the following stages:
1746 * - \ref SCIP_STAGE_PRESOLVING
1747 * - \ref SCIP_STAGE_EXITPRESOLVE
1748 * - \ref SCIP_STAGE_PRESOLVED
1749 * - \ref SCIP_STAGE_INITSOLVE
1750 * - \ref SCIP_STAGE_SOLVING
1751 * - \ref SCIP_STAGE_SOLVED
1752 * - \ref SCIP_STAGE_EXITSOLVE
1753 *
1754 * @pre In case the solution pointer @p sol is @b not NULL, this method can be called if @p scip is in one of the
1755 * following stages:
1756 * - \ref SCIP_STAGE_PROBLEM
1757 * - \ref SCIP_STAGE_TRANSFORMED
1758 * - \ref SCIP_STAGE_INITPRESOLVE
1759 * - \ref SCIP_STAGE_PRESOLVING
1760 * - \ref SCIP_STAGE_EXITPRESOLVE
1761 * - \ref SCIP_STAGE_PRESOLVED
1762 * - \ref SCIP_STAGE_INITSOLVE
1763 * - \ref SCIP_STAGE_SOLVING
1764 * - \ref SCIP_STAGE_SOLVED
1765 * - \ref SCIP_STAGE_EXITSOLVE
1766 */
SCIPprintSol(SCIP * scip,SCIP_SOL * sol,FILE * file,SCIP_Bool printzeros)1767 SCIP_RETCODE SCIPprintSol(
1768 SCIP* scip, /**< SCIP data structure */
1769 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */
1770 FILE* file, /**< output file (or NULL for standard output) */
1771 SCIP_Bool printzeros /**< should variables set to zero be printed? */
1772 )
1773 {
1774 SCIP_Real objvalue;
1775 SCIP_Bool currentsol;
1776 SCIP_Bool oldquiet = FALSE;
1777
1778 assert(SCIPisTransformed(scip) || sol != NULL);
1779
1780 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1781
1782 currentsol = (sol == NULL);
1783 if( currentsol )
1784 {
1785 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintSol(sol==NULL)", \
1786 FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1787
1788 /* create a temporary solution that is linked to the current solution */
1789 SCIP_CALL( SCIPsolCreateCurrentSol(&sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal,
1790 scip->tree, scip->lp, NULL) );
1791 }
1792
1793 if( file != NULL && scip->messagehdlr != NULL )
1794 {
1795 oldquiet = SCIPmessagehdlrIsQuiet(scip->messagehdlr);
1796 SCIPmessagehdlrSetQuiet(scip->messagehdlr, FALSE);
1797 }
1798
1799 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: ");
1800
1801 if( SCIPsolIsPartial(sol) )
1802 {
1803 SCIPmessageFPrintInfo(scip->messagehdlr, file, "unknown\n");
1804 }
1805 else
1806 {
1807 if( SCIPsolIsOriginal(sol) )
1808 objvalue = SCIPsolGetOrigObj(sol);
1809 else
1810 objvalue = SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
1811
1812 SCIPprintReal(scip, file, objvalue, 20, 15);
1813 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");
1814 }
1815
1816 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, FALSE,
1817 printzeros) );
1818
1819 if( file != NULL && scip->messagehdlr != NULL )
1820 {
1821 SCIPmessagehdlrSetQuiet(scip->messagehdlr, oldquiet);
1822 }
1823
1824 if( currentsol )
1825 {
1826 /* free temporary solution */
1827 SCIP_CALL( SCIPsolFree(&sol, scip->mem->probmem, scip->primal) );
1828 }
1829
1830 return SCIP_OKAY;
1831 }
1832
1833 /** outputs non-zero variables of solution in transformed problem space to file stream
1834 *
1835 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1836 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1837 *
1838 * @pre This method can be called if SCIP is in one of the following stages:
1839 * - \ref SCIP_STAGE_TRANSFORMED
1840 * - \ref SCIP_STAGE_INITPRESOLVE
1841 * - \ref SCIP_STAGE_PRESOLVING
1842 * - \ref SCIP_STAGE_EXITPRESOLVE
1843 * - \ref SCIP_STAGE_PRESOLVED
1844 * - \ref SCIP_STAGE_INITSOLVE
1845 * - \ref SCIP_STAGE_SOLVING
1846 * - \ref SCIP_STAGE_SOLVED
1847 * - \ref SCIP_STAGE_EXITSOLVE
1848 */
SCIPprintTransSol(SCIP * scip,SCIP_SOL * sol,FILE * file,SCIP_Bool printzeros)1849 SCIP_RETCODE SCIPprintTransSol(
1850 SCIP* scip, /**< SCIP data structure */
1851 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */
1852 FILE* file, /**< output file (or NULL for standard output) */
1853 SCIP_Bool printzeros /**< should variables set to zero be printed? */
1854 )
1855 {
1856 SCIP_Bool currentsol;
1857
1858 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintTransSol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1859
1860 currentsol = (sol == NULL);
1861 if( currentsol )
1862 {
1863 /* create a temporary solution that is linked to the current solution */
1864 SCIP_CALL( SCIPsolCreateCurrentSol(&sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal,
1865 scip->tree, scip->lp, NULL) );
1866 }
1867
1868 if( SCIPsolIsOriginal(sol) )
1869 {
1870 SCIPerrorMessage("cannot print original space solution as transformed solution\n");
1871 return SCIP_INVALIDCALL;
1872 }
1873
1874 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: ");
1875 SCIPprintReal(scip, file, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob), 20, 9);
1876 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");
1877
1878 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->transprob, NULL, file, FALSE, printzeros) );
1879
1880 if( currentsol )
1881 {
1882 /* free temporary solution */
1883 SCIP_CALL( SCIPsolFree(&sol, scip->mem->probmem, scip->primal) );
1884 }
1885
1886 return SCIP_OKAY;
1887 }
1888
1889 /** outputs discrete variables of solution in original problem space to the given file stream
1890 *
1891 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1892 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1893 *
1894 * @pre This method can be called if @p scip is in one of the following stages:
1895 * - \ref SCIP_STAGE_PROBLEM
1896 * - \ref SCIP_STAGE_TRANSFORMED
1897 * - \ref SCIP_STAGE_INITPRESOLVE
1898 * - \ref SCIP_STAGE_PRESOLVING
1899 * - \ref SCIP_STAGE_EXITPRESOLVE
1900 * - \ref SCIP_STAGE_PRESOLVED
1901 * - \ref SCIP_STAGE_INITSOLVE
1902 * - \ref SCIP_STAGE_SOLVING
1903 * - \ref SCIP_STAGE_SOLVED
1904 * - \ref SCIP_STAGE_EXITSOLVE
1905 */
SCIPprintMIPStart(SCIP * scip,SCIP_SOL * sol,FILE * file)1906 SCIP_RETCODE SCIPprintMIPStart(
1907 SCIP* scip, /**< SCIP data structure */
1908 SCIP_SOL* sol, /**< primal solution */
1909 FILE* file /**< output file (or NULL for standard output) */
1910 )
1911 {
1912 SCIP_Real objvalue;
1913 SCIP_Bool oldquiet = FALSE;
1914
1915 assert(sol != NULL);
1916 assert(!SCIPsolIsPartial(sol));
1917
1918 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintMIPStart", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
1919
1920 if( file != NULL && scip->messagehdlr != NULL )
1921 {
1922 oldquiet = SCIPmessagehdlrIsQuiet(scip->messagehdlr);
1923 SCIPmessagehdlrSetQuiet(scip->messagehdlr, FALSE);
1924 }
1925
1926 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: ");
1927
1928 if( SCIPsolIsOriginal(sol) )
1929 objvalue = SCIPsolGetOrigObj(sol);
1930 else
1931 objvalue = SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob));
1932
1933 SCIPprintReal(scip, file, objvalue, 20, 15);
1934 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");
1935
1936 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, TRUE,
1937 TRUE) );
1938
1939 if( file != NULL && scip->messagehdlr != NULL )
1940 {
1941 SCIPmessagehdlrSetQuiet(scip->messagehdlr, oldquiet);
1942 }
1943
1944 return SCIP_OKAY;
1945 }
1946
1947 /** returns dual solution value of a constraint */
SCIPgetDualSolVal(SCIP * scip,SCIP_CONS * cons,SCIP_Real * dualsolval,SCIP_Bool * boundconstraint)1948 SCIP_RETCODE SCIPgetDualSolVal(
1949 SCIP* scip, /**< SCIP data structure */
1950 SCIP_CONS* cons, /**< constraint for which the dual solution should be returned */
1951 SCIP_Real* dualsolval, /**< pointer to store the dual solution value */
1952 SCIP_Bool* boundconstraint /**< pointer to store whether the constraint is a bound constraint (or NULL) */
1953 )
1954 {
1955 SCIP_CONS* transcons;
1956 int nvars;
1957 SCIP_Bool success;
1958
1959 assert(scip != NULL);
1960 assert(cons != NULL);
1961 assert(dualsolval != NULL);
1962
1963 assert(SCIPconsGetHdlr(cons) != NULL);
1964 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear" ) == 0);
1965
1966 SCIP_CALL( SCIPconsGetNVars(cons, scip->set, &nvars, &success) );
1967 assert(success); /* is always successful, since we only have linear constraints */
1968
1969 if( boundconstraint != NULL )
1970 *boundconstraint = (nvars == 1);
1971
1972 if( SCIPconsIsTransformed(cons) )
1973 transcons = cons;
1974 else
1975 transcons = SCIPconsGetTransformed(cons);
1976
1977 /* it can happen that a transformed constraints gets deleted due to redundancy. by complementary slackness the
1978 * corresponding dual solution value would be zero. however, if the constraint contains exactly one variable we need
1979 * to check the reduced costs of the variable.
1980 */
1981 if( nvars == 0 || (nvars > 1 && transcons == NULL) )
1982 (*dualsolval) = 0.0;
1983 else
1984 {
1985 if( nvars > 1 )
1986 (*dualsolval) = SCIPgetDualsolLinear(scip, transcons);
1987 else
1988 {
1989 /* the constraint is a bound constraint */
1990 SCIP_VAR** vars;
1991 SCIP_Real* vals;
1992 SCIP_Real activity;
1993
1994 vars = SCIPgetVarsLinear(scip, cons);
1995 vals = SCIPgetValsLinear(scip, cons);
1996
1997 activity = SCIPvarGetLPSol(vars[0]) * vals[0];
1998
1999 /* return the reduced cost of the variable if the constraint would be tight */
2000 if( SCIPsetIsEQ(scip->set, activity, SCIPgetRhsLinear(scip, cons))
2001 || SCIPsetIsEQ(scip->set, activity, SCIPgetLhsLinear(scip, cons)) )
2002 (*dualsolval) = SCIPgetVarRedcost(scip, vars[0]);
2003 else
2004 (*dualsolval) = 0.0;
2005 }
2006 }
2007 assert(*dualsolval != SCIP_INVALID); /*lint !e777*/
2008
2009 /* dual values are coming from the LP solver that is always solving a minimization problem */
2010 if( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE )
2011 (*dualsolval) *= -1.0;
2012
2013 return SCIP_OKAY;
2014 }
2015
2016 /** outputs dual solution from LP solver to file stream */
2017 static
printDualSol(SCIP * scip,FILE * file,SCIP_Bool printzeros)2018 SCIP_RETCODE printDualSol(
2019 SCIP* scip, /**< SCIP data structure */
2020 FILE* file, /**< output file (or NULL for standard output) */
2021 SCIP_Bool printzeros /**< should variables set to zero be printed? */
2022 )
2023 {
2024 SCIP_Bool boundconstraint;
2025 int c;
2026
2027 assert(scip->lp != NULL);
2028 assert(scip->lp->solved);
2029 assert(scip->lp->dualfeasible);
2030
2031 /* print dual solution values of all constraints */
2032 for( c = 0; c < scip->origprob->nconss; ++c )
2033 {
2034 SCIP_CONS* cons;
2035 SCIP_Real solval;
2036
2037 cons = scip->origprob->conss[c];
2038 assert(cons != NULL);
2039
2040 SCIP_CALL( SCIPgetDualSolVal(scip, cons, &solval, &boundconstraint) );
2041
2042 if( printzeros || !SCIPisZero(scip, solval) )
2043 {
2044 SCIP_MESSAGEHDLR* messagehdlr = scip->messagehdlr;
2045
2046 SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPconsGetName(cons));
2047
2048 if( SCIPisInfinity(scip, solval) )
2049 SCIPmessageFPrintInfo(messagehdlr, file, " +infinity\n");
2050 else if( SCIPisInfinity(scip, -solval) )
2051 SCIPmessageFPrintInfo(messagehdlr, file, " -infinity\n");
2052 else
2053 {
2054 if( boundconstraint )
2055 SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g*\n", solval);
2056 else
2057 SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g\n", solval);
2058 }
2059 }
2060 }
2061
2062 return SCIP_OKAY;
2063 }
2064
2065 /** check whether the dual solution is available
2066 *
2067 * @note This is used when calling \ref SCIPprintDualSol()
2068 *
2069 * @return is dual solution available?
2070 *
2071 * @pre This method can be called if SCIP is in one of the following stages:
2072 * - \ref SCIP_STAGE_SOLVED
2073 */
SCIPisDualSolAvailable(SCIP * scip,SCIP_Bool printreason)2074 SCIP_Bool SCIPisDualSolAvailable(
2075 SCIP* scip, /**< SCIP data structure */
2076 SCIP_Bool printreason /**< print warning message if dualsol is not available? */
2077 )
2078 {
2079 int c;
2080
2081 assert(scip != NULL);
2082
2083 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisDualSolAvailable", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
2084
2085 if( SCIPgetStage(scip) != SCIP_STAGE_SOLVED )
2086 {
2087 if( printreason )
2088 SCIPmessageFPrintInfo(scip->messagehdlr, NULL, "No dual solution available.\n");
2089 return FALSE;
2090 }
2091
2092 assert(scip->stat != NULL);
2093 assert(scip->transprob != NULL);
2094
2095 /* dual solution only useful when no presolving was performed */
2096 if( scip->stat->performpresol )
2097 {
2098 if( printreason )
2099 SCIPwarningMessage(scip, "No dual information available when presolving was performed.\n");
2100 return FALSE;
2101 }
2102
2103 /* dual solution is created by LP solver and therefore only available for pure LPs */
2104 if( scip->transprob->nvars != scip->transprob->ncontvars )
2105 {
2106 if( printreason )
2107 SCIPwarningMessage(scip, "Dual information only available for pure LPs (only continuous variables).\n");
2108 return FALSE;
2109 }
2110
2111 /* dual solution is created by LP solver and therefore only available for linear constraints */
2112 for( c = scip->transprob->nconss - 1; c >= 0; --c )
2113 {
2114 SCIP_CONSHDLR* conshdlr;
2115
2116 conshdlr = SCIPconsGetHdlr(scip->transprob->conss[c]);
2117 assert(conshdlr != NULL);
2118
2119 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear" ) != 0 )
2120 {
2121 if( printreason )
2122 SCIPwarningMessage(scip, "Dual information only available for pure LPs (only linear constraints).\n");
2123 return FALSE;
2124 }
2125 }
2126
2127 return TRUE;
2128 }
2129
2130 /** outputs dual solution from LP solver to file stream
2131 *
2132 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2133 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2134 *
2135 * @pre This method can be called in all stages but only prints dual information when called in \ref SCIP_STAGE_SOLVED
2136 */
SCIPprintDualSol(SCIP * scip,FILE * file,SCIP_Bool printzeros)2137 SCIP_RETCODE SCIPprintDualSol(
2138 SCIP* scip, /**< SCIP data structure */
2139 FILE* file, /**< output file (or NULL for standard output) */
2140 SCIP_Bool printzeros /**< should variables set to zero be printed? */
2141 )
2142 {
2143 if( SCIPisDualSolAvailable(scip, TRUE) )
2144 {
2145 /* print dual solution */
2146 SCIP_CALL( printDualSol(scip, file, printzeros) );
2147 }
2148
2149 return SCIP_OKAY;
2150 }
2151
2152
2153 /** outputs non-zero variables of solution representing a ray in original problem space to file stream
2154 *
2155 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2156 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2157 *
2158 * @pre This method can be called if SCIP is in one of the following stages:
2159 * - \ref SCIP_STAGE_PROBLEM
2160 * - \ref SCIP_STAGE_TRANSFORMED
2161 * - \ref SCIP_STAGE_INITPRESOLVE
2162 * - \ref SCIP_STAGE_PRESOLVING
2163 * - \ref SCIP_STAGE_EXITPRESOLVE
2164 * - \ref SCIP_STAGE_PRESOLVED
2165 * - \ref SCIP_STAGE_INITSOLVE
2166 * - \ref SCIP_STAGE_SOLVING
2167 * - \ref SCIP_STAGE_SOLVED
2168 * - \ref SCIP_STAGE_EXITSOLVE
2169 */
SCIPprintRay(SCIP * scip,SCIP_SOL * sol,FILE * file,SCIP_Bool printzeros)2170 SCIP_RETCODE SCIPprintRay(
2171 SCIP* scip, /**< SCIP data structure */
2172 SCIP_SOL* sol, /**< primal solution representing ray */
2173 FILE* file, /**< output file (or NULL for standard output) */
2174 SCIP_Bool printzeros /**< should variables set to zero be printed? */
2175 )
2176 {
2177 assert(scip != NULL);
2178 assert(sol != NULL);
2179
2180 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintRay", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2181
2182 SCIP_CALL( SCIPsolPrintRay(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, printzeros) );
2183
2184 return SCIP_OKAY;
2185 }
2186
2187 /** gets number of feasible primal solutions stored in the solution storage in case the problem is transformed;
2188 * in case the problem stage is SCIP_STAGE_PROBLEM, the number of solution in the original solution candidate
2189 * storage is returned
2190 *
2191 * @return number of feasible primal solutions stored in the solution storage in case the problem is transformed; or
2192 * number of solution in the original solution candidate storage if the problem stage is SCIP_STAGE_PROBLEM
2193 *
2194 * @pre This method can be called if SCIP is in one of the following stages:
2195 * - \ref SCIP_STAGE_PROBLEM
2196 * - \ref SCIP_STAGE_TRANSFORMED
2197 * - \ref SCIP_STAGE_INITPRESOLVE
2198 * - \ref SCIP_STAGE_PRESOLVING
2199 * - \ref SCIP_STAGE_EXITPRESOLVE
2200 * - \ref SCIP_STAGE_PRESOLVED
2201 * - \ref SCIP_STAGE_INITSOLVE
2202 * - \ref SCIP_STAGE_SOLVING
2203 * - \ref SCIP_STAGE_SOLVED
2204 * - \ref SCIP_STAGE_EXITSOLVE
2205 */
SCIPgetNSols(SCIP * scip)2206 int SCIPgetNSols(
2207 SCIP* scip /**< SCIP data structure */
2208 )
2209 {
2210 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNSols", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2211
2212 switch( scip->set->stage )
2213 {
2214 case SCIP_STAGE_PROBLEM:
2215 return scip->origprimal->nsols;
2216
2217 case SCIP_STAGE_TRANSFORMED:
2218 case SCIP_STAGE_INITPRESOLVE:
2219 case SCIP_STAGE_PRESOLVING:
2220 case SCIP_STAGE_EXITPRESOLVE:
2221 case SCIP_STAGE_PRESOLVED:
2222 case SCIP_STAGE_INITSOLVE:
2223 case SCIP_STAGE_SOLVING:
2224 case SCIP_STAGE_SOLVED:
2225 case SCIP_STAGE_EXITSOLVE:
2226 return scip->primal->nsols;
2227
2228 case SCIP_STAGE_INIT:
2229 case SCIP_STAGE_TRANSFORMING:
2230 case SCIP_STAGE_FREETRANS:
2231 default:
2232 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2233 SCIPABORT();
2234 return -1; /*lint !e527*/
2235 } /*lint !e788*/
2236 }
2237
2238 /** gets array of feasible primal solutions stored in the solution storage in case the problem is transformed; in case
2239 * if the problem stage is in SCIP_STAGE_PROBLEM, it returns the number array of solution candidate stored
2240 *
2241 * @return array of feasible primal solutions
2242 *
2243 * @pre This method can be called if SCIP is in one of the following stages:
2244 * - \ref SCIP_STAGE_PROBLEM
2245 * - \ref SCIP_STAGE_TRANSFORMED
2246 * - \ref SCIP_STAGE_INITPRESOLVE
2247 * - \ref SCIP_STAGE_PRESOLVING
2248 * - \ref SCIP_STAGE_EXITPRESOLVE
2249 * - \ref SCIP_STAGE_PRESOLVED
2250 * - \ref SCIP_STAGE_INITSOLVE
2251 * - \ref SCIP_STAGE_SOLVING
2252 * - \ref SCIP_STAGE_SOLVED
2253 * - \ref SCIP_STAGE_EXITSOLVE
2254 */
SCIPgetSols(SCIP * scip)2255 SCIP_SOL** SCIPgetSols(
2256 SCIP* scip /**< SCIP data structure */
2257 )
2258 {
2259 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSols", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2260
2261 switch( scip->set->stage )
2262 {
2263 case SCIP_STAGE_PROBLEM:
2264 return scip->origprimal->sols;
2265
2266 case SCIP_STAGE_TRANSFORMED:
2267 case SCIP_STAGE_INITPRESOLVE:
2268 case SCIP_STAGE_PRESOLVING:
2269 case SCIP_STAGE_EXITPRESOLVE:
2270 case SCIP_STAGE_PRESOLVED:
2271 case SCIP_STAGE_INITSOLVE:
2272 case SCIP_STAGE_SOLVING:
2273 case SCIP_STAGE_SOLVED:
2274 case SCIP_STAGE_EXITSOLVE:
2275 return scip->primal->sols;
2276
2277 case SCIP_STAGE_INIT:
2278 case SCIP_STAGE_TRANSFORMING:
2279 case SCIP_STAGE_FREETRANS:
2280 case SCIP_STAGE_FREE:
2281 default:
2282 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2283 return NULL;
2284 } /*lint !e788*/
2285 }
2286
2287 /** gets best feasible primal solution found so far if the problem is transformed; in case the problem is in
2288 * SCIP_STAGE_PROBLEM it returns the best solution candidate, or NULL if no solution has been found or the candidate
2289 * store is empty;
2290 *
2291 * @return best feasible primal solution so far
2292 *
2293 * @pre This method can be called if SCIP is in one of the following stages:
2294 * - \ref SCIP_STAGE_PROBLEM
2295 * - \ref SCIP_STAGE_TRANSFORMED
2296 * - \ref SCIP_STAGE_INITPRESOLVE
2297 * - \ref SCIP_STAGE_PRESOLVING
2298 * - \ref SCIP_STAGE_EXITPRESOLVE
2299 * - \ref SCIP_STAGE_PRESOLVED
2300 * - \ref SCIP_STAGE_INITSOLVE
2301 * - \ref SCIP_STAGE_SOLVING
2302 * - \ref SCIP_STAGE_SOLVED
2303 * - \ref SCIP_STAGE_EXITSOLVE
2304 */
SCIPgetBestSol(SCIP * scip)2305 SCIP_SOL* SCIPgetBestSol(
2306 SCIP* scip /**< SCIP data structure */
2307 )
2308 {
2309 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetBestSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2310 switch( scip->set->stage )
2311 {
2312 case SCIP_STAGE_INIT:
2313 return NULL;
2314 case SCIP_STAGE_PROBLEM:
2315 assert(scip->origprimal != NULL);
2316 if( scip->origprimal->nsols > 0 )
2317 {
2318 assert(scip->origprimal->sols != NULL);
2319 assert(scip->origprimal->sols[0] != NULL);
2320 return scip->origprimal->sols[0];
2321 }
2322 break;
2323
2324 case SCIP_STAGE_TRANSFORMED:
2325 case SCIP_STAGE_INITPRESOLVE:
2326 case SCIP_STAGE_PRESOLVING:
2327 case SCIP_STAGE_EXITPRESOLVE:
2328 case SCIP_STAGE_PRESOLVED:
2329 case SCIP_STAGE_INITSOLVE:
2330 case SCIP_STAGE_SOLVING:
2331 case SCIP_STAGE_SOLVED:
2332 case SCIP_STAGE_EXITSOLVE:
2333 assert(scip->primal != NULL);
2334 if( scip->primal->nsols > 0 )
2335 {
2336 assert(scip->primal->sols != NULL);
2337 assert(scip->primal->sols[0] != NULL);
2338 return scip->primal->sols[0];
2339 }
2340 break;
2341
2342 case SCIP_STAGE_TRANSFORMING:
2343 case SCIP_STAGE_FREETRANS:
2344 case SCIP_STAGE_FREE:
2345 default:
2346 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2347 return NULL;
2348 }
2349
2350 return NULL;
2351 }
2352
2353 /** outputs best feasible primal solution found so far to file stream
2354 *
2355 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2356 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2357 *
2358 * @pre This method can be called if SCIP is in one of the following stages:
2359 * - \ref SCIP_STAGE_INIT
2360 * - \ref SCIP_STAGE_PROBLEM
2361 * - \ref SCIP_STAGE_TRANSFORMED
2362 * - \ref SCIP_STAGE_INITPRESOLVE
2363 * - \ref SCIP_STAGE_PRESOLVING
2364 * - \ref SCIP_STAGE_EXITPRESOLVE
2365 * - \ref SCIP_STAGE_PRESOLVED
2366 * - \ref SCIP_STAGE_INITSOLVE
2367 * - \ref SCIP_STAGE_SOLVING
2368 * - \ref SCIP_STAGE_SOLVED
2369 * - \ref SCIP_STAGE_EXITSOLVE
2370 */
SCIPprintBestSol(SCIP * scip,FILE * file,SCIP_Bool printzeros)2371 SCIP_RETCODE SCIPprintBestSol(
2372 SCIP* scip, /**< SCIP data structure */
2373 FILE* file, /**< output file (or NULL for standard output) */
2374 SCIP_Bool printzeros /**< should variables set to zero be printed? */
2375 )
2376 {
2377 SCIP_SOL* sol;
2378
2379 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintBestSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2380
2381 sol = SCIPgetBestSol(scip);
2382
2383 if( sol == NULL )
2384 SCIPmessageFPrintInfo(scip->messagehdlr, file, "no solution available\n");
2385 else
2386 {
2387 SCIP_CALL( SCIPprintSol(scip, sol, file, printzeros) );
2388 }
2389
2390 return SCIP_OKAY;
2391 }
2392
2393 /** outputs best feasible primal solution found so far in transformed variables to file stream
2394 *
2395 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2396 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2397 *
2398 * @pre This method can be called if SCIP is in one of the following stages:
2399 * - \ref SCIP_STAGE_INIT
2400 * - \ref SCIP_STAGE_PROBLEM
2401 * - \ref SCIP_STAGE_TRANSFORMED
2402 * - \ref SCIP_STAGE_INITPRESOLVE
2403 * - \ref SCIP_STAGE_PRESOLVING
2404 * - \ref SCIP_STAGE_EXITPRESOLVE
2405 * - \ref SCIP_STAGE_PRESOLVED
2406 * - \ref SCIP_STAGE_INITSOLVE
2407 * - \ref SCIP_STAGE_SOLVING
2408 * - \ref SCIP_STAGE_SOLVED
2409 * - \ref SCIP_STAGE_EXITSOLVE
2410 */
SCIPprintBestTransSol(SCIP * scip,FILE * file,SCIP_Bool printzeros)2411 SCIP_RETCODE SCIPprintBestTransSol(
2412 SCIP* scip, /**< SCIP data structure */
2413 FILE* file, /**< output file (or NULL for standard output) */
2414 SCIP_Bool printzeros /**< should variables set to zero be printed? */
2415 )
2416 {
2417 SCIP_SOL* sol;
2418
2419 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintBestTransSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
2420
2421 sol = SCIPgetBestSol(scip);
2422
2423 if( sol != NULL && SCIPsolIsOriginal(sol) )
2424 {
2425 SCIPerrorMessage("best solution is defined in original space - cannot print it as transformed solution\n");
2426 return SCIP_INVALIDCALL;
2427 }
2428
2429 if( sol == NULL )
2430 SCIPmessageFPrintInfo(scip->messagehdlr, file, "no solution available\n");
2431 else
2432 {
2433 SCIP_CALL( SCIPprintTransSol(scip, sol, file, printzeros) );
2434 }
2435
2436 return SCIP_OKAY;
2437 }
2438
2439 /** try to round given solution
2440 *
2441 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2442 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2443 *
2444 * @pre This method can be called if SCIP is in one of the following stages:
2445 * - \ref SCIP_STAGE_SOLVING
2446 */
SCIProundSol(SCIP * scip,SCIP_SOL * sol,SCIP_Bool * success)2447 SCIP_RETCODE SCIProundSol(
2448 SCIP* scip, /**< SCIP data structure */
2449 SCIP_SOL* sol, /**< primal solution */
2450 SCIP_Bool* success /**< pointer to store whether rounding was successful */
2451 )
2452 {
2453 SCIP_CALL( SCIPcheckStage(scip, "SCIProundSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2454
2455 if( SCIPsolIsOriginal(sol) )
2456 {
2457 SCIPerrorMessage("cannot round original space solution\n");
2458 return SCIP_INVALIDCALL;
2459 }
2460
2461 SCIP_CALL( SCIPsolRound(sol, scip->set, scip->stat, scip->transprob, scip->tree, success) );
2462
2463 return SCIP_OKAY;
2464 }
2465
2466 /** retransforms solution to original problem space
2467 *
2468 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2469 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2470 *
2471 * @pre This method can be called if SCIP is in one of the following stages:
2472 * - \ref SCIP_STAGE_TRANSFORMED
2473 * - \ref SCIP_STAGE_INITPRESOLVE
2474 * - \ref SCIP_STAGE_PRESOLVING
2475 * - \ref SCIP_STAGE_EXITPRESOLVE
2476 * - \ref SCIP_STAGE_PRESOLVED
2477 * - \ref SCIP_STAGE_INITSOLVE
2478 * - \ref SCIP_STAGE_SOLVING
2479 * - \ref SCIP_STAGE_SOLVED
2480 * - \ref SCIP_STAGE_EXITSOLVE
2481 * - \ref SCIP_STAGE_FREETRANS
2482 */
SCIPretransformSol(SCIP * scip,SCIP_SOL * sol)2483 SCIP_RETCODE SCIPretransformSol(
2484 SCIP* scip, /**< SCIP data structure */
2485 SCIP_SOL* sol /**< primal CIP solution */
2486 )
2487 {
2488 SCIP_CALL( SCIPcheckStage(scip, "SCIPretransformSol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
2489
2490 switch ( SCIPsolGetOrigin(sol) )
2491 {
2492 case SCIP_SOLORIGIN_ORIGINAL:
2493 /* nothing to do */
2494 return SCIP_OKAY;
2495
2496 case SCIP_SOLORIGIN_LPSOL:
2497 case SCIP_SOLORIGIN_NLPSOL:
2498 case SCIP_SOLORIGIN_RELAXSOL:
2499 case SCIP_SOLORIGIN_PSEUDOSOL:
2500
2501 /* first unlink solution */
2502 SCIP_CALL( SCIPunlinkSol(scip, sol) );
2503
2504 /*lint -fallthrough*/
2505 case SCIP_SOLORIGIN_ZERO:
2506 {
2507 SCIP_Bool hasinfval;
2508
2509 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
2510 break;
2511 }
2512 case SCIP_SOLORIGIN_PARTIAL:
2513 case SCIP_SOLORIGIN_UNKNOWN:
2514 SCIPerrorMessage("unknown solution origin.\n");
2515 return SCIP_INVALIDCALL;
2516
2517 default:
2518 /* note that this is in an internal SCIP error since all solution origins are covert in the switch above */
2519 SCIPerrorMessage("invalid solution origin <%d>\n", SCIPsolGetOrigin(sol));
2520 return SCIP_ERROR;
2521 }
2522
2523 return SCIP_OKAY;
2524 }
2525
2526 /** reads a given solution file
2527 *
2528 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2529 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2530 *
2531 * @pre This method can be called if SCIP is in one of the following stages:
2532 * - \ref SCIP_STAGE_PROBLEM
2533 * - \ref SCIP_STAGE_TRANSFORMED
2534 * - \ref SCIP_STAGE_INITPRESOLVE
2535 * - \ref SCIP_STAGE_PRESOLVING
2536 * - \ref SCIP_STAGE_EXITPRESOLVE
2537 * - \ref SCIP_STAGE_PRESOLVED
2538 * - \ref SCIP_STAGE_INITSOLVE
2539 * - \ref SCIP_STAGE_SOLVING
2540 */
SCIPreadSol(SCIP * scip,const char * filename)2541 SCIP_RETCODE SCIPreadSol(
2542 SCIP* scip, /**< SCIP data structure */
2543 const char* filename /**< name of the input file */
2544 )
2545 {
2546 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2547
2548 /* we pass the reading of the solution file on to reader_sol via the following call */
2549 SCIP_CALL( SCIPreadProb(scip, filename, "sol") );
2550
2551 return SCIP_OKAY;
2552 }
2553
2554 /** reads a given solution file and store the solution values in the given solution pointer */
2555 static
readSolFile(SCIP * scip,const char * filename,SCIP_SOL * sol,SCIP_Bool * partial,SCIP_Bool * error)2556 SCIP_RETCODE readSolFile(
2557 SCIP* scip, /**< SCIP data structure */
2558 const char* filename, /**< name of the input file */
2559 SCIP_SOL* sol, /**< solution pointer */
2560 SCIP_Bool* partial, /**< pointer to store if the solution is partial (or NULL, if not needed) */
2561 SCIP_Bool* error /**< pointer store if an error occured */
2562 )
2563 {
2564 SCIP_FILE* file;
2565 SCIP_Bool unknownvariablemessage;
2566 SCIP_Bool localpartial;
2567 int lineno;
2568
2569 assert(scip != NULL);
2570 assert(sol != NULL);
2571 assert(error != NULL);
2572
2573 /* open input file */
2574 file = SCIPfopen(filename, "r");
2575 if( file == NULL )
2576 {
2577 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2578 SCIPprintSysError(filename);
2579 return SCIP_NOFILE;
2580 }
2581
2582 *error = FALSE;
2583 localpartial = SCIPsolIsPartial(sol);
2584
2585 unknownvariablemessage = FALSE;
2586 lineno = 0;
2587
2588 /* read the file */
2589 while( !SCIPfeof(file) && !(*error) )
2590 {
2591 char buffer[SCIP_MAXSTRLEN];
2592 char varname[SCIP_MAXSTRLEN];
2593 char valuestring[SCIP_MAXSTRLEN];
2594 char objstring[SCIP_MAXSTRLEN];
2595 char format[SCIP_MAXSTRLEN];
2596 SCIP_VAR* var;
2597 SCIP_Real value;
2598 int nread;
2599
2600 /* get next line */
2601 if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL )
2602 break;
2603 lineno++;
2604
2605 /* there are some lines which may preceed the solution information */
2606 if( strncasecmp(buffer, "solution status:", 16) == 0 || strncasecmp(buffer, "objective value:", 16) == 0 ||
2607 strncasecmp(buffer, "Log started", 11) == 0 || strncasecmp(buffer, "Variable Name", 13) == 0 ||
2608 strncasecmp(buffer, "All other variables", 19) == 0 || strncasecmp(buffer, "\n", 1) == 0 ||
2609 strncasecmp(buffer, "NAME", 4) == 0 || strncasecmp(buffer, "ENDATA", 6) == 0 ) /* allow parsing of SOL-format on the MIPLIB 2003 pages */
2610 continue;
2611
2612 /* parse the line */
2613 (void) SCIPsnprintf(format, SCIP_MAXSTRLEN, "%%%ds %%%ds %%%ds\n", SCIP_MAXSTRLEN, SCIP_MAXSTRLEN, SCIP_MAXSTRLEN);
2614 nread = sscanf(buffer, format, varname, valuestring, objstring);
2615 if( nread < 2 )
2616 {
2617 SCIPerrorMessage("Invalid input line %d in solution file <%s>: <%s>.\n", lineno, filename, buffer);
2618 *error = TRUE;
2619 break;
2620 }
2621
2622 /* find the variable */
2623 var = SCIPfindVar(scip, varname);
2624 if( var == NULL )
2625 {
2626 if( !unknownvariablemessage )
2627 {
2628 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n",
2629 varname, lineno, filename);
2630 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n");
2631 unknownvariablemessage = TRUE;
2632 }
2633 continue;
2634 }
2635
2636 /* cast the value */
2637 if( strncasecmp(valuestring, "inv", 3) == 0 )
2638 continue;
2639 else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 )
2640 value = SCIPinfinity(scip);
2641 else if( strncasecmp(valuestring, "-inf", 4) == 0 )
2642 value = -SCIPinfinity(scip);
2643 else if( strncasecmp(valuestring, "unknown", 7) == 0 )
2644 {
2645 value = SCIP_UNKNOWN;
2646 localpartial = TRUE;
2647 }
2648 else
2649 {
2650 /* coverity[secure_coding] */
2651 nread = sscanf(valuestring, "%lf", &value);
2652 if( nread != 1 )
2653 {
2654 SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n",
2655 valuestring, varname, lineno, filename);
2656 *error = TRUE;
2657 break;
2658 }
2659 }
2660
2661 /* set the solution value of the variable, if not multiaggregated */
2662 if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
2663 {
2664 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var));
2665 }
2666 else
2667 {
2668 SCIP_RETCODE retcode;
2669
2670 retcode = SCIPsetSolVal(scip, sol, var, value);
2671
2672 if( retcode == SCIP_INVALIDDATA )
2673 {
2674 if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED )
2675 {
2676 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n",
2677 SCIPvarGetName(var));
2678 }
2679 else
2680 {
2681 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n",
2682 SCIPvarGetName(var));
2683 }
2684 }
2685 else
2686 {
2687 SCIP_CALL_FINALLY( retcode, SCIPfclose(file) );
2688 }
2689 }
2690 }
2691
2692 /* close input file */
2693 SCIPfclose(file);
2694
2695 if( localpartial && !SCIPsolIsPartial(sol) )
2696 {
2697 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
2698 {
2699 SCIP_CALL( SCIPsolMarkPartial(sol, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) );
2700 }
2701 else
2702 *error = TRUE;
2703 }
2704
2705 if( partial != NULL )
2706 *partial = localpartial;
2707
2708 return SCIP_OKAY;
2709 }
2710
2711 /** reads a given xml solution file and store the solution values in the given solution pointer */
2712 static
readXmlSolFile(SCIP * scip,const char * filename,SCIP_SOL * sol,SCIP_Bool * partial,SCIP_Bool * error)2713 SCIP_RETCODE readXmlSolFile(
2714 SCIP* scip, /**< SCIP data structure */
2715 const char* filename, /**< name of the input file */
2716 SCIP_SOL* sol, /**< solution pointer */
2717 SCIP_Bool* partial, /**< pointer to store if the solution is partial (or NULL if not needed) */
2718 SCIP_Bool* error /**< pointer store if an error occured */
2719 )
2720 {
2721 SCIP_Bool unknownvariablemessage;
2722 SCIP_Bool localpartial;
2723 XML_NODE* start;
2724 const XML_NODE* varsnode;
2725 const XML_NODE* varnode;
2726 const char* tag;
2727
2728 assert(scip != NULL);
2729 assert(sol != NULL);
2730 assert(error != NULL);
2731
2732 /* read xml file */
2733 start = xmlProcess(filename);
2734
2735 if( start == NULL )
2736 {
2737 SCIPerrorMessage("Some error occured during parsing the XML solution file.\n");
2738 return SCIP_READERROR;
2739 }
2740
2741 *error = FALSE;
2742 localpartial = SCIPsolIsPartial(sol);
2743
2744 /* find variable sections */
2745 tag = "variables";
2746 varsnode = xmlFindNodeMaxdepth(start, tag, 0, 3);
2747 if( varsnode == NULL )
2748 {
2749 /* free xml data */
2750 xmlFreeNode(start);
2751
2752 SCIPerrorMessage("Variable section not found.\n");
2753 return SCIP_READERROR;
2754 }
2755
2756 /* loop through all variables */
2757 unknownvariablemessage = FALSE;
2758 for( varnode = xmlFirstChild(varsnode); varnode != NULL; varnode = xmlNextSibl(varnode) )
2759 {
2760 SCIP_VAR* var;
2761 const char* varname;
2762 const char* valuestring;
2763 SCIP_Real value;
2764 int nread;
2765
2766 /* find variable name */
2767 varname = xmlGetAttrval(varnode, "name");
2768 if( varname == NULL )
2769 {
2770 SCIPerrorMessage("Attribute \"name\" of variable not found.\n");
2771 *error = TRUE;
2772 break;
2773 }
2774
2775 /* find the variable */
2776 var = SCIPfindVar(scip, varname);
2777 if( var == NULL )
2778 {
2779 if( !unknownvariablemessage )
2780 {
2781 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> of solution file <%s>\n",
2782 varname, filename);
2783 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n");
2784 unknownvariablemessage = TRUE;
2785 }
2786 continue;
2787 }
2788
2789 /* find value of variable */
2790 valuestring = xmlGetAttrval(varnode, "value");
2791 if( valuestring == NULL )
2792 {
2793 SCIPerrorMessage("Attribute \"value\" of variable not found.\n");
2794 *error = TRUE;
2795 break;
2796 }
2797
2798 /* cast the value */
2799 if( strncasecmp(valuestring, "inv", 3) == 0 )
2800 continue;
2801 else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 )
2802 value = SCIPinfinity(scip);
2803 else if( strncasecmp(valuestring, "-inf", 4) == 0 )
2804 value = -SCIPinfinity(scip);
2805 else if( strncasecmp(valuestring, "unknown", 7) == 0 )
2806 {
2807 value = SCIP_UNKNOWN;
2808 localpartial = TRUE;
2809 }
2810 else
2811 {
2812 /* coverity[secure_coding] */
2813 nread = sscanf(valuestring, "%lf", &value);
2814 if( nread != 1 )
2815 {
2816 SCIPwarningMessage(scip, "invalid solution value <%s> for variable <%s> in XML solution file <%s>\n", valuestring, varname, filename);
2817 *error = TRUE;
2818 break;
2819 }
2820 }
2821
2822 /* set the solution value of the variable, if not multiaggregated */
2823 if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR )
2824 {
2825 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var));
2826 }
2827 else
2828 {
2829 SCIP_RETCODE retcode;
2830 retcode = SCIPsetSolVal(scip, sol, var, value);
2831
2832 if( retcode == SCIP_INVALIDDATA )
2833 {
2834 if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED )
2835 {
2836 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n",
2837 SCIPvarGetName(var));
2838 }
2839 else
2840 {
2841 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n",
2842 SCIPvarGetName(var));
2843 }
2844 }
2845 else
2846 {
2847 SCIP_CALL( retcode );
2848 }
2849 }
2850 }
2851
2852 /* free xml data */
2853 xmlFreeNode(start);
2854
2855 if( localpartial && !SCIPsolIsPartial(sol) )
2856 {
2857 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
2858 {
2859 SCIP_CALL( SCIPsolMarkPartial(sol, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) );
2860 }
2861 else
2862 *error = TRUE;
2863 }
2864
2865 if( partial != NULL )
2866 *partial = localpartial;
2867
2868 return SCIP_OKAY;
2869 }
2870
2871 /** reads a given solution file and store the solution values in the given solution pointer
2872 *
2873 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2874 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2875 *
2876 * @pre This method can be called if SCIP is in one of the following stages:
2877 * - \ref SCIP_STAGE_PROBLEM
2878 * - \ref SCIP_STAGE_TRANSFORMED
2879 * - \ref SCIP_STAGE_INITPRESOLVE
2880 * - \ref SCIP_STAGE_PRESOLVING
2881 * - \ref SCIP_STAGE_EXITPRESOLVE
2882 * - \ref SCIP_STAGE_PRESOLVED
2883 * - \ref SCIP_STAGE_INITSOLVE
2884 * - \ref SCIP_STAGE_SOLVING
2885 */
SCIPreadSolFile(SCIP * scip,const char * filename,SCIP_SOL * sol,SCIP_Bool xml,SCIP_Bool * partial,SCIP_Bool * error)2886 SCIP_RETCODE SCIPreadSolFile(
2887 SCIP* scip, /**< SCIP data structure */
2888 const char* filename, /**< name of the input file */
2889 SCIP_SOL* sol, /**< solution pointer */
2890 SCIP_Bool xml, /**< true, iff the given solution in written in XML */
2891 SCIP_Bool* partial, /**< pointer to store if the solution is partial */
2892 SCIP_Bool* error /**< pointer store if an error occured */
2893 )
2894 {
2895 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadSolFile", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2896
2897 if( xml )
2898 {
2899 SCIP_CALL( readXmlSolFile(scip, filename, sol, partial, error) );
2900 }
2901 else
2902 {
2903 SCIP_CALL( readSolFile(scip, filename, sol, partial, error) );
2904 }
2905
2906 return SCIP_OKAY;
2907 }
2908
2909 /** adds feasible primal solution to solution storage by copying it
2910 *
2911 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
2912 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
2913 *
2914 * @pre This method can be called if SCIP is in one of the following stages:
2915 * - \ref SCIP_STAGE_PROBLEM
2916 * - \ref SCIP_STAGE_TRANSFORMED
2917 * - \ref SCIP_STAGE_INITPRESOLVE
2918 * - \ref SCIP_STAGE_PRESOLVING
2919 * - \ref SCIP_STAGE_EXITPRESOLVE
2920 * - \ref SCIP_STAGE_PRESOLVED
2921 * - \ref SCIP_STAGE_SOLVING
2922 * - \ref SCIP_STAGE_FREETRANS
2923 *
2924 * @note Do not call during propagation, use heur_trysol instead.
2925 */
SCIPaddSol(SCIP * scip,SCIP_SOL * sol,SCIP_Bool * stored)2926 SCIP_RETCODE SCIPaddSol(
2927 SCIP* scip, /**< SCIP data structure */
2928 SCIP_SOL* sol, /**< primal CIP solution */
2929 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
2930 )
2931 {
2932 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE) );
2933
2934 switch( scip->set->stage )
2935 {
2936 case SCIP_STAGE_PROBLEM:
2937 case SCIP_STAGE_FREETRANS:
2938 assert(SCIPsolIsOriginal(sol));
2939 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, stored) );
2940 return SCIP_OKAY;
2941
2942 case SCIP_STAGE_TRANSFORMED:
2943 case SCIP_STAGE_INITPRESOLVE:
2944 case SCIP_STAGE_PRESOLVING:
2945 case SCIP_STAGE_EXITPRESOLVE:
2946 /* if the solution is added during presolving and it is not defined on original variables,
2947 * presolving operations will destroy its validity, so we retransform it to the original space
2948 */
2949 if( !SCIPsolIsOriginal(sol) )
2950 {
2951 SCIP_SOL* bestsol = SCIPgetBestSol(scip);
2952 SCIP_SOL* tmpsol = sol;
2953 SCIP_Bool hasinfval;
2954
2955 SCIP_CALL( SCIPcreateSolCopy(scip, &tmpsol, sol) );
2956
2957 SCIP_CALL( SCIPsolUnlink(tmpsol, scip->set, scip->transprob) );
2958 SCIP_CALL( SCIPsolRetransform(tmpsol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
2959
2960 SCIP_CALL( SCIPprimalAddSolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2961 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter,
2962 &tmpsol, stored) );
2963
2964 if( *stored && (bestsol != SCIPgetBestSol(scip)) )
2965 {
2966 SCIPstoreSolutionGap(scip);
2967 }
2968
2969 return SCIP_OKAY;
2970 }
2971 /*lint -fallthrough*/
2972 case SCIP_STAGE_PRESOLVED:
2973 case SCIP_STAGE_SOLVING:
2974 {
2975 SCIP_SOL* bestsol = SCIPgetBestSol(scip);
2976
2977 SCIP_CALL( SCIPprimalAddSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
2978 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, sol,
2979 stored) );
2980
2981 /* @todo use solution index rather than pointer */
2982 if( *stored && (bestsol != SCIPgetBestSol(scip)) )
2983 {
2984 SCIPstoreSolutionGap(scip);
2985 }
2986
2987 return SCIP_OKAY;
2988 }
2989 case SCIP_STAGE_TRANSFORMING:
2990 case SCIP_STAGE_INITSOLVE:
2991 case SCIP_STAGE_SOLVED:
2992 case SCIP_STAGE_EXITSOLVE:
2993 default:
2994 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
2995 return SCIP_INVALIDCALL;
2996 } /*lint !e788*/
2997 }
2998
2999 /** adds primal solution to solution storage, frees the solution afterwards
3000 *
3001 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3002 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3003 *
3004 * @pre This method can be called if SCIP is in one of the following stages:
3005 * - \ref SCIP_STAGE_PROBLEM
3006 * - \ref SCIP_STAGE_TRANSFORMED
3007 * - \ref SCIP_STAGE_INITPRESOLVE
3008 * - \ref SCIP_STAGE_PRESOLVING
3009 * - \ref SCIP_STAGE_EXITPRESOLVE
3010 * - \ref SCIP_STAGE_PRESOLVED
3011 * - \ref SCIP_STAGE_SOLVING
3012 * - \ref SCIP_STAGE_FREETRANS
3013 *
3014 * @note Do not call during propagation, use heur_trysol instead.
3015 */
SCIPaddSolFree(SCIP * scip,SCIP_SOL ** sol,SCIP_Bool * stored)3016 SCIP_RETCODE SCIPaddSolFree(
3017 SCIP* scip, /**< SCIP data structure */
3018 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
3019 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
3020 )
3021 {
3022 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddSolFree", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE) );
3023
3024 switch( scip->set->stage )
3025 {
3026 case SCIP_STAGE_PROBLEM:
3027 case SCIP_STAGE_FREETRANS:
3028 assert(SCIPsolIsOriginal(*sol));
3029 SCIP_CALL( SCIPprimalAddOrigSolFree(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, stored) );
3030 return SCIP_OKAY;
3031
3032 case SCIP_STAGE_TRANSFORMED:
3033 case SCIP_STAGE_INITPRESOLVE:
3034 case SCIP_STAGE_PRESOLVING:
3035 case SCIP_STAGE_EXITPRESOLVE:
3036 /* if the solution is added during presolving and it is not defined on original variables,
3037 * presolving operations will destroy its validity, so we retransform it to the original space
3038 */
3039 if( !SCIPsolIsOriginal(*sol) )
3040 {
3041 SCIP_Bool hasinfval;
3042
3043 SCIP_CALL( SCIPsolUnlink(*sol, scip->set, scip->transprob) );
3044 SCIP_CALL( SCIPsolRetransform(*sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
3045 }
3046 /*lint -fallthrough*/
3047 case SCIP_STAGE_PRESOLVED:
3048 case SCIP_STAGE_SOLVING:
3049 {
3050 SCIP_SOL* bestsol = SCIPgetBestSol(scip);
3051
3052 SCIP_CALL( SCIPprimalAddSolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3053 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter,
3054 sol, stored) );
3055
3056 if( *stored )
3057 {
3058 if( bestsol != SCIPgetBestSol(scip) )
3059 {
3060 assert(SCIPgetBestSol(scip) != NULL);
3061 SCIPstoreSolutionGap(scip);
3062 }
3063 }
3064
3065 return SCIP_OKAY;
3066 }
3067 case SCIP_STAGE_TRANSFORMING:
3068 case SCIP_STAGE_INITSOLVE:
3069 case SCIP_STAGE_SOLVED:
3070 case SCIP_STAGE_EXITSOLVE:
3071 default:
3072 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
3073 return SCIP_INVALIDCALL;
3074 } /*lint !e788*/
3075 }
3076
3077 /** adds current LP/pseudo solution to solution storage
3078 *
3079 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3080 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3081 *
3082 * @pre This method can be called if SCIP is in one of the following stages:
3083 * - \ref SCIP_STAGE_PRESOLVED
3084 * - \ref SCIP_STAGE_SOLVING
3085 */
SCIPaddCurrentSol(SCIP * scip,SCIP_HEUR * heur,SCIP_Bool * stored)3086 SCIP_RETCODE SCIPaddCurrentSol(
3087 SCIP* scip, /**< SCIP data structure */
3088 SCIP_HEUR* heur, /**< heuristic that found the solution */
3089 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
3090 )
3091 {
3092 SCIP_SOL* bestsol;
3093
3094 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3095
3096 bestsol = SCIPgetBestSol(scip);
3097
3098 SCIP_CALL( SCIPprimalAddCurrentSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3099 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, heur,
3100 stored) );
3101
3102 if( *stored )
3103 {
3104 if( bestsol != SCIPgetBestSol(scip) )
3105 SCIPstoreSolutionGap(scip);
3106 }
3107
3108 return SCIP_OKAY;
3109 }
3110
3111 /** checks solution for feasibility; if possible, adds it to storage by copying
3112 *
3113 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3114 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3115 *
3116 * @pre This method can be called if SCIP is in one of the following stages:
3117 * - \ref SCIP_STAGE_TRANSFORMED
3118 * - \ref SCIP_STAGE_INITPRESOLVE
3119 * - \ref SCIP_STAGE_PRESOLVING
3120 * - \ref SCIP_STAGE_EXITPRESOLVE
3121 * - \ref SCIP_STAGE_PRESOLVED
3122 * - \ref SCIP_STAGE_SOLVING
3123 *
3124 * @note Do not call during propagation, use heur_trysol instead.
3125 */
SCIPtrySol(SCIP * scip,SCIP_SOL * sol,SCIP_Bool printreason,SCIP_Bool completely,SCIP_Bool checkbounds,SCIP_Bool checkintegrality,SCIP_Bool checklprows,SCIP_Bool * stored)3126 SCIP_RETCODE SCIPtrySol(
3127 SCIP* scip, /**< SCIP data structure */
3128 SCIP_SOL* sol, /**< primal CIP solution */
3129 SCIP_Bool printreason, /**< Should all reasons of violation be printed? */
3130 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */
3131 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
3132 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
3133 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
3134 SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */
3135 )
3136 {
3137 SCIP_SOL* bestsol;
3138
3139 assert(sol != NULL);
3140 assert(stored != NULL);
3141
3142 SCIP_CALL( SCIPcheckStage(scip, "SCIPtrySol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3143
3144 bestsol = SCIPgetBestSol(scip);
3145
3146 if( !printreason )
3147 completely = FALSE;
3148
3149 /* we cannot check partial solutions */
3150 if( SCIPsolIsPartial(sol) )
3151 {
3152 SCIPerrorMessage("Cannot check feasibility of partial solutions.\n");
3153 return SCIP_INVALIDDATA;
3154 }
3155
3156 /* if the solution is added during presolving and it is not defined on original variables,
3157 * presolving operations will destroy its validity, so we retransform it to the original space
3158 */
3159 if( scip->set->stage == SCIP_STAGE_PRESOLVING && !SCIPsolIsOriginal(sol) )
3160 {
3161 SCIP_Bool hasinfval;
3162
3163 SCIP_CALL( SCIPsolUnlink(sol, scip->set, scip->transprob) );
3164 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
3165 }
3166
3167 if( SCIPsolIsOriginal(sol) )
3168 {
3169 SCIP_Bool feasible;
3170
3171 /* SCIPprimalTrySol() can only be called on transformed solutions; therefore check solutions in original problem
3172 * including modifiable constraints */
3173 SCIP_CALL( checkSolOrig(scip, sol, &feasible, printreason, completely, checkbounds, checkintegrality, checklprows, TRUE) );
3174 if( feasible )
3175 {
3176 SCIP_CALL( SCIPprimalAddSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3177 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter,
3178 sol, stored) );
3179
3180 if( *stored )
3181 {
3182 if( bestsol != SCIPgetBestSol(scip) )
3183 SCIPstoreSolutionGap(scip);
3184 }
3185 }
3186 else
3187 *stored = FALSE;
3188 }
3189 else
3190 {
3191 SCIP_CALL( SCIPprimalTrySol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->origprob,
3192 scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, sol, printreason,
3193 completely, checkbounds, checkintegrality, checklprows, stored) );
3194
3195 if( *stored )
3196 {
3197 if( bestsol != SCIPgetBestSol(scip) )
3198 {
3199 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS
3200 SCIP_Bool feasible;
3201 SCIP_CALL( checkSolOrig(scip, sol, &feasible, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
3202
3203 if( ! feasible )
3204 {
3205 SCIPerrorMessage("Accepted solution not feasible for original problem\n");
3206 SCIPABORT();
3207 }
3208 #endif
3209 SCIPstoreSolutionGap(scip);
3210 }
3211 }
3212 }
3213
3214 return SCIP_OKAY;
3215 }
3216
3217 /** checks primal solution; if feasible, adds it to storage; solution is freed afterwards
3218 *
3219 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3220 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3221 *
3222 * @pre This method can be called if SCIP is in one of the following stages:
3223 * - \ref SCIP_STAGE_TRANSFORMED
3224 * - \ref SCIP_STAGE_INITPRESOLVE
3225 * - \ref SCIP_STAGE_PRESOLVING
3226 * - \ref SCIP_STAGE_EXITPRESOLVE
3227 * - \ref SCIP_STAGE_PRESOLVED
3228 * - \ref SCIP_STAGE_SOLVING
3229 *
3230 * @note Do not call during propagation, use heur_trysol instead.
3231 */
SCIPtrySolFree(SCIP * scip,SCIP_SOL ** sol,SCIP_Bool printreason,SCIP_Bool completely,SCIP_Bool checkbounds,SCIP_Bool checkintegrality,SCIP_Bool checklprows,SCIP_Bool * stored)3232 SCIP_RETCODE SCIPtrySolFree(
3233 SCIP* scip, /**< SCIP data structure */
3234 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
3235 SCIP_Bool printreason, /**< Should all reasons of violations be printed */
3236 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */
3237 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
3238 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
3239 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
3240 SCIP_Bool* stored /**< stores whether solution was feasible and good enough to keep */
3241 )
3242 {
3243 SCIP_SOL* bestsol;
3244
3245 assert(stored != NULL);
3246 assert(sol != NULL);
3247
3248 SCIP_CALL( SCIPcheckStage(scip, "SCIPtrySolFree", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3249
3250 bestsol = SCIPgetBestSol(scip);
3251
3252 if( !printreason )
3253 completely = FALSE;
3254
3255 /* we cannot check partial solutions */
3256 if( SCIPsolIsPartial(*sol) )
3257 {
3258 SCIPerrorMessage("Cannot check feasibility of partial solutions.\n");
3259 return SCIP_INVALIDDATA;
3260 }
3261
3262 /* if the solution is added during presolving and it is not defined on original variables,
3263 * presolving operations will destroy its validity, so we retransform it to the original space
3264 */
3265 if( scip->set->stage == SCIP_STAGE_PRESOLVING && !SCIPsolIsOriginal(*sol) )
3266 {
3267 SCIP_Bool hasinfval;
3268
3269 SCIP_CALL( SCIPsolUnlink(*sol, scip->set, scip->transprob) );
3270 SCIP_CALL( SCIPsolRetransform(*sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) );
3271 }
3272
3273 if( SCIPsolIsOriginal(*sol) )
3274 {
3275 SCIP_Bool feasible;
3276
3277 /* SCIPprimalTrySol() can only be called on transformed solutions; therefore check solutions in original problem
3278 * including modifiable constraints
3279 */
3280 SCIP_CALL( checkSolOrig(scip, *sol, &feasible, printreason, completely, checkbounds, checkintegrality, checklprows, TRUE) );
3281
3282 if( feasible )
3283 {
3284 SCIP_CALL( SCIPprimalAddSolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3285 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter,
3286 sol, stored) );
3287
3288 if( *stored )
3289 {
3290 if( bestsol != SCIPgetBestSol(scip) )
3291 SCIPstoreSolutionGap(scip);
3292 }
3293 }
3294 else
3295 {
3296 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->primal) );
3297 *stored = FALSE;
3298 }
3299 }
3300 else
3301 {
3302 SCIP_CALL( SCIPprimalTrySolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3303 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter,
3304 sol, printreason, completely, checkbounds, checkintegrality, checklprows, stored) );
3305
3306 if( *stored )
3307 {
3308 if( bestsol != SCIPgetBestSol(scip) )
3309 {
3310 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS
3311 SCIP_Bool feasible;
3312 SCIP_CALL( checkSolOrig(scip, SCIPgetBestSol(scip), &feasible, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
3313
3314 if( ! feasible )
3315 {
3316 SCIPerrorMessage("Accepted incumbent not feasible for original problem\n");
3317 SCIPABORT();
3318 }
3319 #endif
3320 SCIPstoreSolutionGap(scip);
3321 }
3322 }
3323 }
3324
3325 return SCIP_OKAY;
3326 }
3327
3328 /** checks current LP/pseudo solution for feasibility; if possible, adds it to storage
3329 *
3330 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3331 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3332 *
3333 * @pre This method can be called if SCIP is in one of the following stages:
3334 * - \ref SCIP_STAGE_PRESOLVED
3335 * - \ref SCIP_STAGE_SOLVING
3336 */
SCIPtryCurrentSol(SCIP * scip,SCIP_HEUR * heur,SCIP_Bool printreason,SCIP_Bool completely,SCIP_Bool checkintegrality,SCIP_Bool checklprows,SCIP_Bool * stored)3337 SCIP_RETCODE SCIPtryCurrentSol(
3338 SCIP* scip, /**< SCIP data structure */
3339 SCIP_HEUR* heur, /**< heuristic that found the solution */
3340 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
3341 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */
3342 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
3343 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
3344 SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */
3345 )
3346 {
3347 SCIP_SOL* bestsol;
3348
3349 SCIP_CALL( SCIPcheckStage(scip, "SCIPtryCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
3350
3351 bestsol = SCIPgetBestSol(scip);
3352
3353 if( !printreason )
3354 completely = FALSE;
3355
3356 SCIP_CALL( SCIPprimalTryCurrentSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat,
3357 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, heur,
3358 printreason, completely, checkintegrality, checklprows, stored) );
3359
3360 if( *stored )
3361 {
3362 if( bestsol != SCIPgetBestSol(scip) )
3363 {
3364 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS
3365 SCIP_Bool feasible;
3366 SCIP_CALL( checkSolOrig(scip, SCIPgetBestSol(scip), &feasible, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
3367
3368 if( ! feasible )
3369 {
3370 SCIPerrorMessage("Accepted incumbent not feasible for original problem\n");
3371 SCIPABORT();
3372 }
3373 #endif
3374 SCIPstoreSolutionGap(scip);
3375 }
3376 }
3377
3378 return SCIP_OKAY;
3379 }
3380
3381 /** returns all partial solutions
3382 *
3383 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3384 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3385 *
3386 * @pre This method can be called if SCIP is in one of the following stages:
3387 * - \ref SCIP_STAGE_PROBLEM
3388 * - \ref SCIP_STAGE_PRESOLVING
3389 * - \ref SCIP_STAGE_SOLVING
3390 * - \ref SCIP_STAGE_SOLVED
3391 */
SCIPgetPartialSols(SCIP * scip)3392 SCIP_SOL** SCIPgetPartialSols(
3393 SCIP* scip /**< SCIP data structure */
3394 )
3395 {
3396 assert(scip != NULL);
3397
3398 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPartialSols", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3399
3400 return scip->origprimal->partialsols;
3401 }
3402
3403 /** returns number of partial solutions
3404 *
3405 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3406 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3407 *
3408 * @pre This method can be called if SCIP is in one of the following stages:
3409 * - \ref SCIP_STAGE_PROBLEM
3410 * - \ref SCIP_STAGE_PRESOLVING
3411 * - \ref SCIP_STAGE_SOLVING
3412 * - \ref SCIP_STAGE_SOLVED
3413 */
SCIPgetNPartialSols(SCIP * scip)3414 int SCIPgetNPartialSols(
3415 SCIP* scip /**< SCIP data structure */
3416 )
3417 {
3418 assert(scip != NULL);
3419
3420 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPartialSols", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3421
3422 return scip->origprimal->npartialsols;
3423 }
3424
3425 /** checks solution for feasibility without adding it to the solution store
3426 *
3427 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3428 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3429 *
3430 * @pre This method can be called if SCIP is in one of the following stages:
3431 * - \ref SCIP_STAGE_PROBLEM
3432 * - \ref SCIP_STAGE_TRANSFORMED
3433 * - \ref SCIP_STAGE_INITPRESOLVE
3434 * - \ref SCIP_STAGE_PRESOLVING
3435 * - \ref SCIP_STAGE_EXITPRESOLVE
3436 * - \ref SCIP_STAGE_PRESOLVED
3437 * - \ref SCIP_STAGE_INITSOLVE
3438 * - \ref SCIP_STAGE_SOLVING
3439 * - \ref SCIP_STAGE_SOLVED
3440 */
SCIPcheckSol(SCIP * scip,SCIP_SOL * sol,SCIP_Bool printreason,SCIP_Bool completely,SCIP_Bool checkbounds,SCIP_Bool checkintegrality,SCIP_Bool checklprows,SCIP_Bool * feasible)3441 SCIP_RETCODE SCIPcheckSol(
3442 SCIP* scip, /**< SCIP data structure */
3443 SCIP_SOL* sol, /**< primal CIP solution */
3444 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
3445 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */
3446 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
3447 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
3448 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
3449 SCIP_Bool* feasible /**< stores whether given solution is feasible */
3450 )
3451 {
3452 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3453
3454 /* return immediately if the solution is of type partial */
3455 if( SCIPsolIsPartial(sol) )
3456 {
3457 SCIPerrorMessage("Cannot check feasibility of partial solutions.");
3458 return SCIP_INVALIDDATA;
3459 }
3460
3461 /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
3462 checklprows = checklprows || scip->set->misc_exactsolve;
3463
3464 if( !printreason )
3465 completely = FALSE;
3466
3467 if( SCIPsolIsOriginal(sol) )
3468 {
3469 /* SCIPsolCheck() can only be called on transformed solutions */
3470 SCIP_CALL( checkSolOrig(scip, sol, feasible, printreason, completely, checkbounds, checkintegrality, checklprows, FALSE) );
3471 }
3472 else
3473 {
3474 SCIP_CALL( SCIPsolCheck(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->transprob,
3475 printreason, completely, checkbounds, checkintegrality, checklprows, feasible) );
3476 }
3477
3478 return SCIP_OKAY;
3479 }
3480
3481 /** checks solution for feasibility in original problem without adding it to the solution store;
3482 * this method is used to double check a solution in order to validate the presolving process
3483 *
3484 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3485 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3486 *
3487 * @pre This method can be called if SCIP is in one of the following stages:
3488 * - \ref SCIP_STAGE_PROBLEM
3489 * - \ref SCIP_STAGE_TRANSFORMED
3490 * - \ref SCIP_STAGE_INITPRESOLVE
3491 * - \ref SCIP_STAGE_PRESOLVING
3492 * - \ref SCIP_STAGE_EXITPRESOLVE
3493 * - \ref SCIP_STAGE_PRESOLVED
3494 * - \ref SCIP_STAGE_INITSOLVE
3495 * - \ref SCIP_STAGE_SOLVING
3496 * - \ref SCIP_STAGE_SOLVED
3497 */
SCIPcheckSolOrig(SCIP * scip,SCIP_SOL * sol,SCIP_Bool * feasible,SCIP_Bool printreason,SCIP_Bool completely)3498 SCIP_RETCODE SCIPcheckSolOrig(
3499 SCIP* scip, /**< SCIP data structure */
3500 SCIP_SOL* sol, /**< primal CIP solution */
3501 SCIP_Bool* feasible, /**< stores whether given solution is feasible */
3502 SCIP_Bool printreason, /**< should the reason for the violation be printed? */
3503 SCIP_Bool completely /**< Should all violations be checked if printreason is true? */
3504 )
3505 {
3506 assert(scip != NULL);
3507 assert(sol != NULL);
3508 assert(feasible != NULL);
3509
3510 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckSolOrig", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3511
3512 /* return immediately if the solution is of type partial */
3513 if( SCIPsolIsPartial(sol) )
3514 {
3515 SCIPerrorMessage("Cannot check feasibility of partial solutions.");
3516 return SCIP_INVALIDDATA;
3517 }
3518
3519 if( !printreason )
3520 completely = FALSE;
3521
3522 /* check solution in original problem; that includes bounds, integrality, and non modifiable constraints */
3523 SCIP_CALL( checkSolOrig(scip, sol, feasible, printreason, completely, TRUE, TRUE, TRUE, FALSE) );
3524
3525 return SCIP_OKAY;
3526 }
3527
3528 /** return whether a primal ray is stored that proves unboundedness of the LP relaxation
3529 *
3530 * @return return whether a primal ray is stored that proves unboundedness of the LP relaxation
3531 *
3532 * @pre This method can be called if SCIP is in one of the following stages:
3533 * - \ref SCIP_STAGE_SOLVING
3534 * - \ref SCIP_STAGE_SOLVED
3535 */
SCIPhasPrimalRay(SCIP * scip)3536 SCIP_Bool SCIPhasPrimalRay(
3537 SCIP* scip /**< SCIP data structure */
3538 )
3539 {
3540 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasPrimalRay", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3541
3542 return scip->primal->primalray != NULL;
3543 }
3544
3545 /** gets value of given variable in primal ray causing unboundedness of the LP relaxation;
3546 * should only be called if such a ray is stored (check with SCIPhasPrimalRay())
3547 *
3548 * @return value of given variable in primal ray causing unboundedness of the LP relaxation
3549 *
3550 * @pre This method can be called if SCIP is in one of the following stages:
3551 * - \ref SCIP_STAGE_SOLVING
3552 * - \ref SCIP_STAGE_SOLVED
3553 */
SCIPgetPrimalRayVal(SCIP * scip,SCIP_VAR * var)3554 SCIP_Real SCIPgetPrimalRayVal(
3555 SCIP* scip, /**< SCIP data structure */
3556 SCIP_VAR* var /**< variable to get value for */
3557 )
3558 {
3559 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPrimalRayVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3560
3561 assert(var != NULL);
3562 assert(scip->primal->primalray != NULL);
3563 assert(var->scip == scip);
3564
3565 return SCIPsolGetRayVal(scip->primal->primalray, scip->set, scip->stat, var);
3566 }
3567
3568 /** updates the primal ray thats proves unboundedness
3569 *
3570 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
3571 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
3572 *
3573 * @pre This method can be called if @p scip is in one of the following stages:
3574 * - \ref SCIP_STAGE_PRESOLVING
3575 * - \ref SCIP_STAGE_PRESOLVED
3576 * - \ref SCIP_STAGE_SOLVING
3577 * - \ref SCIP_STAGE_SOLVED
3578 *
3579 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
3580 */
SCIPupdatePrimalRay(SCIP * scip,SCIP_SOL * primalray)3581 SCIP_RETCODE SCIPupdatePrimalRay(
3582 SCIP* scip, /**< SCIP data structure */
3583 SCIP_SOL* primalray /**< the new primal ray */
3584 )
3585 {
3586 assert(scip != NULL);
3587 assert(primalray != NULL);
3588
3589 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdatePrimalRay", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
3590
3591 SCIP_CALL( SCIPprimalUpdateRay(scip->primal, scip->set, scip->stat, primalray, scip->mem->probmem) );
3592
3593 return SCIP_OKAY;
3594 }
3595