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