Scippy

SCIP

Solving Constraint Integer Programs

sol.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2014 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file sol.c
17  * @brief methods for storing primal CIP solutions
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 
25 #include "scip/def.h"
26 #include "scip/set.h"
27 #include "scip/stat.h"
28 #include "scip/clock.h"
29 #include "scip/misc.h"
30 #include "scip/lp.h"
31 #include "scip/nlp.h"
32 #include "scip/relax.h"
33 #include "scip/var.h"
34 #include "scip/prob.h"
35 #include "scip/sol.h"
36 #include "scip/primal.h"
37 #include "scip/tree.h"
38 #include "scip/cons.h"
39 #include "scip/pub_message.h"
40 
41 #ifndef NDEBUG
42 #include "scip/struct_sol.h"
43 #endif
44 
45 
46 
47 /** clears solution arrays of primal CIP solution */
48 static
50  SCIP_SOL* sol /**< primal CIP solution */
51  )
52 {
53  assert(sol != NULL);
54 
56  sol->hasinfval = FALSE;
57 
58  return SCIP_OKAY;
59 }
60 
61 /** sets value of variable in the solution's array */
62 static
64  SCIP_SOL* sol, /**< primal CIP solution */
65  SCIP_SET* set, /**< global SCIP settings */
66  SCIP_VAR* var, /**< problem variable */
67  SCIP_Real val /**< value to set variable to */
68  )
69 {
70  int idx;
71 
72  assert(sol != NULL);
73 
74  idx = SCIPvarGetIndex(var);
75 
76  /* from now on, variable must not be deleted */
78 
79  /* mark the variable valid */
81 
82  /* set the value in the solution array */
84 
85  /* store whether the solution has infinite values assigned to variables */
86  if( val != SCIP_UNKNOWN ) /*lint !e777*/
87  sol->hasinfval = (sol->hasinfval || SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val));
88 
89  return SCIP_OKAY;
90 }
91 
92 /** increases value of variable in the solution's array */
93 static
95  SCIP_SOL* sol, /**< primal CIP solution */
96  SCIP_SET* set, /**< global SCIP settings */
97  SCIP_VAR* var, /**< problem variable */
98  SCIP_Real incval /**< increase of variable's solution value */
99  )
100 {
101  int idx;
102 
103  assert(sol != NULL);
104 
105  idx = SCIPvarGetIndex(var);
106 
107  /* from now on, variable must not be deleted */
109 
110  /* if the variable was not valid, mark it to be valid and set the value to the incval (it is 0.0 if not valid) */
111  if( !SCIPboolarrayGetVal(sol->valid, idx) )
112  {
113  /* mark the variable valid */
115 
116  /* set the value in the solution array */
117  SCIP_CALL( SCIPrealarraySetVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, incval) );
118  }
119  else
120  {
121  /* increase the value in the solution array */
122  SCIP_CALL( SCIPrealarrayIncVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, incval) );
123  }
124 
125  /* store whether the solution has infinite values assigned to variables */
126  incval = SCIPrealarrayGetVal(sol->vals, idx);
127  if( incval != SCIP_UNKNOWN ) /*lint !e777*/
128  sol->hasinfval = (sol->hasinfval || SCIPsetIsInfinity(set, incval) || SCIPsetIsInfinity(set, -incval));
129 
130  return SCIP_OKAY;
131 }
132 
133 /** returns the value of the variable in the given solution */
134 static
136  SCIP_SOL* sol, /**< primal CIP solution */
137  SCIP_VAR* var /**< problem variable */
138  )
139 {
140  int idx;
141 
142  assert(sol != NULL);
143 
144  idx = SCIPvarGetIndex(var);
145 
146  /* check, if the variable's value is valid */
147  if( SCIPboolarrayGetVal(sol->valid, idx) )
148  {
149  return SCIPrealarrayGetVal(sol->vals, idx);
150  }
151  else
152  {
153  /* return the variable's value corresponding to the origin */
154  switch( sol->solorigin )
155  {
157  case SCIP_SOLORIGIN_ZERO:
158  return 0.0;
159 
161  return SCIPvarGetLPSol(var);
162 
164  return SCIPvarGetNLPSol(var);
165 
167  return SCIPvarGetRelaxSolTransVar(var);
168 
170  return SCIPvarGetPseudoSol(var);
171 
173  return SCIP_UNKNOWN;
174 
175  default:
176  SCIPerrorMessage("unknown solution origin <%d>\n", sol->solorigin);
177  SCIPABORT();
178  return 0.0; /*lint !e527*/
179  }
180  }
181 }
182 
183 /** stores solution value of variable in solution's own array */
184 static
186  SCIP_SOL* sol, /**< primal CIP solution */
187  SCIP_SET* set, /**< global SCIP settings */
188  SCIP_VAR* var /**< problem variable */
189  )
190 {
191  SCIP_Real solval;
192 
193  assert(sol != NULL);
194  assert(var != NULL);
195  assert(SCIPvarIsTransformed(var));
197 
198  /* if variable is already valid, nothing has to be done */
199  if( SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var)) )
200  return SCIP_OKAY;
201 
202  SCIPdebugMessage("unlinking solution value of variable <%s>\n", SCIPvarGetName(var));
203 
204  /* store the correct solution value into the solution array */
205  switch( sol->solorigin )
206  {
208  SCIPerrorMessage("cannot unlink solutions of original problem space\n");
209  return SCIP_INVALIDDATA;
210 
211  case SCIP_SOLORIGIN_ZERO:
212  return SCIP_OKAY;
213 
215  solval = SCIPvarGetLPSol(var);
216  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
217  return SCIP_OKAY;
218 
220  solval = SCIPvarGetNLPSol(var);
221  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
222  return SCIP_OKAY;
223 
225  solval = SCIPvarGetRelaxSolTransVar(var);
226  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
227  return SCIP_OKAY;
228 
230  solval = SCIPvarGetPseudoSol(var);
231  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
232  return SCIP_OKAY;
233 
235  SCIP_CALL( solSetArrayVal(sol, set, var, SCIP_UNKNOWN) );
236  return SCIP_OKAY;
237 
238  default:
239  SCIPerrorMessage("unknown solution origin <%d>\n", sol->solorigin);
240  return SCIP_INVALIDDATA;
241  }
242 }
243 
244 /** sets the solution time, nodenum, runnum, and depth stamp to the current values */
245 static
246 void solStamp(
247  SCIP_SOL* sol, /**< primal CIP solution */
248  SCIP_STAT* stat, /**< problem statistics data */
249  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
250  SCIP_Bool checktime /**< should the time be updated? */
251  )
252 {
253  assert(sol != NULL);
254  assert(stat != NULL);
255 
256  if( checktime )
257  sol->time = SCIPclockGetTime(stat->solvingtime);
258  else
259  sol->time = SCIPclockGetLastTime(stat->solvingtime);
260  sol->nodenum = stat->nnodes;
261  sol->runnum = stat->nruns;
262  if( tree == NULL )
263  sol->depth = -1;
264  else
265  sol->depth = SCIPtreeGetCurrentDepth(tree);
266 }
267 
268 /** creates primal CIP solution, initialized to zero */
270  SCIP_SOL** sol, /**< pointer to primal CIP solution */
271  BMS_BLKMEM* blkmem, /**< block memory */
272  SCIP_SET* set, /**< global SCIP settings */
273  SCIP_STAT* stat, /**< problem statistics data */
274  SCIP_PRIMAL* primal, /**< primal data */
275  SCIP_TREE* tree, /**< branch and bound tree */
276  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
277  )
278 {
279  assert(sol != NULL);
280  assert(blkmem != NULL);
281  assert(stat != NULL);
282 
283  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
284  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
285  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
286  (*sol)->heur = heur;
287  (*sol)->solorigin = SCIP_SOLORIGIN_ZERO;
288  (*sol)->obj = 0.0;
289  (*sol)->primalindex = -1;
290  (*sol)->index = stat->solindex;
291  (*sol)->hasinfval = FALSE;
292  stat->solindex++;
293  solStamp(*sol, stat, tree, TRUE);
294 
295  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
296 
297  return SCIP_OKAY;
298 }
299 
300 /** creates primal CIP solution in original problem space, initialized to the offset in the original problem */
302  SCIP_SOL** sol, /**< pointer to primal CIP solution */
303  BMS_BLKMEM* blkmem, /**< block memory */
304  SCIP_SET* set, /**< global SCIP settings */
305  SCIP_STAT* stat, /**< problem statistics data */
306  SCIP_PROB* origprob, /**< original problem data */
307  SCIP_PRIMAL* primal, /**< primal data */
308  SCIP_TREE* tree, /**< branch and bound tree */
309  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
310  )
311 {
312  assert(sol != NULL);
313  assert(blkmem != NULL);
314  assert(stat != NULL);
315 
316  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
317  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
318  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
319  (*sol)->heur = heur;
320  (*sol)->solorigin = SCIP_SOLORIGIN_ORIGINAL;
321  (*sol)->obj = origprob->objoffset;
322  (*sol)->primalindex = -1;
323  (*sol)->index = stat->solindex;
324  (*sol)->hasinfval = FALSE;
325  stat->solindex++;
326  solStamp(*sol, stat, tree, TRUE);
327 
328  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
329 
330  return SCIP_OKAY;
331 }
332 
333 /** creates a copy of a primal CIP solution */
335  SCIP_SOL** sol, /**< pointer to store the copy of the primal CIP solution */
336  BMS_BLKMEM* blkmem, /**< block memory */
337  SCIP_SET* set, /**< global SCIP settings */
338  SCIP_STAT* stat, /**< problem statistics data */
339  SCIP_PRIMAL* primal, /**< primal data */
340  SCIP_SOL* sourcesol /**< primal CIP solution to copy */
341  )
342 {
343  assert(sol != NULL);
344  assert(sourcesol != NULL);
345 
346  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
347  SCIP_CALL( SCIPrealarrayCopy(&(*sol)->vals, blkmem, sourcesol->vals) );
348  SCIP_CALL( SCIPboolarrayCopy(&(*sol)->valid, blkmem, sourcesol->valid) );
349  (*sol)->heur = sourcesol->heur;
350  (*sol)->obj = sourcesol->obj;
351  (*sol)->primalindex = -1;
352  (*sol)->time = sourcesol->time;
353  (*sol)->nodenum = sourcesol->nodenum;
354  (*sol)->solorigin = sourcesol->solorigin;
355  (*sol)->runnum = sourcesol->runnum;
356  (*sol)->depth = sourcesol->depth;
357  (*sol)->index = stat->solindex;
358  (*sol)->hasinfval = sourcesol->hasinfval;
359  stat->solindex++;
360 
361  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
362 
363  return SCIP_OKAY;
364 }
365 
366 /** transformes given original solution to the transformed space; a corresponding transformed solution has to be given
367  * which is copied into the existing solution and freed afterwards
368  */
370  SCIP_SOL* sol, /**< primal CIP solution to change, living in original space */
371  SCIP_SOL** transsol, /**< pointer to corresponding transformed primal CIP solution */
372  BMS_BLKMEM* blkmem, /**< block memory */
373  SCIP_SET* set, /**< global SCIP settings */
374  SCIP_PRIMAL* primal /**< primal data */
375  )
376 { /*lint --e{715}*/
377  SCIP_REALARRAY* tmpvals;
378  SCIP_BOOLARRAY* tmpvalid;
379  SCIP_SOL* tsol;
380 
381  assert(sol != NULL);
382  assert(transsol != NULL);
383  assert(SCIPsolIsOriginal(sol));
384  assert(sol->primalindex > -1);
385 
386  tsol = *transsol;
387  assert(tsol != NULL);
388  assert(!SCIPsolIsOriginal(tsol));
389 
390  /* switch vals and valid arrays; the exisiting solution gets the arrays of the transformed solution;
391  * the transformed one gets the original arrays, because they have to be freed anyway and freeing the transsol
392  * automatically frees its arrays
393  */
394  tmpvals = sol->vals;
395  tmpvalid = sol->valid;
396  sol->vals = tsol->vals;
397  sol->valid = tsol->valid;
398  tsol->vals = tmpvals;
399  tsol->valid = tmpvalid;
400 
401  /* copy solorigin and objective (should be the same, only to avoid numerical issues);
402  * we keep the other statistics of the original solution, since that was the first time that this solution as found
403  */
404  sol->solorigin = tsol->solorigin;
405  sol->obj = tsol->obj;
406 
407  SCIP_CALL( SCIPsolFree(transsol, blkmem, primal) );
408 
409  return SCIP_OKAY;
410 }
411 
412 /** adjusts solution values of implicit integer variables in handed solution. Solution objective value is not
413  * deteriorated by this method.
414  */
416  SCIP_SOL* sol, /**< primal CIP solution */
417  SCIP_SET* set, /**< global SCIP settings */
418  SCIP_STAT* stat, /**< problem statistics data */
419  SCIP_PROB* prob, /**< either original or transformed problem, depending on sol origin */
420  SCIP_TREE* tree, /**< branch and bound tree */
421  SCIP_Bool uselprows /**< should LP row information be considered for none-objective variables */
422  )
423 {
424  SCIP_VAR** vars;
425  int nimplvars;
426  int nbinvars;
427  int nintvars;
428  int v;
429 
430  assert(sol != NULL);
431  assert(prob != NULL);
432 
433  /* get variable data */
434  vars = SCIPprobGetVars(prob);
435  nbinvars = SCIPprobGetNBinVars(prob);
436  nintvars = SCIPprobGetNIntVars(prob);
437  nimplvars = SCIPprobGetNImplVars(prob);
438 
439  if( nimplvars == 0 )
440  return SCIP_OKAY;
441 
442  /* calculate the last array position of implicit integer variables */
443  nimplvars = nbinvars + nintvars + nimplvars;
444 
445  /* loop over implicit integer variables and round them up or down */
446  for( v = nbinvars + nintvars; v < nimplvars; ++v )
447  {
448  SCIP_VAR* var;
449  SCIP_Real solval;
450  SCIP_Real obj;
451  SCIP_Real newsolval;
452  SCIP_Bool roundup;
453  SCIP_Bool rounddown;
454  int nuplocks;
455  int ndownlocks;
456 
457  var = vars[v];
458 
459  assert( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT );
460  solval = SCIPsolGetVal(sol, set, stat, var);
461 
462  /* we do not need to round integral solution values or those of variables which are not column variables */
463  if( SCIPsetIsFeasIntegral(set, solval) || SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN )
464  continue;
465 
466  nuplocks = SCIPvarGetNLocksUp(var);
467  ndownlocks = SCIPvarGetNLocksDown(var);
468  obj = SCIPvarGetObj(var);
469 
470  roundup = FALSE;
471  rounddown = FALSE;
472 
473  /* in case of a non-zero objective coefficient, there is only one possible rounding direction */
474  if( SCIPsetIsFeasNegative(set, obj) )
475  roundup = TRUE;
476  else if( SCIPsetIsFeasPositive(set, obj) )
477  rounddown = TRUE;
478  else if( uselprows )
479  {
480  /* determine rounding direction based on row violations */
481  SCIP_COL* col;
482  SCIP_ROW** rows;
483  SCIP_Real* vals;
484  int nrows;
485  int r;
486 
487  col = SCIPvarGetCol(var);
488  vals = SCIPcolGetVals(col);
489  rows = SCIPcolGetRows(col);
490  nrows = SCIPcolGetNNonz(col);
491 
492  /* loop over rows and search for equations whose violation can be decreased by rounding */
493  for( r = 0; r < nrows && !(roundup && rounddown); ++r )
494  {
495  SCIP_ROW* row;
496  SCIP_Real activity;
497  SCIP_Real rhs;
498  SCIP_Real lhs;
499 
500  row = rows[r];
501  assert(!SCIPsetIsFeasZero(set, vals[r]));
502 
503  if( SCIProwIsLocal(row) || !SCIProwIsInLP(row) )
504  continue;
505 
506  rhs = SCIProwGetRhs(row);
507  lhs = SCIProwGetLhs(row);
508 
509  if( SCIPsetIsInfinity(set, rhs) || SCIPsetIsInfinity(set, -lhs) )
510  continue;
511 
512  activity = SCIProwGetSolActivity(row, set, stat, sol);
513  if( SCIPsetIsFeasLE(set, activity, rhs) && SCIPsetIsFeasLE(set, lhs, activity) )
514  continue;
515 
516  if( (SCIPsetIsFeasGT(set, activity, rhs) && SCIPsetIsPositive(set, vals[r]))
517  || (SCIPsetIsFeasLT(set, activity, lhs) && SCIPsetIsNegative(set, vals[r])) )
518  rounddown = TRUE;
519  else
520  roundup = TRUE;
521  }
522  }
523 
524  /* in case of a tie, we select the rounding step based on the number of variable locks */
525  if( roundup == rounddown )
526  {
527  rounddown = ndownlocks <= nuplocks;
528  roundup = !rounddown;
529  }
530 
531  /* round the variable up or down */
532  if( roundup )
533  {
534  newsolval = SCIPsetCeil(set, solval);
535  assert(SCIPsetIsFeasLE(set, newsolval, SCIPvarGetUbGlobal(var)));
536  }
537  else
538  {
539  assert( rounddown ); /* should be true because of the code above */
540  newsolval = SCIPsetFloor(set, solval);
541  assert(SCIPsetIsFeasGE(set, newsolval, SCIPvarGetLbGlobal(var)));
542  }
543 
544  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, newsolval) );
545  }
546 
547  return SCIP_OKAY;
548 }
549 /** creates primal CIP solution, initialized to the current LP solution */
551  SCIP_SOL** sol, /**< pointer to primal CIP solution */
552  BMS_BLKMEM* blkmem, /**< block memory */
553  SCIP_SET* set, /**< global SCIP settings */
554  SCIP_STAT* stat, /**< problem statistics data */
555  SCIP_PROB* prob, /**< transformed problem data */
556  SCIP_PRIMAL* primal, /**< primal data */
557  SCIP_TREE* tree, /**< branch and bound tree */
558  SCIP_LP* lp, /**< current LP data */
559  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
560  )
561 {
562  assert(sol != NULL);
563  assert(lp != NULL);
564  assert(SCIPlpIsSolved(lp));
565 
566  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
567  SCIP_CALL( SCIPsolLinkLPSol(*sol, set, stat, prob, tree, lp) );
568 
569  return SCIP_OKAY;
570 }
571 
572 /** creates primal CIP solution, initialized to the current NLP solution */
574  SCIP_SOL** sol, /**< pointer to primal CIP solution */
575  BMS_BLKMEM* blkmem, /**< block memory */
576  SCIP_SET* set, /**< global SCIP settings */
577  SCIP_STAT* stat, /**< problem statistics data */
578  SCIP_PRIMAL* primal, /**< primal data */
579  SCIP_TREE* tree, /**< branch and bound tree */
580  SCIP_NLP* nlp, /**< current NLP data */
581  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
582  )
583 {
584  assert(sol != NULL);
585  assert(nlp != NULL);
586 
587  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
588  SCIP_CALL( SCIPsolLinkNLPSol(*sol, stat, tree, nlp) );
589 
590  return SCIP_OKAY;
591 }
592 
593 /** creates primal CIP solution, initialized to the current relaxation solution */
595  SCIP_SOL** sol, /**< pointer to primal CIP solution */
596  BMS_BLKMEM* blkmem, /**< block memory */
597  SCIP_SET* set, /**< global SCIP settings */
598  SCIP_STAT* stat, /**< problem statistics data */
599  SCIP_PRIMAL* primal, /**< primal data */
600  SCIP_TREE* tree, /**< branch and bound tree */
601  SCIP_RELAXATION* relaxation, /**< global relaxation data */
602  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
603  )
604 {
605  assert(sol != NULL);
606  assert(relaxation != NULL);
607  assert(SCIPrelaxationIsSolValid(relaxation));
608 
609  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
610  SCIP_CALL( SCIPsolLinkRelaxSol(*sol, set, stat, tree, relaxation) );
611 
612  return SCIP_OKAY;
613 }
614 
615 /** creates primal CIP solution, initialized to the current pseudo solution */
617  SCIP_SOL** sol, /**< pointer to primal CIP solution */
618  BMS_BLKMEM* blkmem, /**< block memory */
619  SCIP_SET* set, /**< global SCIP settings */
620  SCIP_STAT* stat, /**< problem statistics data */
621  SCIP_PROB* prob, /**< transformed problem data */
622  SCIP_PRIMAL* primal, /**< primal data */
623  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
624  SCIP_LP* lp, /**< current LP data */
625  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
626  )
627 {
628  assert(sol != NULL);
629 
630  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
631  SCIP_CALL( SCIPsolLinkPseudoSol(*sol, set, stat, prob, tree, lp) );
632 
633  return SCIP_OKAY;
634 }
635 
636 /** creates primal CIP solution, initialized to the current solution */
638  SCIP_SOL** sol, /**< pointer to primal CIP solution */
639  BMS_BLKMEM* blkmem, /**< block memory */
640  SCIP_SET* set, /**< global SCIP settings */
641  SCIP_STAT* stat, /**< problem statistics data */
642  SCIP_PROB* prob, /**< transformed problem data */
643  SCIP_PRIMAL* primal, /**< primal data */
644  SCIP_TREE* tree, /**< branch and bound tree */
645  SCIP_LP* lp, /**< current LP data */
646  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
647  )
648 {
649  assert(tree != NULL);
650 
651  if( SCIPtreeHasCurrentNodeLP(tree) )
652  {
653  SCIP_CALL( SCIPsolCreateLPSol(sol, blkmem, set, stat, prob, primal, tree, lp, heur) );
654  }
655  else
656  {
657  SCIP_CALL( SCIPsolCreatePseudoSol(sol, blkmem, set, stat, prob, primal, tree, lp, heur) );
658  }
659 
660  return SCIP_OKAY;
661 }
662 
663 /** creates primal CIP solution, initialized to unknown values */
665  SCIP_SOL** sol, /**< pointer to primal CIP solution */
666  BMS_BLKMEM* blkmem, /**< block memory */
667  SCIP_SET* set, /**< global SCIP settings */
668  SCIP_STAT* stat, /**< problem statistics data */
669  SCIP_PRIMAL* primal, /**< primal data */
670  SCIP_TREE* tree, /**< branch and bound tree */
671  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
672  )
673 {
674  assert(sol != NULL);
675  assert(blkmem != NULL);
676  assert(stat != NULL);
677 
678  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
679  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
680  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
681  (*sol)->heur = heur;
682  (*sol)->solorigin = SCIP_SOLORIGIN_UNKNOWN;
683  (*sol)->obj = 0.0;
684  (*sol)->primalindex = -1;
685  (*sol)->index = stat->solindex;
686  (*sol)->hasinfval = FALSE;
687  stat->solindex++;
688  solStamp(*sol, stat, tree, TRUE);
689 
690  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
691 
692  return SCIP_OKAY;
693 }
694 
695 /** frees primal CIP solution */
697  SCIP_SOL** sol, /**< pointer to primal CIP solution */
698  BMS_BLKMEM* blkmem, /**< block memory */
699  SCIP_PRIMAL* primal /**< primal data */
700  )
701 {
702  assert(sol != NULL);
703  assert(*sol != NULL);
704 
705  SCIPprimalSolFreed(primal, *sol);
706 
707  SCIP_CALL( SCIPrealarrayFree(&(*sol)->vals) );
708  SCIP_CALL( SCIPboolarrayFree(&(*sol)->valid) );
709  BMSfreeBlockMemory(blkmem, sol);
710 
711  return SCIP_OKAY;
712 }
713 
714 /** copies current LP solution into CIP solution by linking */
716  SCIP_SOL* sol, /**< primal CIP solution */
717  SCIP_SET* set, /**< global SCIP settings */
718  SCIP_STAT* stat, /**< problem statistics data */
719  SCIP_PROB* prob, /**< transformed problem data */
720  SCIP_TREE* tree, /**< branch and bound tree */
721  SCIP_LP* lp /**< current LP data */
722  )
723 {
724  assert(sol != NULL);
725  assert(stat != NULL);
726  assert(tree != NULL);
727  assert(lp != NULL);
728  assert(lp->solved);
729  assert(SCIPlpDiving(lp) || !SCIPlpDivingObjChanged(lp));
730 
731  SCIPdebugMessage("linking solution to LP\n");
732 
733  /* clear the old solution arrays */
734  SCIP_CALL( solClearArrays(sol) );
735 
736  /* link solution to LP solution */
737  if( SCIPlpDivingObjChanged(lp) )
738  {
739  /* the objective value has to be calculated manually, because the LP's value is invalid;
740  * use objective values of variables, because columns objective values are changed to dive values
741  */
742  sol->obj = SCIPlpGetLooseObjval(lp, set, prob);
743  if( !SCIPsetIsInfinity(set, -sol->obj) )
744  {
745  SCIP_VAR* var;
746  SCIP_COL** cols;
747  int ncols;
748  int c;
749 
750  cols = SCIPlpGetCols(lp);
751  ncols = SCIPlpGetNCols(lp);
752  for( c = 0; c < ncols; ++c )
753  {
754  var = SCIPcolGetVar(cols[c]);
755  sol->obj += SCIPvarGetObj(var) * cols[c]->primsol;
756  }
757  }
758  }
759  else
760  {
761  /* the objective value in the columns is correct, s.t. the LP's objective value is also correct */
762  sol->obj = SCIPlpGetObjval(lp, set, prob);
763  }
765  solStamp(sol, stat, tree, TRUE);
766 
767  SCIPdebugMessage(" -> objective value: %g\n", sol->obj);
768 
769  return SCIP_OKAY;
770 }
771 
772 /** copies current NLP solution into CIP solution by linking */
774  SCIP_SOL* sol, /**< primal CIP solution */
775  SCIP_STAT* stat, /**< problem statistics data */
776  SCIP_TREE* tree, /**< branch and bound tree */
777  SCIP_NLP* nlp /**< current NLP data */
778  )
779 {
780  assert(sol != NULL);
781  assert(stat != NULL);
782  assert(tree != NULL);
783  assert(nlp != NULL);
785 
786  SCIPdebugMessage("linking solution to NLP\n");
787 
788  /* clear the old solution arrays */
789  SCIP_CALL( solClearArrays(sol) );
790 
791  /* get objective value of NLP solution */
792  if( SCIPnlpIsDivingObjChanged(nlp) )
793  {
794  /* the objective value has to be calculated manually, because the NLP's value is invalid */
795 
796  SCIP_VAR** vars;
797  int nvars;
798  int v;
799 
800  sol->obj = 0.0;
801 
802  vars = SCIPnlpGetVars(nlp);
803  nvars = SCIPnlpGetNVars(nlp);
804  for( v = 0; v < nvars; ++v )
805  {
806  assert(SCIPvarIsActive(vars[v]));
807  sol->obj += SCIPvarGetObj(vars[v]) * SCIPvarGetNLPSol(vars[v]);
808  }
809  }
810  else
811  {
812  sol->obj = SCIPnlpGetObjval(nlp);
813  }
814 
816  solStamp(sol, stat, tree, TRUE);
817 
818  SCIPdebugMessage(" -> objective value: %g\n", sol->obj);
819 
820  return SCIP_OKAY;
821 }
822 
823 /** copies current relaxation solution into CIP solution by linking */
825  SCIP_SOL* sol, /**< primal CIP solution */
826  SCIP_SET* set, /**< global SCIP settings */
827  SCIP_STAT* stat, /**< problem statistics data */
828  SCIP_TREE* tree, /**< branch and bound tree */
829  SCIP_RELAXATION* relaxation /**< global relaxation data */
830  )
831 { /*lint --e{715}*/
832  assert(sol != NULL);
833  assert(stat != NULL);
834  assert(tree != NULL);
835  assert(relaxation != NULL);
836  assert(SCIPrelaxationIsSolValid(relaxation));
837 
838  SCIPdebugMessage("linking solution to relaxation\n");
839 
840  /* clear the old solution arrays */
841  SCIP_CALL( solClearArrays(sol) );
842 
843  /* the objective value in the columns is correct, s.t. the LP's objective value is also correct */
844  sol->obj = SCIPrelaxationGetSolObj(relaxation);
846  solStamp(sol, stat, tree, TRUE);
847 
848  SCIPdebugMessage(" -> objective value: %g\n", sol->obj);
849 
850  return SCIP_OKAY;
851 }
852 
853 /** copies current pseudo solution into CIP solution by linking */
855  SCIP_SOL* sol, /**< primal CIP solution */
856  SCIP_SET* set, /**< global SCIP settings */
857  SCIP_STAT* stat, /**< problem statistics data */
858  SCIP_PROB* prob, /**< transformed problem data */
859  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
860  SCIP_LP* lp /**< current LP data */
861  )
862 {
863  assert(sol != NULL);
864  assert(stat != NULL);
865  assert(tree != NULL);
866 
867  SCIPdebugMessage("linking solution to pseudo solution\n");
868 
869  /* clear the old solution arrays */
870  SCIP_CALL( solClearArrays(sol) );
871 
872  /* link solution to pseudo solution */
873  sol->obj = SCIPlpGetPseudoObjval(lp, set, prob);
875  solStamp(sol, stat, tree, TRUE);
876 
877  SCIPdebugMessage(" -> objective value: %g\n", sol->obj);
878 
879  return SCIP_OKAY;
880 }
881 
882 /** copies current solution (LP or pseudo solution) into CIP solution by linking */
884  SCIP_SOL* sol, /**< primal CIP solution */
885  SCIP_SET* set, /**< global SCIP settings */
886  SCIP_STAT* stat, /**< problem statistics data */
887  SCIP_PROB* prob, /**< transformed problem data */
888  SCIP_TREE* tree, /**< branch and bound tree */
889  SCIP_LP* lp /**< current LP data */
890  )
891 {
892  assert(tree != NULL);
893 
894  SCIPdebugMessage("linking solution to current solution\n");
895 
896  if( SCIPtreeHasCurrentNodeLP(tree) && SCIPlpIsSolved(lp) )
897  {
898  SCIP_CALL( SCIPsolLinkLPSol(sol, set, stat, prob, tree, lp) );
899  }
900  else
901  {
902  SCIP_CALL( SCIPsolLinkPseudoSol(sol, set, stat, prob, tree, lp) );
903  }
904 
905  return SCIP_OKAY;
906 }
907 
908 /** clears primal CIP solution */
910  SCIP_SOL* sol, /**< primal CIP solution */
911  SCIP_STAT* stat, /**< problem statistics data */
912  SCIP_TREE* tree /**< branch and bound tree */
913  )
914 {
915  assert(sol != NULL);
916 
917  SCIP_CALL( solClearArrays(sol) );
919  sol->obj = 0.0;
920  solStamp(sol, stat, tree, TRUE);
921 
922  return SCIP_OKAY;
923 }
924 
925 /** declares all entries in the primal CIP solution to be unknown */
927  SCIP_SOL* sol, /**< primal CIP solution */
928  SCIP_STAT* stat, /**< problem statistics data */
929  SCIP_TREE* tree /**< branch and bound tree */
930  )
931 {
932  assert(sol != NULL);
933 
934  SCIP_CALL( solClearArrays(sol) );
936  sol->obj = 0.0;
937  solStamp(sol, stat, tree, TRUE);
938 
939  return SCIP_OKAY;
940 }
941 
942 /** stores solution values of variables in solution's own array */
944  SCIP_SOL* sol, /**< primal CIP solution */
945  SCIP_SET* set, /**< global SCIP settings */
946  SCIP_PROB* prob /**< transformed problem data */
947  )
948 {
949  int v;
950 
951  assert(sol != NULL);
952  assert(prob != NULL);
953  assert(prob->nvars == 0 || prob->vars != NULL);
954 
955  if( !SCIPsolIsOriginal(sol) && sol->solorigin != SCIP_SOLORIGIN_ZERO
956  && sol->solorigin != SCIP_SOLORIGIN_UNKNOWN )
957  {
958  SCIPdebugMessage("completing solution %p\n", (void*)sol);
959 
960  for( v = 0; v < prob->nvars; ++v )
961  {
962  SCIP_CALL( solUnlinkVar(sol, set, prob->vars[v]) );
963  }
964 
966  }
967 
968  return SCIP_OKAY;
969 }
970 
971 /** sets value of variable in primal CIP solution */
973  SCIP_SOL* sol, /**< primal CIP solution */
974  SCIP_SET* set, /**< global SCIP settings */
975  SCIP_STAT* stat, /**< problem statistics data */
976  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
977  SCIP_VAR* var, /**< variable to add to solution */
978  SCIP_Real val /**< solution value of variable */
979  )
980 {
981  SCIP_Real oldval;
982 
983  assert(sol != NULL);
984  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
985  || sol->solorigin == SCIP_SOLORIGIN_ZERO
987  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
988  assert(stat != NULL);
989  assert(var != NULL);
990  assert(SCIPisFinite(val));
991 
992  SCIPdebugMessage("setting value of <%s> in solution %p to %g\n", SCIPvarGetName(var), (void*)sol, val);
993 
994  /* we want to store only values for non fixed variables (LOOSE or COLUMN); others have to be transformed */
995  switch( SCIPvarGetStatus(var) )
996  {
998  if( SCIPsolIsOriginal(sol) )
999  {
1000  oldval = solGetArrayVal(sol, var);
1001  if( !SCIPsetIsEQ(set, val, oldval) )
1002  {
1003  SCIP_Real obj;
1004 
1005  SCIP_CALL( solSetArrayVal(sol, set, var, val) );
1006 
1007  /* update objective: an unknown solution value does not count towards the objective */
1008  obj = SCIPvarGetObj(var);
1009  if( oldval != SCIP_UNKNOWN ) /*lint !e777*/
1010  sol->obj -= obj * oldval;
1011  if( val != SCIP_UNKNOWN ) /*lint !e777*/
1012  sol->obj += obj * val;
1013 
1014  solStamp(sol, stat, tree, FALSE);
1015 
1016  }
1017  return SCIP_OKAY;
1018  }
1019  else
1020  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetTransVar(var), val);
1021 
1022  case SCIP_VARSTATUS_LOOSE:
1023  case SCIP_VARSTATUS_COLUMN:
1024  assert(!SCIPsolIsOriginal(sol));
1025  oldval = solGetArrayVal(sol, var);
1026  if( !SCIPsetIsEQ(set, val, oldval) )
1027  {
1028  SCIP_Real obj;
1029 
1030  SCIP_CALL( solSetArrayVal(sol, set, var, val) );
1031 
1032  /* update objective: an unknown solution value does not count towards the objective */
1033  obj = SCIPvarGetObj(var);
1034  if( oldval != SCIP_UNKNOWN ) /*lint !e777*/
1035  sol->obj -= obj * oldval;
1036  if( val != SCIP_UNKNOWN ) /*lint !e777*/
1037  sol->obj += obj * val;
1038 
1039  solStamp(sol, stat, tree, FALSE);
1040  }
1041  return SCIP_OKAY;
1042 
1043  case SCIP_VARSTATUS_FIXED:
1044  assert(!SCIPsolIsOriginal(sol));
1045  oldval = SCIPvarGetLbGlobal(var);
1046  if( !SCIPsetIsEQ(set, val, oldval) )
1047  {
1048  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1049  SCIPvarGetName(var), oldval, val);
1050  return SCIP_INVALIDDATA;
1051  }
1052  return SCIP_OKAY;
1053 
1054  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1055  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1058 
1059  if( val == SCIP_UNKNOWN )/*lint !e777*/
1060  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), val);
1061  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1062  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), SCIPvarGetAggrScalar(var) > 0 ? val : -val);
1063  else
1064  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), (val - SCIPvarGetAggrConstant(var))/SCIPvarGetAggrScalar(var));
1065 
1067  if ( SCIPvarGetMultaggrNVars(var) == 1 )
1068  {
1069  SCIP_VAR** multaggrvars;
1070  SCIP_Real* multaggrscalars;
1071  SCIP_Real multaggrconstant;
1072 
1073  multaggrvars = SCIPvarGetMultaggrVars(var);
1074  multaggrscalars = SCIPvarGetMultaggrScalars(var);
1075  multaggrconstant = SCIPvarGetMultaggrConstant(var);
1076 
1077  if( SCIPsetIsInfinity(set, multaggrconstant) || SCIPsetIsInfinity(set, -multaggrconstant) )
1078  {
1079  if( (SCIPsetIsInfinity(set, multaggrconstant) && !SCIPsetIsInfinity(set, val))
1080  || (SCIPsetIsInfinity(set, -multaggrconstant) && !SCIPsetIsInfinity(set, -val)) )
1081  {
1082  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1083  SCIPvarGetName(var), multaggrconstant, val);
1084  return SCIP_INVALIDDATA;
1085  }
1086  return SCIP_OKAY;
1087  }
1088  else
1089  {
1090  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1091  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], multaggrscalars[0] > 0 ? val : -val);
1092  else
1093  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], (val - multaggrconstant)/multaggrscalars[0]);
1094  }
1095  }
1096  SCIPerrorMessage("cannot set solution value for multiple aggregated variable\n");
1097  return SCIP_INVALIDDATA;
1098 
1101 
1102  if( val == SCIP_UNKNOWN )/*lint !e777*/
1103  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), val);
1104  else if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1105  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -val);
1106  else
1107  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), SCIPvarGetNegationConstant(var) - val);
1108 
1109  default:
1110  SCIPerrorMessage("unknown variable status\n");
1111  return SCIP_INVALIDDATA;
1112  }
1113 }
1114 
1115 /** increases value of variable in primal CIP solution */
1117  SCIP_SOL* sol, /**< primal CIP solution */
1118  SCIP_SET* set, /**< global SCIP settings */
1119  SCIP_STAT* stat, /**< problem statistics data */
1120  SCIP_TREE* tree, /**< branch and bound tree */
1121  SCIP_VAR* var, /**< variable to increase solution value for */
1122  SCIP_Real incval /**< increment for solution value of variable */
1123  )
1124 {
1125  SCIP_Real oldval;
1126 
1127  assert(sol != NULL);
1128  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1129  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1130  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1131  assert(stat != NULL);
1132  assert(var != NULL);
1133  assert(!SCIPsetIsInfinity(set, incval) && !SCIPsetIsInfinity(set, -incval));
1134 
1135  SCIPdebugMessage("increasing value of <%s> in solution %p by %g\n", SCIPvarGetName(var), (void*)sol, incval);
1136 
1137  if( SCIPsetIsZero(set, incval) )
1138  return SCIP_OKAY;
1139 
1140  oldval = solGetArrayVal(sol, var);
1141  if( SCIPsetIsInfinity(set, oldval) || SCIPsetIsInfinity(set, -oldval) )
1142  return SCIP_OKAY;
1143 
1144  /* we want to store only values for non fixed variables (LOOSE or COLUMN); others have to be transformed */
1145  /* @todo: handle strange cases, such as sums that yield infinite values */
1146  switch( SCIPvarGetStatus(var) )
1147  {
1149  if( SCIPsolIsOriginal(sol) )
1150  {
1151  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1152  sol->obj += SCIPvarGetObj(var) * incval;
1153  solStamp(sol, stat, tree, FALSE);
1154  return SCIP_OKAY;
1155  }
1156  else
1157  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetTransVar(var), incval);
1158 
1159  case SCIP_VARSTATUS_LOOSE:
1160  case SCIP_VARSTATUS_COLUMN:
1161  assert(!SCIPsolIsOriginal(sol));
1162  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1163  sol->obj += SCIPvarGetObj(var) * incval;
1164  solStamp(sol, stat, tree, FALSE);
1165  return SCIP_OKAY;
1166 
1167  case SCIP_VARSTATUS_FIXED:
1168  SCIPerrorMessage("cannot increase solution value for fixed variable\n");
1169  return SCIP_INVALIDDATA;
1170 
1171  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1172  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1173  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), incval/SCIPvarGetAggrScalar(var));
1174 
1176  SCIPerrorMessage("cannot increase solution value for multiple aggregated variable\n");
1177  return SCIP_INVALIDDATA;
1178 
1180  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -incval);
1181 
1182  default:
1183  SCIPerrorMessage("unknown variable status\n");
1184  return SCIP_INVALIDDATA;
1185  }
1186 }
1187 
1188 /** returns value of variable in primal CIP solution */
1190  SCIP_SOL* sol, /**< primal CIP solution */
1191  SCIP_SET* set, /**< global SCIP settings */
1192  SCIP_STAT* stat, /**< problem statistics data */
1193  SCIP_VAR* var /**< variable to get value for */
1194  )
1195 {
1196  SCIP_VAR** vars;
1197  SCIP_Real* scalars;
1198  SCIP_Real solval;
1199  SCIP_Real solvalsum;
1200  int nvars;
1201  int i;
1202 
1203  assert(sol != NULL);
1204  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1205  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1207  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1208  assert(var != NULL);
1209 
1210  /* if the value of a transformed variable in an original solution is requested, we need to project the variable back
1211  * to the original space, the opposite case is handled below
1212  */
1213  if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) )
1214  {
1215  SCIP_RETCODE retcode;
1216  SCIP_VAR* origvar;
1217  SCIP_Real scalar;
1218  SCIP_Real constant;
1219 
1220  /* we cannot get the value of a transformed variable for a solution that lives in the original problem space
1221  * -> get the corresponding original variable first
1222  */
1223  origvar = var;
1224  scalar = 1.0;
1225  constant = 0.0;
1226  retcode = SCIPvarGetOrigvarSum(&origvar, &scalar, &constant);
1227  if ( retcode != SCIP_OKAY )
1228  return SCIP_INVALID;
1229  if( origvar == NULL )
1230  {
1231  /* the variable has no original counterpart: in the original solution, it has a value of zero */
1232  return 0.0;
1233  }
1234  assert(!SCIPvarIsTransformed(origvar));
1235  return scalar * SCIPsolGetVal(sol, set, stat, origvar) + constant;
1236  }
1237 
1238  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1239  switch( SCIPvarGetStatus(var) )
1240  {
1242  if( SCIPsolIsOriginal(sol) )
1243  return solGetArrayVal(sol, var);
1244  else
1245  return SCIPsolGetVal(sol, set, stat, SCIPvarGetTransVar(var));
1246 
1247  case SCIP_VARSTATUS_LOOSE:
1248  case SCIP_VARSTATUS_COLUMN:
1249  assert(!SCIPsolIsOriginal(sol));
1250  return solGetArrayVal(sol, var);
1251 
1252  case SCIP_VARSTATUS_FIXED:
1253  assert(!SCIPsolIsOriginal(sol));
1254  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1255  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1256  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1257  return SCIPvarGetLbGlobal(var);
1258 
1259  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1260  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetAggrVar(var));
1261  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1262  return SCIP_UNKNOWN;
1263  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1264  {
1265  if( SCIPvarGetAggrScalar(var) * solval > 0.0 )
1266  return SCIPsetInfinity(set);
1267  if( SCIPvarGetAggrScalar(var) * solval < 0.0 )
1268  return -SCIPsetInfinity(set);
1269  }
1270  return SCIPvarGetAggrScalar(var) * solval + SCIPvarGetAggrConstant(var);
1271 
1273  nvars = SCIPvarGetMultaggrNVars(var);
1274  vars = SCIPvarGetMultaggrVars(var);
1275  scalars = SCIPvarGetMultaggrScalars(var);
1276  solvalsum = SCIPvarGetMultaggrConstant(var);
1277  for( i = 0; i < nvars; ++i )
1278  {
1279  solval = SCIPsolGetVal(sol, set, stat, vars[i]);
1280  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1281  return SCIP_UNKNOWN;
1282  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1283  {
1284  if( scalars[i] * solval > 0.0 )
1285  return SCIPsetInfinity(set);
1286  if( scalars[i] * solval < 0.0 )
1287  return -SCIPsetInfinity(set);
1288  }
1289  solvalsum += scalars[i] * solval;
1290  }
1291  return solvalsum;
1292 
1294  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetNegationVar(var));
1295  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1296  return SCIP_UNKNOWN;
1297  if( SCIPsetIsInfinity(set, solval) )
1298  return -SCIPsetInfinity(set);
1299  if( SCIPsetIsInfinity(set, -solval) )
1300  return SCIPsetInfinity(set);
1301  return SCIPvarGetNegationConstant(var) - solval;
1302 
1303  default:
1304  SCIPerrorMessage("unknown variable status\n");
1305  SCIPABORT();
1306  return 0.0; /*lint !e527*/
1307  }
1308 }
1309 
1310 /** returns value of variable in primal ray represented by primal CIP solution */
1312  SCIP_SOL* sol, /**< primal CIP solution, representing a primal ray */
1313  SCIP_SET* set, /**< global SCIP settings */
1314  SCIP_STAT* stat, /**< problem statistics data */
1315  SCIP_VAR* var /**< variable to get value for */
1316  )
1317 {
1318  SCIP_VAR** vars;
1319  SCIP_Real* scalars;
1320  SCIP_Real solval;
1321  SCIP_Real solvalsum;
1322  int nvars;
1323  int i;
1324 
1325  assert(sol != NULL);
1326  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1327  assert(var != NULL);
1328 
1329  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1330  switch( SCIPvarGetStatus(var) )
1331  {
1333  return SCIPsolGetRayVal(sol, set, stat, SCIPvarGetTransVar(var));
1334 
1335  case SCIP_VARSTATUS_LOOSE:
1336  case SCIP_VARSTATUS_COLUMN:
1337  return solGetArrayVal(sol, var);
1338 
1339  case SCIP_VARSTATUS_FIXED:
1340  assert(!SCIPsolIsOriginal(sol));
1341  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1342  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1343  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1344  return 0.0; /* constants are ignored for computing the ray direction */
1345 
1346  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1347  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetAggrVar(var));
1348  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1349  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1350  return SCIPvarGetAggrScalar(var) * solval; /* constants are ignored for computing the ray direction */
1351 
1353  nvars = SCIPvarGetMultaggrNVars(var);
1354  vars = SCIPvarGetMultaggrVars(var);
1355  scalars = SCIPvarGetMultaggrScalars(var);
1356  solvalsum = 0.0; /* constants are ignored for computing the ray direction */
1357  for( i = 0; i < nvars; ++i )
1358  {
1359  solval = SCIPsolGetRayVal(sol, set, stat, vars[i]);
1360  assert(solval != SCIP_UNKNOWN ); /*lint !e777*/
1361  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1362  solvalsum += scalars[i] * solval;
1363  }
1364  return solvalsum;
1365 
1367  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetNegationVar(var));
1368  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1369  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1370  return -solval; /* constants are ignored for computing the ray direction */
1371 
1372  default:
1373  SCIPerrorMessage("unknown variable status\n");
1374  SCIPABORT();
1375  return 0.0; /*lint !e527*/
1376  }
1377 }
1378 
1379 /** gets objective value of primal CIP solution in transformed problem */
1381  SCIP_SOL* sol, /**< primal CIP solution */
1382  SCIP_SET* set, /**< global SCIP settings */
1383  SCIP_PROB* transprob, /**< tranformed problem data */
1384  SCIP_PROB* origprob /**< original problem data */
1385  )
1386 {
1387  assert(sol != NULL);
1388 
1389  /* for original solutions, sol->obj contains the external objective value */
1390  if( SCIPsolIsOriginal(sol) )
1391  return SCIPprobInternObjval(transprob, origprob, set, sol->obj);
1392  else
1393  return sol->obj;
1394 }
1395 
1396 /** updates primal solutions after a change in a variable's objective value */
1398  SCIP_SOL* sol, /**< primal CIP solution */
1399  SCIP_VAR* var, /**< problem variable */
1400  SCIP_Real oldobj, /**< old objective value */
1401  SCIP_Real newobj /**< new objective value */
1402  )
1403 {
1404  SCIP_Real solval;
1405 
1406  assert(sol != NULL);
1407  assert(!SCIPsolIsOriginal(sol));
1409 
1410  solval = solGetArrayVal(sol, var);
1411  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1412  sol->obj += (newobj - oldobj) * solval;
1413 }
1414 
1415 /** checks primal CIP solution for feasibility */
1417  SCIP_SOL* sol, /**< primal CIP solution */
1418  SCIP_SET* set, /**< global SCIP settings */
1419  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1420  BMS_BLKMEM* blkmem, /**< block memory */
1421  SCIP_STAT* stat, /**< problem statistics */
1422  SCIP_PROB* prob, /**< transformed problem data */
1423  SCIP_Bool printreason, /**< should all reasons of violations be printed? */
1424  SCIP_Bool checkbounds, /**< should the bounds of the variables be checked? */
1425  SCIP_Bool checkintegrality, /**< has integrality to be checked? */
1426  SCIP_Bool checklprows, /**< have current LP rows to be checked? */
1427  SCIP_Bool* feasible /**< stores whether solution is feasible */
1428  )
1429 {
1430  SCIP_RESULT result;
1431  int h;
1432 
1433  assert(sol != NULL);
1434  assert(!SCIPsolIsOriginal(sol));
1435  assert(set != NULL);
1436  assert(prob != NULL);
1437  assert(feasible != NULL);
1438 
1439  SCIPdebugMessage("checking solution with objective value %g (nodenum=%"SCIP_LONGINT_FORMAT", origin=%u)\n",
1440  sol->obj, sol->nodenum, sol->solorigin);
1441 
1442  *feasible = TRUE;
1443 
1444  /* check whether the solution respects the global bounds of the variables */
1445  if( checkbounds )
1446  {
1447  int v;
1448 
1449  for( v = 0; v < prob->nvars && (*feasible || printreason); ++v )
1450  {
1451  SCIP_VAR* var;
1452  SCIP_Real solval;
1453 
1454  var = prob->vars[v];
1455  solval = SCIPsolGetVal(sol, set, stat, var);
1456 
1457  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1458  {
1459  SCIP_Real lb;
1460  SCIP_Real ub;
1461 
1462  lb = SCIPvarGetLbGlobal(var);
1463  ub = SCIPvarGetUbGlobal(var);
1464  *feasible = *feasible && SCIPsetIsFeasGE(set, solval, lb) && SCIPsetIsFeasLE(set, solval, ub);
1465 
1466  if( printreason && (SCIPsetIsFeasLT(set, solval, lb) || SCIPsetIsFeasGT(set, solval, ub)) )
1467  {
1468  SCIPmessagePrintInfo(messagehdlr, "solution value %g violates bounds of <%s>[%g,%g] by %g\n", solval, SCIPvarGetName(var),
1469  SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), MAX(lb - solval, 0.0) + MAX(solval - ub, 0.0));
1470  }
1471  }
1472 
1473 #ifdef SCIP_DEBUG
1474  if( !(*feasible) && !printreason )
1475  {
1476  SCIPdebugPrintf(" -> solution value %g violates bounds of <%s>[%g,%g]\n", solval, SCIPvarGetName(var),
1478  }
1479 #endif
1480  }
1481  }
1482 
1483  /* check whether there are infinite variable values that lead to an objective value of +infinity */
1484  if( *feasible && sol->hasinfval )
1485  {
1486  int v;
1487 
1488  for( v = 0; v < prob->nvars && (*feasible || printreason); ++v )
1489  {
1490  SCIP_VAR* var;
1491  SCIP_Real solval;
1492 
1493  var = prob->vars[v];
1494  solval = SCIPsolGetVal(sol, set, stat, var);
1495  assert(solval != SCIP_INVALID); /*lint !e777*/
1496 
1497  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1498  {
1499  *feasible = *feasible && (!SCIPsetIsInfinity(set, solval) || SCIPsetIsLE(set, SCIPvarGetObj(var), 0.0) );
1500  *feasible = *feasible && (!SCIPsetIsInfinity(set, -solval) || SCIPsetIsGE(set, SCIPvarGetObj(var), 0.0) );
1501 
1502  if( printreason && ((SCIPsetIsInfinity(set, solval) && SCIPsetIsGT(set, SCIPvarGetObj(var), 0.0)) ||
1503  (SCIPsetIsInfinity(set, -solval) && SCIPsetIsLT(set, SCIPvarGetObj(var), 0.0))) )
1504  {
1505  SCIPmessagePrintInfo(messagehdlr, "infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1506  solval, SCIPvarGetName(var), SCIPvarGetObj(var));
1507  }
1508  }
1509 
1510 #ifdef SCIP_DEBUG
1511  if( !(*feasible) && !printreason )
1512  {
1513  SCIPdebugPrintf("infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1514  solval, SCIPvarGetName(var), SCIPvarGetObj(var));
1515  }
1516 #endif
1517  }
1518  }
1519 
1520  /* check whether the solution fulfills all constraints */
1521  for( h = 0; h < set->nconshdlrs && (*feasible || printreason); ++h )
1522  {
1523  SCIP_CALL( SCIPconshdlrCheck(set->conshdlrs[h], blkmem, set, stat, sol,
1524  checkintegrality, checklprows, printreason, &result) );
1525  *feasible = *feasible && (result == SCIP_FEASIBLE);
1526 
1527 #ifdef SCIP_DEBUG
1528  if( !(*feasible) )
1529  {
1530  SCIPdebugPrintf(" -> infeasibility detected in constraint handler <%s>\n",
1531  SCIPconshdlrGetName(set->conshdlrs[h]));
1532  }
1533 #endif
1534  }
1535 
1536  return SCIP_OKAY;
1537 }
1538 
1539 /** try to round given solution */
1541  SCIP_SOL* sol, /**< primal solution */
1542  SCIP_SET* set, /**< global SCIP settings */
1543  SCIP_STAT* stat, /**< problem statistics data */
1544  SCIP_PROB* prob, /**< transformed problem data */
1545  SCIP_TREE* tree, /**< branch and bound tree */
1546  SCIP_Bool* success /**< pointer to store whether rounding was successful */
1547  )
1548 {
1549  int nvars;
1550  int v;
1551 
1552  assert(sol != NULL);
1553  assert(!SCIPsolIsOriginal(sol));
1554  assert(prob != NULL);
1555  assert(prob->transformed);
1556  assert(success != NULL);
1557 
1558  /* round all roundable fractional variables in the corresponding direction as long as no unroundable var was found */
1559  nvars = prob->nbinvars + prob->nintvars;
1560  for( v = 0; v < nvars; ++v )
1561  {
1562  SCIP_VAR* var;
1563  SCIP_Real solval;
1564  SCIP_Bool mayrounddown;
1565  SCIP_Bool mayroundup;
1566 
1567  var = prob->vars[v];
1569  solval = solGetArrayVal(sol, var);
1570 
1571  /* solutions with unknown entries cannot be rounded */
1572  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1573  break;
1574 
1575  /* if solution value is already integral, there is nothing to do */
1576  if( SCIPsetIsIntegral(set, solval) )
1577  continue;
1578 
1579  /* if solution value is already integral with feastol, round to nearest integral value */
1580  if( SCIPsetIsFeasIntegral(set, solval) )
1581  {
1582  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, SCIPsetRound(set, solval)) );
1583  continue;
1584  }
1585 
1586  /* get rounding possibilities */
1587  mayrounddown = SCIPvarMayRoundDown(var);
1588  mayroundup = SCIPvarMayRoundUp(var);
1589 
1590  /* choose rounding direction */
1591  if( mayrounddown && mayroundup )
1592  {
1593  /* we can round in both directions: round in objective function direction */
1594  if( SCIPvarGetObj(var) >= 0.0 )
1595  solval = SCIPsetFeasFloor(set, solval);
1596  else
1597  solval = SCIPsetFeasCeil(set, solval);
1598  }
1599  else if( mayrounddown )
1600  solval = SCIPsetFeasFloor(set, solval);
1601  else if( mayroundup )
1602  solval = SCIPsetFeasCeil(set, solval);
1603  else
1604  break;
1605 
1606  /* store new solution value */
1607  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, solval) );
1608  }
1609 
1610  /* check, if rounding was successful */
1611  *success = (v == nvars);
1612 
1613  return SCIP_OKAY;
1614 }
1615 
1616 /** updates the solution value sums in variables by adding the value in the given solution */
1618  SCIP_SOL* sol, /**< primal CIP solution */
1619  SCIP_SET* set, /**< global SCIP settings */
1620  SCIP_STAT* stat, /**< problem statistics data */
1621  SCIP_PROB* prob, /**< transformed problem data */
1622  SCIP_Real weight /**< weight of solution in weighted average */
1623  )
1624 {
1625  SCIP_Real solval;
1626  int v;
1627 
1628  assert(sol != NULL);
1629  assert(!SCIPsolIsOriginal(sol));
1630  assert(0.0 <= weight && weight <= 1.0);
1631 
1632  for( v = 0; v < prob->nvars; ++v )
1633  {
1634  assert(prob->vars[v] != NULL);
1635  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
1636  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1637  {
1638  prob->vars[v]->primsolavg *= (1.0-weight);
1639  prob->vars[v]->primsolavg += weight*solval;
1640  }
1641  }
1642 }
1643 
1644 /** retransforms solution to original problem space */
1646  SCIP_SOL* sol, /**< primal CIP solution */
1647  SCIP_SET* set, /**< global SCIP settings */
1648  SCIP_STAT* stat, /**< problem statistics data */
1649  SCIP_PROB* origprob, /**< original problem */
1650  SCIP_PROB* transprob, /**< transformed problem */
1651  SCIP_Bool* hasinfval /**< pointer to store whether the solution has infinite values */
1652  )
1653 {
1654  SCIP_VAR** transvars;
1655  SCIP_VAR** vars;
1656  SCIP_VAR** activevars;
1657  SCIP_Real* solvals;
1658  SCIP_Real* activevals;
1659  SCIP_Real* transsolvals;
1660  SCIP_Real constant;
1661  int requiredsize;
1662  int ntransvars;
1663  int nactivevars;
1664  int nvars;
1665  int v;
1666  int i;
1667 
1668  assert(sol != NULL);
1669  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1670  assert(origprob != NULL);
1671  assert(transprob != NULL);
1672  assert(hasinfval != NULL);
1673  assert(!origprob->transformed);
1674  assert(transprob->transformed);
1675 
1676  *hasinfval = FALSE;
1677 
1678  /* This method was a performance bottleneck when retransforming a solution during presolving, before flattening the
1679  * aggregation graph. In that case, calling SCIPsolGetVal() on the original variable consumed too much
1680  * time. Therefore, we now first compute the active representation of each original variable using
1681  * SCIPvarGetActiveRepresentatives(), which is much faster, and sum up the solution values of the active variables by
1682  * hand for each original variable.
1683  */
1684  vars = origprob->vars;
1685  nvars = origprob->nvars;
1686  transvars = transprob->vars;
1687  ntransvars = transprob->nvars;
1688 
1689  /* allocate temporary memory for getting the active representation of the original variables, buffering the solution
1690  * values of all active variables and storing the original solution values
1691  */
1692  SCIP_CALL( SCIPsetAllocBufferArray(set, &transsolvals, ntransvars + 1) );
1693  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevars, ntransvars + 1) );
1694  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevals, ntransvars + 1) );
1695  SCIP_CALL( SCIPsetAllocBufferArray(set, &solvals, nvars) );
1696  assert(transsolvals != NULL); /* for flexelint */
1697  assert(solvals != NULL); /* for flexelint */
1698 
1699  /* get the solution values of all active variables */
1700  for( v = 0; v < ntransvars; ++v )
1701  {
1702  transsolvals[v] = SCIPsolGetVal(sol, set, stat, transvars[v]);
1703  }
1704 
1705  /* get the solution in original problem variables */
1706  for( v = 0; v < nvars; ++v )
1707  {
1708  activevars[0] = vars[v];
1709  activevals[0] = 1.0;
1710  nactivevars = 1;
1711  constant = 0.0;
1712 
1713  /* get active representation of the original variable */
1714  SCIP_CALL( SCIPvarGetActiveRepresentatives(set, activevars, activevals, &nactivevars, ntransvars + 1, &constant,
1715  &requiredsize, TRUE) );
1716  assert(requiredsize <= ntransvars);
1717 
1718  /* compute solution value of the original variable */
1719  solvals[v] = constant;
1720  for( i = 0; i < nactivevars; ++i )
1721  {
1722  assert(0 <= SCIPvarGetProbindex(activevars[i]) && SCIPvarGetProbindex(activevars[i]) < ntransvars);
1723  assert(!SCIPsetIsInfinity(set, -solvals[v]) || !SCIPsetIsInfinity(set, activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1724  assert(!SCIPsetIsInfinity(set, solvals[v]) || !SCIPsetIsInfinity(set, -activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1725  solvals[v] += activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])];
1726  }
1727 
1728  if( SCIPsetIsInfinity(set, solvals[v]) )
1729  {
1730  solvals[v] = SCIPsetInfinity(set);
1731  *hasinfval = TRUE;
1732  }
1733  else if( SCIPsetIsInfinity(set, -solvals[v]) )
1734  {
1735  solvals[v] = -SCIPsetInfinity(set);
1736  *hasinfval = TRUE;
1737  }
1738  }
1739 
1740  /* clear the solution and convert it into original space */
1741  SCIP_CALL( solClearArrays(sol) );
1743  sol->obj = 0.0;
1744 
1745  /* reinsert the values of the original variables */
1746  for( v = 0; v < nvars; ++v )
1747  {
1748  if( !SCIPsetIsZero(set, solvals[v]) )
1749  {
1750  SCIP_CALL( solSetArrayVal(sol, set, vars[v], solvals[v]) );
1751  if( solvals[v] != SCIP_UNKNOWN ) /*lint !e777*/
1752  sol->obj += SCIPvarGetObj(vars[v]) * solvals[v];
1753  }
1754  }
1755 
1756  /**@todo remember the variables without original counterpart (priced variables) in the solution */
1757 
1758  /* free temporary memory */
1759  SCIPsetFreeBufferArray(set, &solvals);
1760  SCIPsetFreeBufferArray(set, &activevals);
1761  SCIPsetFreeBufferArray(set, &activevars);
1762  SCIPsetFreeBufferArray(set, &transsolvals);
1763 
1764  return SCIP_OKAY;
1765 }
1766 
1767 /** recomputes the objective value of an original solution, e.g., when transferring solutions
1768  * from the solution pool (objective coefficients might have changed in the meantime)
1769  */
1771  SCIP_SOL* sol, /**< primal CIP solution */
1772  SCIP_SET* set, /**< global SCIP settings */
1773  SCIP_STAT* stat, /**< problem statistics data */
1774  SCIP_PROB* origprob /**< original problem */
1775  )
1776 {
1777  SCIP_VAR** vars;
1778  SCIP_Real solval;
1779  int nvars;
1780  int v;
1781 
1782  assert(sol != NULL);
1783  assert(SCIPsolIsOriginal(sol));
1784  assert(origprob != NULL);
1785 
1786  vars = origprob->vars;
1787  nvars = origprob->nvars;
1788 
1789  /* recompute the objective value */
1790  sol->obj = SCIPprobGetObjoffset(origprob);
1791  for( v = 0; v < nvars; ++v )
1792  {
1793  solval = SCIPsolGetVal(sol, set, stat, vars[v]);
1794  if( !SCIPsetIsZero(set, solval) && solval != SCIP_UNKNOWN ) /*lint !e777*/
1795  {
1796  sol->obj += SCIPvarGetObj(vars[v]) * solval;
1797  }
1798  }
1799 
1800  if( SCIPsetIsInfinity(set, -sol->obj) )
1801  sol->obj = -SCIPsetInfinity(set);
1802 }
1803 
1804 /** returns whether the given solutions are equal */
1806  SCIP_SOL* sol1, /**< first primal CIP solution */
1807  SCIP_SOL* sol2, /**< second primal CIP solution */
1808  SCIP_SET* set, /**< global SCIP settings */
1809  SCIP_STAT* stat, /**< problem statistics data */
1810  SCIP_PROB* origprob, /**< original problem */
1811  SCIP_PROB* transprob /**< transformed problem after presolve, or NULL if both solution are
1812  * defined in the original problem space */
1813  )
1814 {
1815  SCIP_PROB* prob;
1816  SCIP_Real obj1;
1817  SCIP_Real obj2;
1818  int v;
1819 
1820  assert(sol1 != NULL);
1821  assert(sol2 != NULL);
1822  assert((SCIPsolIsOriginal(sol1) && SCIPsolIsOriginal(sol2)) || transprob != NULL);
1823 
1824  /* if both solutions are original or both are transformed, take the objective values stored in the solutions */
1825  if( SCIPsolIsOriginal(sol1) == SCIPsolIsOriginal(sol2) )
1826  {
1827  obj1 = sol1->obj;
1828  obj2 = sol2->obj;
1829  }
1830  /* one solution is original and the other not, so we have to get for both the objective in the transformed problem */
1831  else
1832  {
1833  obj1 = SCIPsolGetObj(sol1, set, transprob, origprob);
1834  obj2 = SCIPsolGetObj(sol2, set, transprob, origprob);
1835  }
1836 
1837  /* solutions with different objective values cannot be the same */
1838  if( !SCIPsetIsEQ(set, obj1, obj2) )
1839  return FALSE;
1840 
1841  /* if one of the solutions is defined in the original space, the comparison has to be performed in the original
1842  * space
1843  */
1844  prob = transprob;
1845  if( SCIPsolIsOriginal(sol1) || SCIPsolIsOriginal(sol2) )
1846  prob = origprob;
1847  assert(prob != NULL);
1848 
1849  /* compare each variable value */
1850  for( v = 0; v < prob->nvars; ++v )
1851  {
1852  SCIP_Real val1;
1853  SCIP_Real val2;
1854 
1855  val1 = SCIPsolGetVal(sol1, set, stat, prob->vars[v]);
1856  val2 = SCIPsolGetVal(sol2, set, stat, prob->vars[v]);
1857  if( !SCIPsetIsEQ(set, val1, val2) )
1858  return FALSE;
1859  }
1860 
1861  return TRUE;
1862 }
1863 
1864 /** outputs non-zero elements of solution to file stream */
1866  SCIP_SOL* sol, /**< primal CIP solution */
1867  SCIP_SET* set, /**< global SCIP settings */
1868  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1869  SCIP_STAT* stat, /**< problem statistics data */
1870  SCIP_PROB* prob, /**< problem data (original or transformed) */
1871  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
1872  FILE* file, /**< output file (or NULL for standard output) */
1873  SCIP_Bool printzeros /**< should variables set to zero be printed? */
1874  )
1875 {
1876  SCIP_Real solval;
1877  int v;
1878 
1879  assert(sol != NULL);
1880  assert(prob != NULL);
1881  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
1882 
1883  /* display variables of problem data */
1884  for( v = 0; v < prob->nfixedvars; ++v )
1885  {
1886  assert(prob->fixedvars[v] != NULL);
1887  solval = SCIPsolGetVal(sol, set, stat, prob->fixedvars[v]);
1888  if( printzeros || !SCIPsetIsZero(set, solval) )
1889  {
1890  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
1891  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1892  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
1893  else if( SCIPsetIsInfinity(set, solval) )
1894  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
1895  else if( SCIPsetIsInfinity(set, -solval) )
1896  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
1897  else
1898  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
1899  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(prob->fixedvars[v]));
1900  }
1901  }
1902 
1903  for( v = 0; v < prob->nvars; ++v )
1904  {
1905  assert(prob->vars[v] != NULL);
1906  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
1907  if( printzeros || !SCIPsetIsZero(set, solval) )
1908  {
1909  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
1910  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1911  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
1912  else if( SCIPsetIsInfinity(set, solval) )
1913  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
1914  else if( SCIPsetIsInfinity(set, -solval) )
1915  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
1916  else
1917  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
1918  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(prob->vars[v]));
1919  }
1920  }
1921 
1922  /* display additional priced variables (if given problem data is original problem) */
1923  if( !prob->transformed && !SCIPsolIsOriginal(sol) )
1924  {
1925  assert(transprob != NULL);
1926  for( v = 0; v < transprob->nfixedvars; ++v )
1927  {
1928  assert(transprob->fixedvars[v] != NULL);
1929  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
1930  continue;
1931 
1932  solval = SCIPsolGetVal(sol, set, stat, transprob->fixedvars[v]);
1933  if( printzeros || !SCIPsetIsZero(set, solval) )
1934  {
1935  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[v]));
1936  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1937  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
1938  else if( SCIPsetIsInfinity(set, solval) )
1939  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
1940  else if( SCIPsetIsInfinity(set, -solval) )
1941  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
1942  else
1943  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
1944  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(transprob->fixedvars[v]));
1945  }
1946  }
1947  for( v = 0; v < transprob->nvars; ++v )
1948  {
1949  assert(transprob->vars[v] != NULL);
1950  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
1951  continue;
1952 
1953  solval = SCIPsolGetVal(sol, set, stat, transprob->vars[v]);
1954  if( printzeros || !SCIPsetIsZero(set, solval) )
1955  {
1956  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
1957  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1958  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
1959  else if( SCIPsetIsInfinity(set, solval) )
1960  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
1961  else if( SCIPsetIsInfinity(set, -solval) )
1962  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
1963  else
1964  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
1965  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(transprob->vars[v]));
1966  }
1967  }
1968  }
1969 
1970  return SCIP_OKAY;
1971 }
1972 
1973 /** outputs non-zero elements of solution representing a ray to file stream */
1975  SCIP_SOL* sol, /**< primal CIP solution */
1976  SCIP_SET* set, /**< global SCIP settings */
1977  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1978  SCIP_STAT* stat, /**< problem statistics data */
1979  SCIP_PROB* prob, /**< problem data (original or transformed) */
1980  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
1981  FILE* file, /**< output file (or NULL for standard output) */
1982  SCIP_Bool printzeros /**< should variables set to zero be printed? */
1983  )
1984 {
1985  SCIP_Real solval;
1986  int v;
1987 
1988  assert(sol != NULL);
1989  assert(prob != NULL);
1990  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
1991 
1992  /* display variables of problem data */
1993  for( v = 0; v < prob->nfixedvars; ++v )
1994  {
1995  assert(prob->fixedvars[v] != NULL);
1996  solval = SCIPsolGetRayVal(sol, set, stat, prob->fixedvars[v]);
1997  if( printzeros || !SCIPsetIsZero(set, solval) )
1998  {
1999  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
2000  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2001  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2002  else if( SCIPsetIsInfinity(set, solval) )
2003  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2004  else if( SCIPsetIsInfinity(set, -solval) )
2005  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2006  else
2007  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2008  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(prob->fixedvars[v]));
2009  }
2010  }
2011  for( v = 0; v < prob->nvars; ++v )
2012  {
2013  assert(prob->vars[v] != NULL);
2014  solval = SCIPsolGetRayVal(sol, set, stat, prob->vars[v]);
2015  if( printzeros || !SCIPsetIsZero(set, solval) )
2016  {
2017  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
2018  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2019  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2020  else if( SCIPsetIsInfinity(set, solval) )
2021  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2022  else if( SCIPsetIsInfinity(set, -solval) )
2023  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2024  else
2025  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
2026  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(prob->vars[v]));
2027  }
2028  }
2029 
2030  /* display additional priced variables (if given problem data is original problem) */
2031  if( !prob->transformed && !SCIPsolIsOriginal(sol) )
2032  {
2033  assert(transprob != NULL);
2034  for( v = 0; v < transprob->nfixedvars; ++v )
2035  {
2036  assert(transprob->fixedvars[v] != NULL);
2037  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
2038  continue;
2039 
2040  solval = SCIPsolGetRayVal(sol, set, stat, transprob->fixedvars[v]);
2041  if( printzeros || !SCIPsetIsZero(set, solval) )
2042  {
2043  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[v]));
2044  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2045  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2046  else if( SCIPsetIsInfinity(set, solval) )
2047  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2048  else if( SCIPsetIsInfinity(set, -solval) )
2049  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2050  else
2051  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2052  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(transprob->fixedvars[v]));
2053  }
2054  }
2055  for( v = 0; v < transprob->nvars; ++v )
2056  {
2057  assert(transprob->vars[v] != NULL);
2058  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
2059  continue;
2060 
2061  solval = SCIPsolGetRayVal(sol, set, stat, transprob->vars[v]);
2062  if( printzeros || !SCIPsetIsZero(set, solval) )
2063  {
2064  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
2065  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2066  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2067  else if( SCIPsetIsInfinity(set, solval) )
2068  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2069  else if( SCIPsetIsInfinity(set, -solval) )
2070  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2071  else
2072  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2073  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetObj(transprob->vars[v]));
2074  }
2075  }
2076  }
2077 
2078  return SCIP_OKAY;
2079 }
2080 
2081 
2082 
2083 
2084 /*
2085  * simple functions implemented as defines
2086  */
2087 
2088 /* In debug mode, the following methods are implemented as function calls to ensure
2089  * type validity.
2090  * In optimized mode, the methods are implemented as defines to improve performance.
2091  * However, we want to have them in the library anyways, so we have to undef the defines.
2092  */
2093 
2094 #undef SCIPsolGetOrigin
2095 #undef SCIPsolIsOriginal
2096 #undef SCIPsolGetOrigObj
2097 #undef SCIPsolGetTime
2098 #undef SCIPsolGetNodenum
2099 #undef SCIPsolGetRunnum
2100 #undef SCIPsolGetDepth
2101 #undef SCIPsolGetHeur
2102 #undef SCIPsolOrigAddObjval
2103 #undef SCIPsolGetPrimalIndex
2104 #undef SCIPsolSetPrimalIndex
2105 #undef SCIPsolGetIndex
2106 #undef SCIPsolSetHeur
2107 
2108 /** gets origin of solution */
2110  SCIP_SOL* sol /**< primal CIP solution */
2111  )
2112 {
2113  assert(sol != NULL);
2114 
2115  return sol->solorigin;
2116 }
2117 
2118 /** returns whether the given solution is defined on original variables */
2120  SCIP_SOL* sol /**< primal CIP solution */
2121  )
2122 {
2123  assert(sol != NULL);
2124 
2125  return (sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
2126 }
2127 
2128 /** gets objective value of primal CIP solution which lives in the original problem space */
2130  SCIP_SOL* sol /**< primal CIP solution */
2131  )
2132 {
2133  assert(sol != NULL);
2134  assert(SCIPsolIsOriginal(sol));
2135 
2136  return sol->obj;
2137 }
2138 
2139 /** adds value to the objective value of a given original primal CIP solution */
2141  SCIP_SOL* sol, /**< primal CIP solution */
2142  SCIP_Real addval /**< offset value to add */
2143  )
2144 {
2145  assert(sol != NULL);
2146  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
2147 
2148  sol->obj += addval;
2149 }
2150 
2151 /** gets clock time, when this solution was found */
2153  SCIP_SOL* sol /**< primal CIP solution */
2154  )
2155 {
2156  assert(sol != NULL);
2157 
2158  return sol->time;
2159 }
2160 
2161 /** gets branch and bound run number, where this solution was found */
2163  SCIP_SOL* sol /**< primal CIP solution */
2164  )
2165 {
2166  assert(sol != NULL);
2167 
2168  return sol->runnum;
2169 }
2170 
2171 /** gets node number, where this solution was found */
2173  SCIP_SOL* sol /**< primal CIP solution */
2174  )
2175 {
2176  assert(sol != NULL);
2177 
2178  return sol->nodenum;
2179 }
2180 
2181 /** gets node's depth, where this solution was found */
2183  SCIP_SOL* sol /**< primal CIP solution */
2184  )
2185 {
2186  assert(sol != NULL);
2187 
2188  return sol->depth;
2189 }
2190 
2191 /** gets heuristic, that found this solution (or NULL if it's from the tree) */
2193  SCIP_SOL* sol /**< primal CIP solution */
2194  )
2195 {
2196  assert(sol != NULL);
2197 
2198  return sol->heur;
2199 }
2200 
2201 /** gets current position of solution in array of existing solutions of primal data */
2203  SCIP_SOL* sol /**< primal CIP solution */
2204  )
2205 {
2206  assert(sol != NULL);
2207 
2208  return sol->primalindex;
2209 }
2210 
2211 /** sets current position of solution in array of existing solutions of primal data */
2213  SCIP_SOL* sol, /**< primal CIP solution */
2214  int primalindex /**< new primal index of solution */
2215  )
2216 {
2217  assert(sol != NULL);
2218 
2219  sol->primalindex = primalindex;
2220 }
2221 
2222 /** returns unique index of given solution */
2224  SCIP_SOL* sol /**< primal CIP solution */
2225  )
2226 {
2227  assert(sol != NULL);
2228 
2229  return sol->index;
2230 }
2231 
2232 /** informs the solution that it now belongs to the given primal heuristic */
2234  SCIP_SOL* sol, /**< primal CIP solution */
2235  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
2236  )
2237 {
2238  assert(sol != NULL);
2239 
2240  sol->heur = heur;
2241 }
2242 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
Definition: var.c:16082
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:16183
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16205
SCIP_RETCODE SCIPsolCreateRelaxSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_RELAXATION *relaxation, SCIP_HEUR *heur)
Definition: sol.c:594
SCIP_RETCODE SCIPsolUnlink(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *prob)
Definition: sol.c:943
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4669
SCIP_RETCODE SCIPsolRound(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool *success)
Definition: sol.c:1540
SCIP_RETCODE SCIPsolLinkPseudoSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:854
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4715
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5087
internal methods for storing primal CIP solutions
int solindex
Definition: struct_stat.h:203
int SCIPprobGetNBinVars(SCIP_PROB *prob)
Definition: prob.c:2154
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:19105
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1434
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:652
internal methods for branch and bound tree
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:11962
SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4826
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3269
int depth
Definition: struct_sol.h:60
SCIP_RETCODE SCIPsolLinkNLPSol(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_NLP *nlp)
Definition: sol.c:773
internal methods for clocks and timing issues
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4762
SCIP_Longint nodenum
Definition: struct_sol.h:54
#define NULL
Definition: lpi_spx.cpp:129
SCIP_RETCODE SCIPrealarrayCreate(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem)
Definition: misc.c:2166
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:16426
SCIP_Bool SCIPboolarrayGetVal(SCIP_BOOLARRAY *boolarray, int idx)
Definition: misc.c:3149
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:18637
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:16838
int nintvars
Definition: struct_prob.h:62
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16380
SCIP_RETCODE SCIPsolLinkLPSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:715
SCIP_RETCODE SCIPsolCreateUnknown(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_HEUR *heur)
Definition: sol.c:664
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:4531
SCIP_RETCODE SCIPsolLinkCurrentSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:883
SCIP_HEUR * heur
Definition: struct_sol.h:58
#define FALSE
Definition: def.h:52
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5120
SCIP_Real objoffset
Definition: struct_prob.h:40
SCIP_Bool solved
Definition: struct_lp.h:334
SCIP_RETCODE SCIPsolCopy(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_SOL *sourcesol)
Definition: sol.c:334
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4751
#define TRUE
Definition: def.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
void SCIPsolSetPrimalIndex(SCIP_SOL *sol, int primalindex)
Definition: sol.c:2212
SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:1959
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1757
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:7213
SCIP_Real SCIPsolGetRayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1311
SCIP_RETCODE SCIPsolSetUnknown(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: sol.c:926
SCIP_RETCODE SCIPboolarrayCopy(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem, SCIP_BOOLARRAY *sourceboolarray)
Definition: misc.c:2923
SCIP_Bool SCIPsolsAreEqual(SCIP_SOL *sol1, SCIP_SOL *sol2, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: sol.c:1805
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4848
SCIP_VAR ** fixedvars
Definition: struct_prob.h:55
SCIP_Real mem_arraygrowfac
Definition: struct_set.h:290
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2119
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:14953
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16227
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:631
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4773
SCIP_RETCODE SCIPsolClear(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: sol.c:909
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1761
SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4837
int runnum
Definition: struct_sol.h:59
SCIP_Real SCIPvarGetRelaxSolTransVar(SCIP_VAR *var)
Definition: var.c:12984
internal methods for LP management
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2172
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2162
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:16136
internal methods for collecting primal CIP solutions and primal informations
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1189
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:2223
SCIP_RETCODE SCIPboolarraySetVal(SCIP_BOOLARRAY *boolarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Bool val)
Definition: misc.c:3170
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:18880
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4739
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:15907
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:2500
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:16114
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4703
SCIP_Real SCIPclockGetLastTime(SCIP_CLOCK *clck)
Definition: clock.c:508
SCIP_Bool SCIPnlpIsDivingObjChanged(SCIP_NLP *nlp)
Definition: nlp.c:6295
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:15930
static void solStamp(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_Bool checktime)
Definition: sol.c:246
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1380
int SCIPprobGetNImplVars(SCIP_PROB *prob)
Definition: prob.c:2172
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:18506
void SCIPsolUpdateVarsum(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Real weight)
Definition: sol.c:1617
SCIP_RETCODE SCIPrealarrayCopy(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem, SCIP_REALARRAY *sourcerealarray)
Definition: misc.c:2186
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:18647
#define SCIPdebugPrintf
Definition: pub_message.h:80
SCIP_RETCODE SCIPsolCreateCurrentSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: sol.c:637
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:16125
SCIP_RETCODE SCIPboolarrayCreate(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem)
Definition: misc.c:2903
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:18870
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3873
SCIP_Real SCIPrealarrayGetVal(SCIP_REALARRAY *realarray, int idx)
Definition: misc.c:2410
SCIP_Real primsolavg
Definition: struct_var.h:209
SCIP_Real SCIPnlpGetObjval(SCIP_NLP *nlp)
Definition: nlp.c:5533
SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:972
SCIP_CONSHDLR ** conshdlrs
Definition: struct_set.h:63
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:18848
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:18746
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
internal methods for NLP management
SCIP_Real SCIPsolGetTime(SCIP_SOL *sol)
Definition: sol.c:2152
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5157
static SCIP_RETCODE solIncArrayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var, SCIP_Real incval)
Definition: sol.c:94
internal miscellaneous methods
SCIP_RETCODE SCIPboolarrayClear(SCIP_BOOLARRAY *boolarray)
Definition: misc.c:3118
SCIP_RETCODE SCIPsolPrint(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PROB *transprob, FILE *file, SCIP_Bool printzeros)
Definition: sol.c:1865
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16093
#define REALABS(x)
Definition: def.h:146
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:16159
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3214
static SCIP_RETCODE solUnlinkVar(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var)
Definition: sol.c:185
SCIP_RETCODE SCIPsolCreateOriginal(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_HEUR *heur)
Definition: sol.c:301
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5071
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:578
int primalindex
Definition: struct_sol.h:61
internal methods for relaxators
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4691
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:14839
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2129
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5039
datastructures for storing primal CIP solutions
int SCIPprobGetNIntVars(SCIP_PROB *prob)
Definition: prob.c:2163
SCIP_RETCODE SCIPsolTransform(SCIP_SOL *sol, SCIP_SOL **transsol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal)
Definition: sol.c:369
void SCIPsolRecomputeObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob)
Definition: sol.c:1770
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6155
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:417
internal methods for problem variables
void SCIPvarMarkNotDeletable(SCIP_VAR *var)
Definition: var.c:16032
#define SCIP_UNKNOWN
Definition: def.h:143
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:16436
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:4784
int SCIPsolGetDepth(SCIP_SOL *sol)
Definition: sol.c:2182
SCIP_RETCODE SCIPprimalSolCreated(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_SOL *sol)
Definition: primal.c:1412
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:16773
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16062
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2192
#define SCIP_Bool
Definition: def.h:49
int nbinvars
Definition: struct_prob.h:61
SCIP_Real SCIPprobGetObjoffset(SCIP_PROB *prob)
Definition: prob.c:2199
SCIP_NLPSOLSTAT SCIPnlpGetSolstat(SCIP_NLP *nlp)
Definition: nlp.c:5923
SCIP_RETCODE SCIPsolIncVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real incval)
Definition: sol.c:1116
SCIP_RETCODE SCIPsolCreate(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_HEUR *heur)
Definition: sol.c:269
int mem_arraygrowinit
Definition: struct_set.h:293
SCIP_RETCODE SCIPrealarrayFree(SCIP_REALARRAY **realarray)
Definition: misc.c:2210
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:19115
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPsolRetransform(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_Bool *hasinfval)
Definition: sol.c:1645
void SCIPsolOrigAddObjval(SCIP_SOL *sol, SCIP_Real addval)
Definition: sol.c:2140
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:16216
static SCIP_RETCODE solSetArrayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:63
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:7230
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:16147
int SCIPnlpGetNVars(SCIP_NLP *nlp)
Definition: nlp.c:5746
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:16171
SCIP_Bool transformed
Definition: struct_prob.h:78
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5023
int nfixedvars
Definition: struct_prob.h:67
SCIP_RETCODE SCIPsolPrintRay(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PROB *transprob, FILE *file, SCIP_Bool printzeros)
Definition: sol.c:1974
SCIP_RETCODE SCIPsolAdjustImplicitSolVals(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool uselprows)
Definition: sol.c:415
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:16760
SCIP_SOLORIGIN solorigin
Definition: struct_sol.h:63
static SCIP_RETCODE solClearArrays(SCIP_SOL *sol)
Definition: sol.c:49
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:14878
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
SCIP_RETCODE SCIPsolLinkRelaxSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_RELAXATION *relaxation)
Definition: sol.c:824
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5146
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16370
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2109
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:2233
static const SCIP_Real scalars[]
Definition: lp.c:5431
SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition: var.c:12049
SCIP_RETCODE SCIPsolCreateLPSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: sol.c:550
SCIP_RETCODE SCIPvarGetActiveRepresentatives(SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: var.c:3739
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:114
SCIP_RETCODE SCIPconshdlrCheck(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
Definition: cons.c:3429
SCIP_RETCODE SCIPboolarrayFree(SCIP_BOOLARRAY **boolarray)
Definition: misc.c:2947
public methods for message output
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16072
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:602
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:4727
static SCIP_Real solGetArrayVal(SCIP_SOL *sol, SCIP_VAR *var)
Definition: sol.c:135
int SCIPsolGetPrimalIndex(SCIP_SOL *sol)
Definition: sol.c:2202
void SCIPsolUpdateVarObj(SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: sol.c:1397
SCIP_Real time
Definition: struct_sol.h:53
#define SCIP_Real
Definition: def.h:123
internal methods for problem statistics
SCIP_RETCODE SCIPsolCheck(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
Definition: sol.c:1416
SCIP_VAR ** vars
Definition: struct_prob.h:54
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:19085
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5098
SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
Definition: prob.c:2190
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3277
#define SCIP_INVALID
Definition: def.h:142
enum SCIP_SolOrigin SCIP_SOLORIGIN
Definition: type_sol.h:43
internal methods for constraints and constraint handlers
SCIP_Real primsol
Definition: struct_lp.h:135
SCIP_REALARRAY * vals
Definition: struct_sol.h:55
#define SCIP_Longint
Definition: def.h:107
SCIP_VAR ** SCIPnlpGetVars(SCIP_NLP *nlp)
Definition: nlp.c:5736
SCIP_RETCODE SCIPsolCreateNLPSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_NLP *nlp, SCIP_HEUR *heur)
Definition: sol.c:573
#define SCIPisFinite(x)
Definition: pub_misc.h:4984
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5055
SCIP_RETCODE SCIPrealarraySetVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real val)
Definition: misc.c:2431
SCIP_BOOLARRAY * valid
Definition: struct_sol.h:56
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16052
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:404
int nconshdlrs
Definition: struct_set.h:87
SCIP_RETCODE SCIPsolCreatePseudoSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: sol.c:616
common defines and data types used in all packages of SCIP
SCIP_Longint nnodes
Definition: struct_stat.h:63
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:371
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:18407
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:18516
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:18481
#define SCIP_ALLOC(x)
Definition: def.h:269
#define SCIPABORT()
Definition: def.h:230
SCIP_Bool hasinfval
Definition: struct_sol.h:64
SCIP_Real obj
Definition: struct_sol.h:52
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3159
int index
Definition: struct_sol.h:62
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5109
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:696