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-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file sol.c
17  * @ingroup OTHER_CFILES
18  * @brief methods for storing primal CIP solutions
19  * @author Tobias Achterberg
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include "scip/clock.h"
25 #include "scip/cons.h"
26 #include "scip/lp.h"
27 #include "scip/misc.h"
28 #include "scip/nlp.h"
29 #include "scip/primal.h"
30 #include "scip/prob.h"
31 #include "scip/pub_lp.h"
32 #include "scip/pub_message.h"
33 #include "scip/pub_sol.h"
34 #include "scip/pub_var.h"
35 #include "scip/relax.h"
36 #include "scip/set.h"
37 #include "scip/sol.h"
38 #include "scip/stat.h"
39 #include "scip/struct_lp.h"
40 #include "scip/struct_prob.h"
41 #include "scip/struct_set.h"
42 #include "scip/struct_sol.h"
43 #include "scip/struct_stat.h"
44 #include "scip/struct_var.h"
45 #include "scip/tree.h"
46 #include "scip/var.h"
47 
48 
49 
50 /** clears solution arrays of primal CIP solution */
51 static
53  SCIP_SOL* sol /**< primal CIP solution */
54  )
55 {
56  assert(sol != NULL);
57 
59  sol->hasinfval = FALSE;
60 
61  return SCIP_OKAY;
62 }
63 
64 /** sets value of variable in the solution's array */
65 static
67  SCIP_SOL* sol, /**< primal CIP solution */
68  SCIP_SET* set, /**< global SCIP settings */
69  SCIP_VAR* var, /**< problem variable */
70  SCIP_Real val /**< value to set variable to */
71  )
72 {
73  int idx;
74 
75  assert(sol != NULL);
76 
77  idx = SCIPvarGetIndex(var);
78 
79  /* from now on, variable must not be deleted */
81 
82  /* mark the variable valid */
83  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, TRUE) );
84 
85  /* set the value in the solution array */
86  SCIP_CALL( SCIPrealarraySetVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, val) );
87 
88  /* store whether the solution has infinite values assigned to variables */
89  if( val != SCIP_UNKNOWN ) /*lint !e777*/
90  sol->hasinfval = (sol->hasinfval || SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val));
91 
92  return SCIP_OKAY;
93 }
94 
95 /** increases value of variable in the solution's array */
96 static
98  SCIP_SOL* sol, /**< primal CIP solution */
99  SCIP_SET* set, /**< global SCIP settings */
100  SCIP_VAR* var, /**< problem variable */
101  SCIP_Real incval /**< increase of variable's solution value */
102  )
103 {
104  int idx;
105 
106  assert(sol != NULL);
107 
108  idx = SCIPvarGetIndex(var);
109 
110  /* from now on, variable must not be deleted */
112 
113  /* 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) */
114  if( !SCIPboolarrayGetVal(sol->valid, idx) )
115  {
116  /* mark the variable valid */
117  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, TRUE) );
118 
119  /* set the value in the solution array */
120  SCIP_CALL( SCIPrealarraySetVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, incval) );
121  }
122  else
123  {
124  /* increase the value in the solution array */
125  SCIP_CALL( SCIPrealarrayIncVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, incval) );
126  }
127 
128  /* store whether the solution has infinite values assigned to variables */
129  incval = SCIPrealarrayGetVal(sol->vals, idx);
130  if( incval != SCIP_UNKNOWN ) /*lint !e777*/
131  sol->hasinfval = (sol->hasinfval || SCIPsetIsInfinity(set, incval) || SCIPsetIsInfinity(set, -incval));
132 
133  return SCIP_OKAY;
134 }
135 
136 /** returns the value of the variable in the given solution */
137 static
139  SCIP_SOL* sol, /**< primal CIP solution */
140  SCIP_VAR* var /**< problem variable */
141  )
142 {
143  int idx;
144 
145  assert(sol != NULL);
146 
147  idx = SCIPvarGetIndex(var);
148 
149  /* check, if the variable's value is valid */
150  if( SCIPboolarrayGetVal(sol->valid, idx) )
151  {
152  return SCIPrealarrayGetVal(sol->vals, idx);
153  }
154  else
155  {
156  /* return the variable's value corresponding to the origin */
157  switch( sol->solorigin )
158  {
160  case SCIP_SOLORIGIN_ZERO:
161  return 0.0;
162 
164  return SCIPvarGetLPSol(var);
165 
167  return SCIPvarGetNLPSol(var);
168 
170  return SCIPvarGetRelaxSolTransVar(var);
171 
173  return SCIPvarGetPseudoSol(var);
174 
177  return SCIP_UNKNOWN;
178 
179  default:
180  SCIPerrorMessage("unknown solution origin <%d>\n", sol->solorigin);
181  SCIPABORT();
182  return 0.0; /*lint !e527*/
183  }
184  }
185 }
186 
187 /** stores solution value of variable in solution's own array */
188 static
190  SCIP_SOL* sol, /**< primal CIP solution */
191  SCIP_SET* set, /**< global SCIP settings */
192  SCIP_VAR* var /**< problem variable */
193  )
194 {
195  SCIP_Real solval;
196 
197  assert(sol != NULL);
198  assert(var != NULL);
199  assert(SCIPvarIsTransformed(var));
201 
202  /* if variable is already valid, nothing has to be done */
203  if( SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var)) )
204  return SCIP_OKAY;
205 
206  SCIPsetDebugMsg(set, "unlinking solution value of variable <%s>\n", SCIPvarGetName(var));
207 
208  /* store the correct solution value into the solution array */
209  switch( sol->solorigin )
210  {
212  SCIPerrorMessage("cannot unlink solutions of original problem space\n");
213  return SCIP_INVALIDDATA;
214 
215  case SCIP_SOLORIGIN_ZERO:
216  return SCIP_OKAY;
217 
219  solval = SCIPvarGetLPSol(var);
220  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
221  return SCIP_OKAY;
222 
224  solval = SCIPvarGetNLPSol(var);
225  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
226  return SCIP_OKAY;
227 
229  solval = SCIPvarGetRelaxSolTransVar(var);
230  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
231  return SCIP_OKAY;
232 
234  solval = SCIPvarGetPseudoSol(var);
235  SCIP_CALL( solSetArrayVal(sol, set, var, solval) );
236  return SCIP_OKAY;
237 
240  SCIP_CALL( solSetArrayVal(sol, set, var, SCIP_UNKNOWN) );
241  return SCIP_OKAY;
242 
243  default:
244  SCIPerrorMessage("unknown solution origin <%d>\n", sol->solorigin);
245  return SCIP_INVALIDDATA;
246  }
247 }
248 
249 /** sets the solution time, nodenum, runnum, and depth stamp to the current values */
250 static
251 void solStamp(
252  SCIP_SOL* sol, /**< primal CIP solution */
253  SCIP_STAT* stat, /**< problem statistics data */
254  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
255  SCIP_Bool checktime /**< should the time be updated? */
256  )
257 {
258  assert(sol != NULL);
259  assert(stat != NULL);
260 
261  if( checktime )
262  {
263  sol->time = SCIPclockGetTime(stat->solvingtime);
264 #ifndef NDEBUG
265  sol->lpcount = stat->lpcount;
266 #endif
267  }
268  else
269  sol->time = SCIPclockGetLastTime(stat->solvingtime);
270  sol->nodenum = stat->nnodes;
271  sol->runnum = stat->nruns;
272  if( tree == NULL )
273  sol->depth = -1;
274  else
275  sol->depth = SCIPtreeGetCurrentDepth(tree);
276 }
277 
278 /** creates primal CIP solution, initialized to zero */
280  SCIP_SOL** sol, /**< pointer to primal CIP solution */
281  BMS_BLKMEM* blkmem, /**< block memory */
282  SCIP_SET* set, /**< global SCIP settings */
283  SCIP_STAT* stat, /**< problem statistics data */
284  SCIP_PRIMAL* primal, /**< primal data */
285  SCIP_TREE* tree, /**< branch and bound tree */
286  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
287  )
288 {
289  assert(sol != NULL);
290  assert(blkmem != NULL);
291  assert(stat != NULL);
292 
293  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
294  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
295  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
296 
297  (*sol)->solorigin = SCIP_SOLORIGIN_ZERO;
298  (*sol)->obj = 0.0;
299  (*sol)->primalindex = -1;
300  (*sol)->index = stat->solindex;
301  (*sol)->hasinfval = FALSE;
303  stat->solindex++;
304  solStamp(*sol, stat, tree, TRUE);
306 
307  /* set solution type and creator depending on whether a heuristic or NULL is passed */
308  SCIPsolSetHeur(*sol, heur);
309 
310  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
311 
312  return SCIP_OKAY;
313 }
314 
315 /** creates primal CIP solution in original problem space, initialized to the offset in the original problem */
317  SCIP_SOL** sol, /**< pointer to primal CIP solution */
318  BMS_BLKMEM* blkmem, /**< block memory */
319  SCIP_SET* set, /**< global SCIP settings */
320  SCIP_STAT* stat, /**< problem statistics data */
321  SCIP_PROB* origprob, /**< original problem data */
322  SCIP_PRIMAL* primal, /**< primal data */
323  SCIP_TREE* tree, /**< branch and bound tree */
324  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
325  )
326 {
327  assert(sol != NULL);
328  assert(blkmem != NULL);
329  assert(stat != NULL);
330 
331  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
332  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
333  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
334  (*sol)->solorigin = SCIP_SOLORIGIN_ORIGINAL;
335  (*sol)->obj = origprob->objoffset;
336  (*sol)->primalindex = -1;
337  (*sol)->index = stat->solindex;
338  (*sol)->hasinfval = FALSE;
339  stat->solindex++;
340  solStamp(*sol, stat, tree, TRUE);
341 
342  /* set solution type and creator depending on whether a heuristic or NULL is passed */
343  SCIPsolSetHeur(*sol, heur);
344 
346 
347  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
348 
349  return SCIP_OKAY;
350 }
351 
352 /** creates a copy of a primal CIP solution */
354  SCIP_SOL** sol, /**< pointer to store the copy of the primal CIP solution */
355  BMS_BLKMEM* blkmem, /**< block memory */
356  SCIP_SET* set, /**< global SCIP settings */
357  SCIP_STAT* stat, /**< problem statistics data */
358  SCIP_PRIMAL* primal, /**< primal data */
359  SCIP_SOL* sourcesol /**< primal CIP solution to copy */
360  )
361 {
362  assert(sol != NULL);
363  assert(sourcesol != NULL);
364 
365  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
366  SCIP_CALL( SCIPrealarrayCopy(&(*sol)->vals, blkmem, sourcesol->vals) );
367  SCIP_CALL( SCIPboolarrayCopy(&(*sol)->valid, blkmem, sourcesol->valid) );
368 
369  /* copy solution type and creator information */
370  switch( sourcesol->type )
371  {
375  case SCIP_SOLTYPE_PSEUDO:
376  (*sol)->type = sourcesol->type;
377  break;
378  case SCIP_SOLTYPE_HEUR:
379  SCIPsolSetHeur((*sol), SCIPsolGetHeur(sourcesol));
380  break;
381  case SCIP_SOLTYPE_RELAX:
382  SCIPsolSetRelax((*sol), SCIPsolGetRelax(sourcesol));
383  break;
384  default:
385  SCIPerrorMessage("Unknown source solution type %d!\n", sourcesol->type);
386  return SCIP_INVALIDDATA;
387  }
388  (*sol)->obj = sourcesol->obj;
389  (*sol)->primalindex = -1;
390  (*sol)->time = sourcesol->time;
391 #ifndef NDEBUG
392  (*sol)->lpcount = sourcesol->lpcount;
393 #endif
394  (*sol)->nodenum = sourcesol->nodenum;
395  (*sol)->solorigin = sourcesol->solorigin;
396  (*sol)->runnum = sourcesol->runnum;
397  (*sol)->depth = sourcesol->depth;
398  (*sol)->index = stat->solindex;
399  (*sol)->hasinfval = sourcesol->hasinfval;
400  stat->solindex++;
401  (*sol)->viol.absviolbounds = sourcesol->viol.absviolbounds;
402  (*sol)->viol.absviolcons = sourcesol->viol.absviolcons;
403  (*sol)->viol.absviolintegrality = sourcesol->viol.absviolintegrality;
404  (*sol)->viol.absviollprows = sourcesol->viol.absviollprows;
405  (*sol)->viol.relviolbounds = sourcesol->viol.relviolbounds;
406  (*sol)->viol.relviolcons = sourcesol->viol.relviolcons;
407  (*sol)->viol.relviollprows = sourcesol->viol.relviollprows;
408 
409  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
410 
411  return SCIP_OKAY;
412 }
413 
414 /** transformes given original solution to the transformed space; a corresponding transformed solution has to be given
415  * which is copied into the existing solution and freed afterwards
416  */
418  SCIP_SOL* sol, /**< primal CIP solution to change, living in original space */
419  SCIP_SOL** transsol, /**< pointer to corresponding transformed primal CIP solution */
420  BMS_BLKMEM* blkmem, /**< block memory */
421  SCIP_SET* set, /**< global SCIP settings */
422  SCIP_PRIMAL* primal /**< primal data */
423  )
424 { /*lint --e{715}*/
425  SCIP_REALARRAY* tmpvals;
426  SCIP_BOOLARRAY* tmpvalid;
427  SCIP_SOL* tsol;
428 
429  assert(sol != NULL);
430  assert(transsol != NULL);
431  assert(set != NULL);
432  assert(SCIPsolIsOriginal(sol));
433  assert(sol->primalindex > -1);
434 
435  tsol = *transsol;
436  assert(tsol != NULL);
437  assert(!SCIPsolIsOriginal(tsol));
438 
439  /* switch vals and valid arrays; the exisiting solution gets the arrays of the transformed solution;
440  * the transformed one gets the original arrays, because they have to be freed anyway and freeing the transsol
441  * automatically frees its arrays
442  */
443  tmpvals = sol->vals;
444  tmpvalid = sol->valid;
445  sol->vals = tsol->vals;
446  sol->valid = tsol->valid;
447  tsol->vals = tmpvals;
448  tsol->valid = tmpvalid;
449 
450  /* copy solorigin and objective (should be the same, only to avoid numerical issues);
451  * we keep the other statistics of the original solution, since that was the first time that this solution as found
452  */
453  sol->solorigin = tsol->solorigin;
454  sol->obj = tsol->obj;
455 
456  SCIP_CALL( SCIPsolFree(transsol, blkmem, primal) );
457 
458  return SCIP_OKAY;
459 }
460 
461 /** adjusts solution values of implicit integer variables in handed solution. Solution objective value is not
462  * deteriorated by this method.
463  */
465  SCIP_SOL* sol, /**< primal CIP solution */
466  SCIP_SET* set, /**< global SCIP settings */
467  SCIP_STAT* stat, /**< problem statistics data */
468  SCIP_PROB* prob, /**< either original or transformed problem, depending on sol origin */
469  SCIP_TREE* tree, /**< branch and bound tree */
470  SCIP_Bool uselprows /**< should LP row information be considered for none-objective variables */
471  )
472 {
473  SCIP_VAR** vars;
474  int nimplvars;
475  int nbinvars;
476  int nintvars;
477  int v;
478 
479  assert(sol != NULL);
480  assert(prob != NULL);
481 
482  /* get variable data */
483  vars = SCIPprobGetVars(prob);
484  nbinvars = SCIPprobGetNBinVars(prob);
485  nintvars = SCIPprobGetNIntVars(prob);
486  nimplvars = SCIPprobGetNImplVars(prob);
487 
488  if( nimplvars == 0 )
489  return SCIP_OKAY;
490 
491  /* calculate the last array position of implicit integer variables */
492  nimplvars = nbinvars + nintvars + nimplvars;
493 
494  /* loop over implicit integer variables and round them up or down */
495  for( v = nbinvars + nintvars; v < nimplvars; ++v )
496  {
497  SCIP_VAR* var;
498  SCIP_Real solval;
499  SCIP_Real obj;
500  SCIP_Real newsolval;
501  SCIP_Bool roundup;
502  SCIP_Bool rounddown;
503  int nuplocks;
504  int ndownlocks;
505 
506  var = vars[v];
507 
508  assert( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT );
509  solval = SCIPsolGetVal(sol, set, stat, var);
510 
511  /* we do not need to round integral solution values or those of variables which are not column variables */
512  if( SCIPsetIsFeasIntegral(set, solval) || SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN )
513  continue;
514 
517  obj = SCIPvarGetUnchangedObj(var);
518 
519  roundup = FALSE;
520  rounddown = FALSE;
521 
522  /* in case of a non-zero objective coefficient, there is only one possible rounding direction */
523  if( SCIPsetIsFeasNegative(set, obj) )
524  roundup = TRUE;
525  else if( SCIPsetIsFeasPositive(set, obj) )
526  rounddown = TRUE;
527  else if( uselprows )
528  {
529  /* determine rounding direction based on row violations */
530  SCIP_COL* col;
531  SCIP_ROW** rows;
532  SCIP_Real* vals;
533  int nrows;
534  int r;
535 
536  col = SCIPvarGetCol(var);
537  vals = SCIPcolGetVals(col);
538  rows = SCIPcolGetRows(col);
539  nrows = SCIPcolGetNNonz(col);
540 
541  /* loop over rows and search for equations whose violation can be decreased by rounding */
542  for( r = 0; r < nrows && !(roundup && rounddown); ++r )
543  {
544  SCIP_ROW* row;
545  SCIP_Real activity;
546  SCIP_Real rhs;
547  SCIP_Real lhs;
548 
549  row = rows[r];
550 
551  if( SCIProwIsLocal(row) || !SCIProwIsInLP(row) )
552  continue;
553 
554  rhs = SCIProwGetRhs(row);
555  lhs = SCIProwGetLhs(row);
556 
557  if( SCIPsetIsInfinity(set, rhs) || SCIPsetIsInfinity(set, -lhs) )
558  continue;
559 
560  activity = SCIProwGetSolActivity(row, set, stat, sol);
561  if( SCIPsetIsFeasLE(set, activity, rhs) && SCIPsetIsFeasLE(set, lhs, activity) )
562  continue;
563 
564  assert(! SCIPsetIsZero(set, vals[r]));
565  if( (SCIPsetIsFeasGT(set, activity, rhs) && SCIPsetIsPositive(set, vals[r]))
566  || (SCIPsetIsFeasLT(set, activity, lhs) && SCIPsetIsNegative(set, vals[r])) )
567  rounddown = TRUE;
568  else
569  roundup = TRUE;
570  }
571  }
572 
573  /* in case of a tie, we select the rounding step based on the number of variable locks */
574  if( roundup == rounddown )
575  {
576  rounddown = ndownlocks <= nuplocks;
577  roundup = !rounddown;
578  }
579 
580  /* round the variable up or down */
581  if( roundup )
582  {
583  newsolval = SCIPsetCeil(set, solval);
584  assert(SCIPsetIsFeasLE(set, newsolval, SCIPvarGetUbGlobal(var)));
585  }
586  else
587  {
588  assert( rounddown ); /* should be true because of the code above */
589  newsolval = SCIPsetFloor(set, solval);
590  assert(SCIPsetIsFeasGE(set, newsolval, SCIPvarGetLbGlobal(var)));
591  }
592 
593  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, newsolval) );
594  }
595 
596  return SCIP_OKAY;
597 }
598 /** creates primal CIP solution, initialized to the current LP solution */
600  SCIP_SOL** sol, /**< pointer to primal CIP solution */
601  BMS_BLKMEM* blkmem, /**< block memory */
602  SCIP_SET* set, /**< global SCIP settings */
603  SCIP_STAT* stat, /**< problem statistics data */
604  SCIP_PROB* prob, /**< transformed problem data */
605  SCIP_PRIMAL* primal, /**< primal data */
606  SCIP_TREE* tree, /**< branch and bound tree */
607  SCIP_LP* lp, /**< current LP data */
608  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
609  )
610 {
611  assert(sol != NULL);
612  assert(lp != NULL);
613  assert(SCIPlpIsSolved(lp));
614 
615  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
616  SCIP_CALL( SCIPsolLinkLPSol(*sol, set, stat, prob, tree, lp) );
617 
618  return SCIP_OKAY;
619 }
620 
621 /** creates primal CIP solution, initialized to the current NLP solution */
623  SCIP_SOL** sol, /**< pointer to primal CIP solution */
624  BMS_BLKMEM* blkmem, /**< block memory */
625  SCIP_SET* set, /**< global SCIP settings */
626  SCIP_STAT* stat, /**< problem statistics data */
627  SCIP_PRIMAL* primal, /**< primal data */
628  SCIP_TREE* tree, /**< branch and bound tree */
629  SCIP_NLP* nlp, /**< current NLP data */
630  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
631  )
632 {
633  assert(sol != NULL);
634  assert(nlp != NULL);
635 
636  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
637  SCIP_CALL( SCIPsolLinkNLPSol(*sol, stat, tree, nlp) );
638 
639  return SCIP_OKAY;
640 }
641 
642 /** creates primal CIP solution, initialized to the current relaxation solution */
644  SCIP_SOL** sol, /**< pointer to primal CIP solution */
645  BMS_BLKMEM* blkmem, /**< block memory */
646  SCIP_SET* set, /**< global SCIP settings */
647  SCIP_STAT* stat, /**< problem statistics data */
648  SCIP_PRIMAL* primal, /**< primal data */
649  SCIP_TREE* tree, /**< branch and bound tree */
650  SCIP_RELAXATION* relaxation, /**< global relaxation data */
651  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
652  )
653 {
654  assert(sol != NULL);
655  assert(relaxation != NULL);
656  assert(SCIPrelaxationIsSolValid(relaxation));
657 
658  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
659  SCIP_CALL( SCIPsolLinkRelaxSol(*sol, set, stat, tree, relaxation) );
660 
661  /* update solution type and store relaxator as creator only if no heuristic is specified as creator */
662  if( heur == NULL )
663  SCIPsolSetRelax(*sol, SCIPrelaxationGetSolRelax(relaxation));
664 
665  return SCIP_OKAY;
666 }
667 
668 /** creates primal CIP solution, initialized to the current pseudo solution */
670  SCIP_SOL** sol, /**< pointer to primal CIP solution */
671  BMS_BLKMEM* blkmem, /**< block memory */
672  SCIP_SET* set, /**< global SCIP settings */
673  SCIP_STAT* stat, /**< problem statistics data */
674  SCIP_PROB* prob, /**< transformed problem data */
675  SCIP_PRIMAL* primal, /**< primal data */
676  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
677  SCIP_LP* lp, /**< current LP data */
678  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
679  )
680 {
681  assert(sol != NULL);
682 
683  SCIP_CALL( SCIPsolCreate(sol, blkmem, set, stat, primal, tree, heur) );
684  SCIP_CALL( SCIPsolLinkPseudoSol(*sol, set, stat, prob, tree, lp) );
685 
686  /* update solution type to pseudo solution */
687  if( heur == NULL )
688  SCIPsolSetPseudo(*sol);
689 
690  return SCIP_OKAY;
691 }
692 
693 /** creates primal CIP solution, initialized to the current solution */
695  SCIP_SOL** sol, /**< pointer to primal CIP solution */
696  BMS_BLKMEM* blkmem, /**< block memory */
697  SCIP_SET* set, /**< global SCIP settings */
698  SCIP_STAT* stat, /**< problem statistics data */
699  SCIP_PROB* prob, /**< transformed problem data */
700  SCIP_PRIMAL* primal, /**< primal data */
701  SCIP_TREE* tree, /**< branch and bound tree */
702  SCIP_LP* lp, /**< current LP data */
703  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
704  )
705 {
706  assert(tree != NULL);
707 
708  if( SCIPtreeHasCurrentNodeLP(tree) )
709  {
710  SCIP_CALL( SCIPsolCreateLPSol(sol, blkmem, set, stat, prob, primal, tree, lp, heur) );
711  }
712  else
713  {
714  SCIP_CALL( SCIPsolCreatePseudoSol(sol, blkmem, set, stat, prob, primal, tree, lp, heur) );
715  }
716 
717  return SCIP_OKAY;
718 }
719 
720 /** creates partial primal CIP solution, initialized to unknown values */
722  SCIP_SOL** sol, /**< pointer to primal CIP solution */
723  BMS_BLKMEM* blkmem, /**< block memory */
724  SCIP_SET* set, /**< global SCIP settings */
725  SCIP_STAT* stat, /**< problem statistics data */
726  SCIP_PRIMAL* primal, /**< primal data */
727  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
728  )
729 {
730  assert(sol != NULL);
731  assert(blkmem != NULL);
732  assert(set != NULL);
733  assert(stat != NULL);
734  assert(primal != NULL);
735 
736  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
737  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
738  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
739  (*sol)->solorigin = SCIP_SOLORIGIN_PARTIAL;
740  (*sol)->obj = SCIP_UNKNOWN;
741  (*sol)->primalindex = -1;
742  (*sol)->index = stat->solindex;
743  (*sol)->hasinfval = FALSE;
744  stat->solindex++;
745  solStamp(*sol, stat, NULL, TRUE);
747 
748  /* set solution type and creator depending on whether a heuristic or NULL is passed */
749  SCIPsolSetHeur(*sol, heur);
750 
751  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
752 
753  return SCIP_OKAY;
754 }
755 
756 /** creates primal CIP solution, initialized to unknown values */
758  SCIP_SOL** sol, /**< pointer to primal CIP solution */
759  BMS_BLKMEM* blkmem, /**< block memory */
760  SCIP_SET* set, /**< global SCIP settings */
761  SCIP_STAT* stat, /**< problem statistics data */
762  SCIP_PRIMAL* primal, /**< primal data */
763  SCIP_TREE* tree, /**< branch and bound tree */
764  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
765  )
766 {
767  assert(sol != NULL);
768  assert(blkmem != NULL);
769  assert(stat != NULL);
770 
771  SCIP_ALLOC( BMSallocBlockMemory(blkmem, sol) );
772  SCIP_CALL( SCIPrealarrayCreate(&(*sol)->vals, blkmem) );
773  SCIP_CALL( SCIPboolarrayCreate(&(*sol)->valid, blkmem) );
774  (*sol)->solorigin = SCIP_SOLORIGIN_UNKNOWN;
775  (*sol)->obj = 0.0;
776  (*sol)->primalindex = -1;
777  (*sol)->index = stat->solindex;
778  (*sol)->hasinfval = FALSE;
779  stat->solindex++;
780  solStamp(*sol, stat, tree, TRUE);
782 
783  /* set solution type and creator depending on whether a heuristic or NULL is passed */
784  SCIPsolSetHeur(*sol, heur);
785 
786  SCIP_CALL( SCIPprimalSolCreated(primal, set, *sol) );
787 
788  return SCIP_OKAY;
789 }
790 
791 /** frees primal CIP solution */
793  SCIP_SOL** sol, /**< pointer to primal CIP solution */
794  BMS_BLKMEM* blkmem, /**< block memory */
795  SCIP_PRIMAL* primal /**< primal data */
796  )
797 {
798  assert(sol != NULL);
799  assert(*sol != NULL);
800 
801  SCIPprimalSolFreed(primal, *sol);
802 
803  SCIP_CALL( SCIPrealarrayFree(&(*sol)->vals) );
804  SCIP_CALL( SCIPboolarrayFree(&(*sol)->valid) );
805  BMSfreeBlockMemory(blkmem, sol);
806 
807  return SCIP_OKAY;
808 }
809 
810 /** copies current LP solution into CIP solution by linking */
812  SCIP_SOL* sol, /**< primal CIP solution */
813  SCIP_SET* set, /**< global SCIP settings */
814  SCIP_STAT* stat, /**< problem statistics data */
815  SCIP_PROB* prob, /**< transformed problem data */
816  SCIP_TREE* tree, /**< branch and bound tree */
817  SCIP_LP* lp /**< current LP data */
818  )
819 {
820  assert(sol != NULL);
821  assert(stat != NULL);
822  assert(tree != NULL);
823  assert(lp != NULL);
824  assert(lp->solved);
825  assert(SCIPlpDiving(lp) || SCIPtreeProbing(tree) || !SCIPlpDivingObjChanged(lp));
826 
827  SCIPsetDebugMsg(set, "linking solution to LP\n");
828 
829  /* clear the old solution arrays */
830  SCIP_CALL( solClearArrays(sol) );
831 
832  /* link solution to LP solution */
833  if( SCIPlpDivingObjChanged(lp) )
834  {
835  /* the objective value has to be calculated manually, because the LP's value is invalid;
836  * use objective values of variables, because columns objective values are changed to dive values
837  */
838  sol->obj = SCIPlpGetLooseObjval(lp, set, prob);
839  if( !SCIPsetIsInfinity(set, -sol->obj) )
840  {
841  SCIP_VAR* var;
842  SCIP_COL** cols;
843  int ncols;
844  int c;
845 
846  cols = SCIPlpGetCols(lp);
847  ncols = SCIPlpGetNCols(lp);
848  for( c = 0; c < ncols; ++c )
849  {
850  var = SCIPcolGetVar(cols[c]);
851  sol->obj += SCIPvarGetUnchangedObj(var) * cols[c]->primsol;
852  }
853  }
854  }
855  else
856  {
857  /* the objective value in the columns is correct, s.t. the LP's objective value is also correct */
858  sol->obj = SCIPlpGetObjval(lp, set, prob);
859  }
861  solStamp(sol, stat, tree, TRUE);
862 
863  SCIPsetDebugMsg(set, " -> objective value: %g\n", sol->obj);
864 
865  return SCIP_OKAY;
866 }
867 
868 /** copies current NLP solution into CIP solution by linking */
870  SCIP_SOL* sol, /**< primal CIP solution */
871  SCIP_STAT* stat, /**< problem statistics data */
872  SCIP_TREE* tree, /**< branch and bound tree */
873  SCIP_NLP* nlp /**< current NLP data */
874  )
875 {
876  assert(sol != NULL);
877  assert(stat != NULL);
878  assert(tree != NULL);
879  assert(nlp != NULL);
881 
882  SCIPstatDebugMsg(stat, "linking solution to NLP\n");
883 
884  /* clear the old solution arrays */
885  SCIP_CALL( solClearArrays(sol) );
886 
887  /* get objective value of NLP solution */
888  if( SCIPnlpIsDivingObjChanged(nlp) )
889  {
890  /* the objective value has to be calculated manually, because the NLP's value is invalid */
891 
892  SCIP_VAR** vars;
893  int nvars;
894  int v;
895 
896  sol->obj = 0.0;
897 
898  vars = SCIPnlpGetVars(nlp);
899  nvars = SCIPnlpGetNVars(nlp);
900  for( v = 0; v < nvars; ++v )
901  {
902  assert(SCIPvarIsActive(vars[v]));
903  sol->obj += SCIPvarGetUnchangedObj(vars[v]) * SCIPvarGetNLPSol(vars[v]);
904  }
905  }
906  else
907  {
908  sol->obj = SCIPnlpGetObjval(nlp);
909  }
910 
912  solStamp(sol, stat, tree, TRUE);
913 
914  SCIPstatDebugMsg(stat, " -> objective value: %g\n", sol->obj);
915 
916  return SCIP_OKAY;
917 }
918 
919 /** copies current relaxation solution into CIP solution by linking */
921  SCIP_SOL* sol, /**< primal CIP solution */
922  SCIP_SET* set, /**< global SCIP settings */
923  SCIP_STAT* stat, /**< problem statistics data */
924  SCIP_TREE* tree, /**< branch and bound tree */
925  SCIP_RELAXATION* relaxation /**< global relaxation data */
926  )
927 { /*lint --e{715}*/
928  assert(sol != NULL);
929  assert(stat != NULL);
930  assert(tree != NULL);
931  assert(relaxation != NULL);
932  assert(SCIPrelaxationIsSolValid(relaxation));
933 
934  SCIPsetDebugMsg(set, "linking solution to relaxation\n");
935 
936  /* clear the old solution arrays */
937  SCIP_CALL( solClearArrays(sol) );
938 
939  /* the objective value in the columns is correct, s.t. the LP's objective value is also correct */
940  sol->obj = SCIPrelaxationGetSolObj(relaxation);
942  solStamp(sol, stat, tree, TRUE);
943 
944  SCIPsetDebugMsg(set, " -> objective value: %g\n", sol->obj);
945 
946  return SCIP_OKAY;
947 }
948 
949 /** copies current pseudo solution into CIP solution by linking */
951  SCIP_SOL* sol, /**< primal CIP solution */
952  SCIP_SET* set, /**< global SCIP settings */
953  SCIP_STAT* stat, /**< problem statistics data */
954  SCIP_PROB* prob, /**< transformed problem data */
955  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
956  SCIP_LP* lp /**< current LP data */
957  )
958 {
959  assert(sol != NULL);
960  assert(stat != NULL);
961  assert(tree != NULL);
962 
963  SCIPsetDebugMsg(set, "linking solution to pseudo solution\n");
964 
965  /* clear the old solution arrays */
966  SCIP_CALL( solClearArrays(sol) );
967 
968  /* link solution to pseudo solution */
969  sol->obj = SCIPlpGetPseudoObjval(lp, set, prob);
971  solStamp(sol, stat, tree, TRUE);
972 
973  SCIPsetDebugMsg(set, " -> objective value: %g\n", sol->obj);
974 
975  return SCIP_OKAY;
976 }
977 
978 /** copies current solution (LP or pseudo solution) into CIP solution by linking */
980  SCIP_SOL* sol, /**< primal CIP solution */
981  SCIP_SET* set, /**< global SCIP settings */
982  SCIP_STAT* stat, /**< problem statistics data */
983  SCIP_PROB* prob, /**< transformed problem data */
984  SCIP_TREE* tree, /**< branch and bound tree */
985  SCIP_LP* lp /**< current LP data */
986  )
987 {
988  assert(tree != NULL);
989 
990  SCIPsetDebugMsg(set, "linking solution to current solution\n");
991 
992  if( SCIPtreeHasCurrentNodeLP(tree) && SCIPlpIsSolved(lp) )
993  {
994  SCIP_CALL( SCIPsolLinkLPSol(sol, set, stat, prob, tree, lp) );
995  }
996  else
997  {
998  SCIP_CALL( SCIPsolLinkPseudoSol(sol, set, stat, prob, tree, lp) );
999  }
1000 
1001  return SCIP_OKAY;
1002 }
1003 
1004 /** clears primal CIP solution */
1006  SCIP_SOL* sol, /**< primal CIP solution */
1007  SCIP_STAT* stat, /**< problem statistics data */
1008  SCIP_TREE* tree /**< branch and bound tree */
1009  )
1010 {
1011  assert(sol != NULL);
1012 
1013  SCIP_CALL( solClearArrays(sol) );
1015  sol->obj = 0.0;
1016  solStamp(sol, stat, tree, TRUE);
1017 
1018  return SCIP_OKAY;
1019 }
1020 
1021 /** declares all entries in the primal CIP solution to be unknown */
1023  SCIP_SOL* sol, /**< primal CIP solution */
1024  SCIP_STAT* stat, /**< problem statistics data */
1025  SCIP_TREE* tree /**< branch and bound tree */
1026  )
1027 {
1028  assert(sol != NULL);
1029 
1030  SCIP_CALL( solClearArrays(sol) );
1032  sol->obj = 0.0;
1033  solStamp(sol, stat, tree, TRUE);
1034 
1035  return SCIP_OKAY;
1036 }
1037 
1038 /** stores solution values of variables in solution's own array */
1040  SCIP_SOL* sol, /**< primal CIP solution */
1041  SCIP_SET* set, /**< global SCIP settings */
1042  SCIP_PROB* prob /**< transformed problem data */
1043  )
1044 {
1045  int v;
1046 
1047  assert(sol != NULL);
1048  assert(prob != NULL);
1049  assert(prob->nvars == 0 || prob->vars != NULL);
1050 
1051  if( !SCIPsolIsOriginal(sol) && sol->solorigin != SCIP_SOLORIGIN_ZERO
1052  && sol->solorigin != SCIP_SOLORIGIN_UNKNOWN )
1053  {
1054  SCIPsetDebugMsg(set, "completing solution %p\n", (void*)sol);
1055 
1056  for( v = 0; v < prob->nvars; ++v )
1057  {
1058  SCIP_CALL( solUnlinkVar(sol, set, prob->vars[v]) );
1059  }
1060 
1061  sol->solorigin = SCIP_SOLORIGIN_ZERO;
1062  }
1063 
1064  return SCIP_OKAY;
1065 }
1066 
1067 /** sets value of variable in primal CIP solution */
1069  SCIP_SOL* sol, /**< primal CIP solution */
1070  SCIP_SET* set, /**< global SCIP settings */
1071  SCIP_STAT* stat, /**< problem statistics data */
1072  SCIP_TREE* tree, /**< branch and bound tree, or NULL */
1073  SCIP_VAR* var, /**< variable to add to solution */
1074  SCIP_Real val /**< solution value of variable */
1075  )
1076 {
1077  SCIP_Real oldval;
1078 
1079  assert(sol != NULL);
1080  assert(stat != NULL);
1081  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1082  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1085  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1086  assert(var != NULL);
1087  assert(SCIPisFinite(val));
1088 
1089  SCIPsetDebugMsg(set, "setting value of <%s> in solution %p to %g\n", SCIPvarGetName(var), (void*)sol, val);
1090 
1091  /* we want to store only values for non fixed variables (LOOSE or COLUMN); others have to be transformed */
1092  switch( SCIPvarGetStatus(var) )
1093  {
1095  if( SCIPsolIsOriginal(sol) )
1096  {
1097  oldval = solGetArrayVal(sol, var);
1098 
1099  if( !SCIPsetIsEQ(set, val, oldval) )
1100  {
1101  SCIP_Real obj;
1102  SCIP_Real objcont;
1103 
1104  SCIP_CALL( solSetArrayVal(sol, set, var, val) );
1105 
1106  /* update the objective value; we do not need to do this for partial solutions */
1107  if( !SCIPsolIsPartial(sol) )
1108  {
1109  /* an unknown solution value does not count towards the objective */
1110  obj = SCIPvarGetUnchangedObj(var);
1111  if( oldval != SCIP_UNKNOWN ) /*lint !e777*/
1112  {
1113  objcont = obj * oldval;
1114 
1115  /* we want to use a clean infinity */
1116  if( SCIPsetIsInfinity(set, -objcont) || SCIPsetIsInfinity(set, sol->obj-objcont) )
1117  sol->obj = SCIPsetInfinity(set);
1118  else if( SCIPsetIsInfinity(set, objcont) || SCIPsetIsInfinity(set, -(sol->obj-objcont)) )
1119  sol->obj = -SCIPsetInfinity(set);
1120  else
1121  sol->obj -= objcont;
1122  }
1123  if( val != SCIP_UNKNOWN ) /*lint !e777*/
1124  {
1125  objcont = obj * val;
1126 
1127  /* we want to use a clean infinity */
1128  if( SCIPsetIsInfinity(set, objcont) || SCIPsetIsInfinity(set, sol->obj+objcont) )
1129  sol->obj = SCIPsetInfinity(set);
1130  else if( SCIPsetIsInfinity(set, objcont) || SCIPsetIsInfinity(set, -(sol->obj+objcont)) )
1131  sol->obj = -SCIPsetInfinity(set);
1132  else
1133  sol->obj += objcont;
1134  }
1135  }
1136 
1137  solStamp(sol, stat, tree, FALSE);
1138  }
1139  return SCIP_OKAY;
1140  }
1141  else
1142  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetTransVar(var), val);
1143 
1144  case SCIP_VARSTATUS_LOOSE:
1145  case SCIP_VARSTATUS_COLUMN:
1146  assert(!SCIPsolIsOriginal(sol));
1147  assert(sol->solorigin != SCIP_SOLORIGIN_LPSOL || SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var))
1148  || sol->lpcount == stat->lpcount);
1149  oldval = solGetArrayVal(sol, var);
1150  if( !SCIPsetIsEQ(set, val, oldval) )
1151  {
1152  SCIP_Real obj;
1153  SCIP_Real objcont;
1154 
1155  SCIP_CALL( solSetArrayVal(sol, set, var, val) );
1156 
1157  /* update objective: an unknown solution value does not count towards the objective */
1158  obj = SCIPvarGetUnchangedObj(var);
1159 
1160  if( oldval != SCIP_UNKNOWN ) /*lint !e777*/
1161  {
1162  objcont = obj * oldval;
1163 
1164  /* we want to use a clean infinity */
1165  if( SCIPsetIsInfinity(set, -objcont) || SCIPsetIsInfinity(set, sol->obj-objcont) )
1166  sol->obj = SCIPsetInfinity(set);
1167  else if( SCIPsetIsInfinity(set, objcont) || SCIPsetIsInfinity(set, -(sol->obj-objcont)) )
1168  sol->obj = -SCIPsetInfinity(set);
1169  else
1170  sol->obj -= objcont;
1171  }
1172  if( val != SCIP_UNKNOWN ) /*lint !e777*/
1173  {
1174  objcont = obj * val;
1175 
1176  /* we want to use a clean infinity */
1177  if( SCIPsetIsInfinity(set, objcont) || SCIPsetIsInfinity(set, sol->obj+objcont) )
1178  sol->obj = SCIPsetInfinity(set);
1179  else if( SCIPsetIsInfinity(set, -objcont) || SCIPsetIsInfinity(set, -(sol->obj+objcont)) )
1180  sol->obj = -SCIPsetInfinity(set);
1181  else
1182  sol->obj += objcont;
1183  }
1184 
1185  solStamp(sol, stat, tree, FALSE);
1186  }
1187  return SCIP_OKAY;
1188 
1189  case SCIP_VARSTATUS_FIXED:
1190  assert(!SCIPsolIsOriginal(sol));
1191  oldval = SCIPvarGetLbGlobal(var);
1192  if( !SCIPsetIsEQ(set, val, oldval) )
1193  {
1194  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1195  SCIPvarGetName(var), oldval, val);
1196  return SCIP_INVALIDDATA;
1197  }
1198  return SCIP_OKAY;
1199 
1200  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1201  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1204 
1205  if( val == SCIP_UNKNOWN )/*lint !e777*/
1206  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), val);
1207  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1208  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), SCIPvarGetAggrScalar(var) > 0 ? val : -val);
1209  else
1210  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), (val - SCIPvarGetAggrConstant(var))/SCIPvarGetAggrScalar(var));
1211 
1213  if ( SCIPvarGetMultaggrNVars(var) == 1 )
1214  {
1215  SCIP_VAR** multaggrvars;
1216  SCIP_Real* multaggrscalars;
1217  SCIP_Real multaggrconstant;
1218 
1219  multaggrvars = SCIPvarGetMultaggrVars(var);
1220  multaggrscalars = SCIPvarGetMultaggrScalars(var);
1221  multaggrconstant = SCIPvarGetMultaggrConstant(var);
1222 
1223  if( SCIPsetIsInfinity(set, multaggrconstant) || SCIPsetIsInfinity(set, -multaggrconstant) )
1224  {
1225  if( (SCIPsetIsInfinity(set, multaggrconstant) && !SCIPsetIsInfinity(set, val))
1226  || (SCIPsetIsInfinity(set, -multaggrconstant) && !SCIPsetIsInfinity(set, -val)) )
1227  {
1228  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1229  SCIPvarGetName(var), multaggrconstant, val);
1230  return SCIP_INVALIDDATA;
1231  }
1232  return SCIP_OKAY;
1233  }
1234  else
1235  {
1236  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1237  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], multaggrscalars[0] > 0 ? val : -val);
1238  else
1239  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], (val - multaggrconstant)/multaggrscalars[0]);
1240  }
1241  }
1242  SCIPerrorMessage("cannot set solution value for multiple aggregated variable\n");
1243  return SCIP_INVALIDDATA;
1244 
1247 
1248  if( val == SCIP_UNKNOWN )/*lint !e777*/
1249  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), val);
1250  else if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1251  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -val);
1252  else
1253  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), SCIPvarGetNegationConstant(var) - val);
1254 
1255  default:
1256  SCIPerrorMessage("unknown variable status\n");
1257  return SCIP_INVALIDDATA;
1258  }
1259 }
1260 
1261 /** increases value of variable in primal CIP solution */
1263  SCIP_SOL* sol, /**< primal CIP solution */
1264  SCIP_SET* set, /**< global SCIP settings */
1265  SCIP_STAT* stat, /**< problem statistics data */
1266  SCIP_TREE* tree, /**< branch and bound tree */
1267  SCIP_VAR* var, /**< variable to increase solution value for */
1268  SCIP_Real incval /**< increment for solution value of variable */
1269  )
1270 {
1271  SCIP_Real oldval;
1272 
1273  assert(sol != NULL);
1274  assert(stat != NULL);
1275  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1276  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1277  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1278  assert(var != NULL);
1279  assert(!SCIPsetIsInfinity(set, incval) && !SCIPsetIsInfinity(set, -incval));
1280 
1281  SCIPsetDebugMsg(set, "increasing value of <%s> in solution %p by %g\n", SCIPvarGetName(var), (void*)sol, incval);
1282 
1283  if( SCIPsetIsZero(set, incval) )
1284  return SCIP_OKAY;
1285 
1286  assert(sol->solorigin != SCIP_SOLORIGIN_LPSOL || SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var))
1287  || sol->lpcount == stat->lpcount);
1288 
1289  oldval = solGetArrayVal(sol, var);
1290  if( SCIPsetIsInfinity(set, oldval) || SCIPsetIsInfinity(set, -oldval) )
1291  return SCIP_OKAY;
1292 
1293  /* we want to store only values for non fixed variables (LOOSE or COLUMN); others have to be transformed */
1294  /* @todo: handle strange cases, such as sums that yield infinite values */
1295  switch( SCIPvarGetStatus(var) )
1296  {
1298  if( SCIPsolIsOriginal(sol) )
1299  {
1300  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1301  sol->obj += SCIPvarGetUnchangedObj(var) * incval;
1302  solStamp(sol, stat, tree, FALSE);
1303  return SCIP_OKAY;
1304  }
1305  else
1306  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetTransVar(var), incval);
1307 
1308  case SCIP_VARSTATUS_LOOSE:
1309  case SCIP_VARSTATUS_COLUMN:
1310  assert(!SCIPsolIsOriginal(sol));
1311  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1312  sol->obj += SCIPvarGetUnchangedObj(var) * incval;
1313  solStamp(sol, stat, tree, FALSE);
1314  return SCIP_OKAY;
1315 
1316  case SCIP_VARSTATUS_FIXED:
1317  SCIPerrorMessage("cannot increase solution value for fixed variable\n");
1318  return SCIP_INVALIDDATA;
1319 
1320  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1321  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1322  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), incval/SCIPvarGetAggrScalar(var));
1323 
1325  SCIPerrorMessage("cannot increase solution value for multiple aggregated variable\n");
1326  return SCIP_INVALIDDATA;
1327 
1329  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -incval);
1330 
1331  default:
1332  SCIPerrorMessage("unknown variable status\n");
1333  return SCIP_INVALIDDATA;
1334  }
1335 }
1336 
1337 /** returns value of variable in primal CIP solution */
1339  SCIP_SOL* sol, /**< primal CIP solution */
1340  SCIP_SET* set, /**< global SCIP settings */
1341  SCIP_STAT* stat, /**< problem statistics data */
1342  SCIP_VAR* var /**< variable to get value for */
1343  )
1344 {
1345  SCIP_VAR** vars;
1346  SCIP_Real* scalars;
1347  SCIP_Real solval;
1348  SCIP_Real solvalsum;
1349  int nvars;
1350  int i;
1351 
1352  assert(sol != NULL);
1353  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1354  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1357  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1358  assert(var != NULL);
1359 
1360  /* if the value of a transformed variable in an original solution is requested, we need to project the variable back
1361  * to the original space, the opposite case is handled below
1362  */
1363  if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) )
1364  {
1365  SCIP_RETCODE retcode;
1366  SCIP_VAR* origvar;
1367  SCIP_Real scalar;
1368  SCIP_Real constant;
1369 
1370  /* we cannot get the value of a transformed variable for a solution that lives in the original problem space
1371  * -> get the corresponding original variable first
1372  */
1373  origvar = var;
1374  scalar = 1.0;
1375  constant = 0.0;
1376  retcode = SCIPvarGetOrigvarSum(&origvar, &scalar, &constant);
1377  if ( retcode != SCIP_OKAY )
1378  return SCIP_INVALID;
1379  if( origvar == NULL )
1380  {
1381  /* the variable has no original counterpart: in the original solution, it has a value of zero */
1382  return 0.0;
1383  }
1384  assert(!SCIPvarIsTransformed(origvar));
1385 
1386  solval = SCIPsolGetVal(sol, set, stat, origvar);
1387  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1388  return SCIP_UNKNOWN;
1389  else
1390  return scalar * solval + constant;
1391  }
1392 
1393  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1394  switch( SCIPvarGetStatus(var) )
1395  {
1397  if( SCIPsolIsOriginal(sol) )
1398  return solGetArrayVal(sol, var);
1399  else
1400  return SCIPsolGetVal(sol, set, stat, SCIPvarGetTransVar(var));
1401 
1402  case SCIP_VARSTATUS_LOOSE:
1403  case SCIP_VARSTATUS_COLUMN:
1404  assert(!SCIPsolIsOriginal(sol));
1406  || sol->lpcount == stat->lpcount);
1407  return solGetArrayVal(sol, var);
1408 
1409  case SCIP_VARSTATUS_FIXED:
1410  assert(!SCIPsolIsOriginal(sol));
1411  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1412  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1413  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1414  return SCIPvarGetLbGlobal(var);
1415 
1416  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1417  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetAggrVar(var));
1418  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1419  return SCIP_UNKNOWN;
1420  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1421  {
1422  if( SCIPvarGetAggrScalar(var) * solval > 0.0 )
1423  return SCIPsetInfinity(set);
1424  if( SCIPvarGetAggrScalar(var) * solval < 0.0 )
1425  return -SCIPsetInfinity(set);
1426  }
1427  return SCIPvarGetAggrScalar(var) * solval + SCIPvarGetAggrConstant(var);
1428 
1430  nvars = SCIPvarGetMultaggrNVars(var);
1431  vars = SCIPvarGetMultaggrVars(var);
1432  scalars = SCIPvarGetMultaggrScalars(var);
1433  solvalsum = SCIPvarGetMultaggrConstant(var);
1434  for( i = 0; i < nvars; ++i )
1435  {
1436  solval = SCIPsolGetVal(sol, set, stat, vars[i]);
1437  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1438  return SCIP_UNKNOWN;
1439  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1440  {
1441  if( scalars[i] * solval > 0.0 )
1442  return SCIPsetInfinity(set);
1443  if( scalars[i] * solval < 0.0 )
1444  return -SCIPsetInfinity(set);
1445  }
1446  solvalsum += scalars[i] * solval;
1447  }
1448  return solvalsum;
1449 
1451  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetNegationVar(var));
1452  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1453  return SCIP_UNKNOWN;
1454  if( SCIPsetIsInfinity(set, solval) )
1455  return -SCIPsetInfinity(set);
1456  if( SCIPsetIsInfinity(set, -solval) )
1457  return SCIPsetInfinity(set);
1458  return SCIPvarGetNegationConstant(var) - solval;
1459 
1460  default:
1461  SCIPerrorMessage("unknown variable status\n");
1462  SCIPABORT();
1463  return 0.0; /*lint !e527*/
1464  }
1465 }
1466 
1467 /** returns value of variable in primal ray represented by primal CIP solution */
1469  SCIP_SOL* sol, /**< primal CIP solution, representing a primal ray */
1470  SCIP_SET* set, /**< global SCIP settings */
1471  SCIP_STAT* stat, /**< problem statistics data */
1472  SCIP_VAR* var /**< variable to get value for */
1473  )
1474 {
1475  SCIP_VAR** vars;
1476  SCIP_Real* scalars;
1477  SCIP_Real solval;
1478  SCIP_Real solvalsum;
1479  int nvars;
1480  int i;
1481 
1482  assert(sol != NULL);
1483  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1484  assert(var != NULL);
1485 
1486  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1487  switch( SCIPvarGetStatus(var) )
1488  {
1490  return SCIPsolGetRayVal(sol, set, stat, SCIPvarGetTransVar(var));
1491 
1492  case SCIP_VARSTATUS_LOOSE:
1493  case SCIP_VARSTATUS_COLUMN:
1494  return solGetArrayVal(sol, var);
1495 
1496  case SCIP_VARSTATUS_FIXED:
1497  assert(!SCIPsolIsOriginal(sol));
1498  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1499  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1500  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1501  return 0.0; /* constants are ignored for computing the ray direction */
1502 
1503  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1504  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetAggrVar(var));
1505  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1506  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1507  return SCIPvarGetAggrScalar(var) * solval; /* constants are ignored for computing the ray direction */
1508 
1510  nvars = SCIPvarGetMultaggrNVars(var);
1511  vars = SCIPvarGetMultaggrVars(var);
1512  scalars = SCIPvarGetMultaggrScalars(var);
1513  solvalsum = 0.0; /* constants are ignored for computing the ray direction */
1514  for( i = 0; i < nvars; ++i )
1515  {
1516  solval = SCIPsolGetRayVal(sol, set, stat, vars[i]);
1517  assert(solval != SCIP_UNKNOWN ); /*lint !e777*/
1518  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1519  solvalsum += scalars[i] * solval;
1520  }
1521  return solvalsum;
1522 
1524  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetNegationVar(var));
1525  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1526  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1527  return -solval; /* constants are ignored for computing the ray direction */
1528 
1529  default:
1530  SCIPerrorMessage("unknown variable status\n");
1531  SCIPABORT();
1532  return 0.0; /*lint !e527*/
1533  }
1534 }
1535 
1536 /** gets objective value of primal CIP solution in transformed problem */
1538  SCIP_SOL* sol, /**< primal CIP solution */
1539  SCIP_SET* set, /**< global SCIP settings */
1540  SCIP_PROB* transprob, /**< tranformed problem data */
1541  SCIP_PROB* origprob /**< original problem data */
1542  )
1543 {
1544  assert(sol != NULL);
1545 
1546  /* for original solutions, sol->obj contains the external objective value */
1547  if( SCIPsolIsOriginal(sol) )
1548  return SCIPprobInternObjval(transprob, origprob, set, sol->obj);
1549  else
1550  return sol->obj;
1551 }
1552 
1553 /** updates primal solutions after a change in a variable's objective value */
1555  SCIP_SOL* sol, /**< primal CIP solution */
1556  SCIP_VAR* var, /**< problem variable */
1557  SCIP_Real oldobj, /**< old objective value */
1558  SCIP_Real newobj /**< new objective value */
1559  )
1560 {
1561  SCIP_Real solval;
1562 
1563  assert(sol != NULL);
1564  assert(!SCIPsolIsOriginal(sol));
1566 
1567  solval = solGetArrayVal(sol, var);
1568  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1569  sol->obj += (newobj - oldobj) * solval;
1570 }
1571 
1572 /* mark the given solution as partial solution */
1574  SCIP_SOL* sol, /**< primal CIP solution */
1575  SCIP_SET* set, /**< global SCIP settings */
1576  SCIP_STAT* stat, /**< problem statistics */
1577  SCIP_VAR** vars, /**< problem variables */
1578  int nvars /**< number of problem variables */
1579  )
1580 {
1581  SCIP_Real* vals;
1582  int v;
1583 
1584  assert(sol != NULL);
1585  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
1586  assert(nvars == 0 || vars != NULL);
1587 
1588  if( nvars == 0 )
1589  return SCIP_OKAY;;
1590 
1591  SCIP_CALL( SCIPsetAllocBufferArray(set, &vals, nvars) );
1592 
1593  /* get values */
1594  for( v = 0; v < nvars; v++ )
1595  {
1596  assert(!SCIPvarIsTransformed(vars[v]));
1597  vals[v] = SCIPsolGetVal(sol, set, stat, vars[v]);
1598  }
1599 
1600  /* change origin to partial */
1602 
1603  /* set values */
1604  for( v = 0; v < nvars; v++ )
1605  {
1606  int idx = SCIPvarGetIndex(vars[v]);
1607 
1608  if( vals[v] != SCIP_UNKNOWN ) /*lint !e777*/
1609  {
1610  /* from now on, variable must not be deleted */
1611  SCIPvarMarkNotDeletable(vars[v]);
1612 
1613  /* mark the variable valid */
1614  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, TRUE) );
1615 
1616  /* set the value in the solution array */
1617  SCIP_CALL( SCIPrealarraySetVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, vals[v]) );
1618  }
1619  else
1620  {
1621  /* mark the variable invalid */
1622  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, FALSE) );
1623  }
1624  }
1625 
1626  /* free buffer */
1627  SCIPsetFreeBufferArray(set, &vals);
1628 
1629  return SCIP_OKAY;
1630 }
1631 
1632 /** checks primal CIP solution for feasibility
1633  *
1634  * @note The difference between SCIPsolCheck() and SCIPcheckSolOrig() is that modifiable constraints are handled
1635  * differently. There might be some variables which do not have an original counter part (e.g. in
1636  * branch-and-price). Therefore, modifiable constraints can not be double-checked in the original space.
1637  */
1639  SCIP_SOL* sol, /**< primal CIP solution */
1640  SCIP_SET* set, /**< global SCIP settings */
1641  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1642  BMS_BLKMEM* blkmem, /**< block memory */
1643  SCIP_STAT* stat, /**< problem statistics */
1644  SCIP_PROB* prob, /**< transformed problem data */
1645  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1646  SCIP_Bool completely, /**< Should all violations be checked? */
1647  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1648  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1649  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1650  SCIP_Bool* feasible /**< stores whether solution is feasible */
1651  )
1652 {
1653  SCIP_RESULT result;
1654  int h;
1655 
1656  assert(sol != NULL);
1657  assert(!SCIPsolIsOriginal(sol));
1658  assert(set != NULL);
1659  assert(prob != NULL);
1660  assert(feasible != NULL);
1661 
1662  SCIPsetDebugMsg(set, "checking solution with objective value %g (nodenum=%" SCIP_LONGINT_FORMAT ", origin=%u)\n",
1663  sol->obj, sol->nodenum, sol->solorigin);
1664 
1665  *feasible = TRUE;
1666 
1668 
1669  if( !printreason )
1670  completely = FALSE;
1671 
1672  /* check whether the solution respects the global bounds of the variables */
1673  if( checkbounds || sol->hasinfval )
1674  {
1675  int v;
1676 
1677  for( v = 0; v < prob->nvars && (*feasible || completely); ++v )
1678  {
1679  SCIP_VAR* var;
1680  SCIP_Real solval;
1681 
1682  var = prob->vars[v];
1683  solval = SCIPsolGetVal(sol, set, stat, var);
1684 
1685  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1686  {
1687  SCIP_Real lb;
1688  SCIP_Real ub;
1689 
1690  lb = SCIPvarGetLbGlobal(var);
1691  ub = SCIPvarGetUbGlobal(var);
1692 
1693  /* if we have to check bound and one of the current bounds is violated */
1694  if( checkbounds && ((!SCIPsetIsInfinity(set, -lb) && SCIPsetIsFeasLT(set, solval, lb))
1695  || (!SCIPsetIsInfinity(set, ub) && SCIPsetIsFeasGT(set, solval, ub))) )
1696  {
1697  *feasible = FALSE;
1698 
1699  if( printreason )
1700  {
1701  SCIPmessagePrintInfo(messagehdlr, "solution value %g violates bounds of <%s>[%g,%g] by %g\n", solval, SCIPvarGetName(var),
1702  SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), MAX(lb - solval, 0.0) + MAX(solval - ub, 0.0));
1703  }
1704 #ifdef SCIP_DEBUG
1705  else
1706  {
1707  SCIPsetDebugMsgPrint(set, " -> solution value %g violates bounds of <%s>[%g,%g]\n", solval, SCIPvarGetName(var),
1709  }
1710 #endif
1711  }
1712 
1713  /* check whether there are infinite variable values that lead to an objective value of +infinity */
1714  if( *feasible && sol->hasinfval )
1715  {
1716  *feasible = *feasible && (!SCIPsetIsInfinity(set, solval) || SCIPsetIsLE(set, SCIPvarGetUnchangedObj(var), 0.0) );
1717  *feasible = *feasible && (!SCIPsetIsInfinity(set, -solval) || SCIPsetIsGE(set, SCIPvarGetUnchangedObj(var), 0.0) );
1718 
1719  if( ((SCIPsetIsInfinity(set, solval) && SCIPsetIsGT(set, SCIPvarGetUnchangedObj(var), 0.0)) || (SCIPsetIsInfinity(set, -solval) && SCIPsetIsLT(set, SCIPvarGetUnchangedObj(var), 0.0))) )
1720  {
1721  if( printreason )
1722  {
1723  SCIPmessagePrintInfo(messagehdlr, "infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1724  solval, SCIPvarGetName(var), SCIPvarGetUnchangedObj(var));
1725  }
1726 #ifdef SCIP_DEBUG
1727  else
1728  {
1729  SCIPsetDebugMsgPrint(set, "infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1730  solval, SCIPvarGetName(var), SCIPvarGetUnchangedObj(var));
1731  }
1732 #endif
1733  }
1734  }
1735  }
1736  }
1737  }
1738 
1739  /* check whether the solution fulfills all constraints */
1740  for( h = 0; h < set->nconshdlrs && (*feasible || completely); ++h )
1741  {
1742  SCIP_CALL( SCIPconshdlrCheck(set->conshdlrs[h], blkmem, set, stat, sol,
1743  checkintegrality, checklprows, printreason, completely, &result) );
1744  *feasible = *feasible && (result == SCIP_FEASIBLE);
1745 
1746 #ifdef SCIP_DEBUG
1747  if( !(*feasible) )
1748  {
1749  SCIPdebugPrintf(" -> infeasibility detected in constraint handler <%s>\n",
1750  SCIPconshdlrGetName(set->conshdlrs[h]));
1751  }
1752 #endif
1753  }
1754 
1755  return SCIP_OKAY;
1756 }
1757 
1758 /** try to round given solution */
1760  SCIP_SOL* sol, /**< primal solution */
1761  SCIP_SET* set, /**< global SCIP settings */
1762  SCIP_STAT* stat, /**< problem statistics data */
1763  SCIP_PROB* prob, /**< transformed problem data */
1764  SCIP_TREE* tree, /**< branch and bound tree */
1765  SCIP_Bool* success /**< pointer to store whether rounding was successful */
1766  )
1767 {
1768  int nvars;
1769  int v;
1770 
1771  assert(sol != NULL);
1772  assert(!SCIPsolIsOriginal(sol));
1773  assert(prob != NULL);
1774  assert(prob->transformed);
1775  assert(success != NULL);
1776 
1777  /* round all roundable fractional variables in the corresponding direction as long as no unroundable var was found */
1778  nvars = prob->nbinvars + prob->nintvars;
1779  for( v = 0; v < nvars; ++v )
1780  {
1781  SCIP_VAR* var;
1782  SCIP_Real solval;
1783  SCIP_Bool mayrounddown;
1784  SCIP_Bool mayroundup;
1785 
1786  var = prob->vars[v];
1789  || sol->lpcount == stat->lpcount);
1790  solval = solGetArrayVal(sol, var);
1791 
1792  /* solutions with unknown entries cannot be rounded */
1793  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1794  break;
1795 
1796  /* if solution value is already integral with feastol, continue */
1797  if( SCIPsetIsFeasIntegral(set, solval) )
1798  continue;
1799 
1800  /* get rounding possibilities */
1801  mayrounddown = SCIPvarMayRoundDown(var);
1802  mayroundup = SCIPvarMayRoundUp(var);
1803 
1804  /* choose rounding direction */
1805  if( mayrounddown && mayroundup )
1806  {
1807  /* we can round in both directions: round in objective function direction */
1808  if( SCIPvarGetUnchangedObj(var) >= 0.0 )
1809  solval = SCIPsetFeasFloor(set, solval);
1810  else
1811  solval = SCIPsetFeasCeil(set, solval);
1812  }
1813  else if( mayrounddown )
1814  solval = SCIPsetFeasFloor(set, solval);
1815  else if( mayroundup )
1816  solval = SCIPsetFeasCeil(set, solval);
1817  else
1818  break;
1819 
1820  /* store new solution value */
1821  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, solval) );
1822  }
1823 
1824  /* check, if rounding was successful */
1825  *success = (v == nvars);
1826 
1827  return SCIP_OKAY;
1828 }
1829 
1830 /** updates the solution value sums in variables by adding the value in the given solution */
1832  SCIP_SOL* sol, /**< primal CIP solution */
1833  SCIP_SET* set, /**< global SCIP settings */
1834  SCIP_STAT* stat, /**< problem statistics data */
1835  SCIP_PROB* prob, /**< transformed problem data */
1836  SCIP_Real weight /**< weight of solution in weighted average */
1837  )
1838 {
1839  SCIP_Real solval;
1840  int v;
1841 
1842  assert(sol != NULL);
1843  assert(!SCIPsolIsOriginal(sol));
1844  assert(0.0 <= weight && weight <= 1.0);
1845 
1846  for( v = 0; v < prob->nvars; ++v )
1847  {
1848  assert(prob->vars[v] != NULL);
1849  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
1850  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1851  {
1852  prob->vars[v]->primsolavg *= (1.0-weight);
1853  prob->vars[v]->primsolavg += weight*solval;
1854  }
1855  }
1856 }
1857 
1858 /** retransforms solution to original problem space */
1860  SCIP_SOL* sol, /**< primal CIP solution */
1861  SCIP_SET* set, /**< global SCIP settings */
1862  SCIP_STAT* stat, /**< problem statistics data */
1863  SCIP_PROB* origprob, /**< original problem */
1864  SCIP_PROB* transprob, /**< transformed problem */
1865  SCIP_Bool* hasinfval /**< pointer to store whether the solution has infinite values */
1866  )
1867 {
1868  SCIP_VAR** transvars;
1869  SCIP_VAR** vars;
1870  SCIP_VAR** activevars;
1871  SCIP_Real* solvals;
1872  SCIP_Real* activevals;
1873  SCIP_Real* transsolvals;
1874  SCIP_Real constant;
1875  int requiredsize;
1876  int ntransvars;
1877  int nactivevars;
1878  int nvars;
1879  int v;
1880  int i;
1881 
1882  assert(sol != NULL);
1883  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1884  assert(origprob != NULL);
1885  assert(transprob != NULL);
1886  assert(hasinfval != NULL);
1887  assert(!origprob->transformed);
1888  assert(transprob->transformed);
1889 
1890  *hasinfval = FALSE;
1891 
1892  /* This method was a performance bottleneck when retransforming a solution during presolving, before flattening the
1893  * aggregation graph. In that case, calling SCIPsolGetVal() on the original variable consumed too much
1894  * time. Therefore, we now first compute the active representation of each original variable using
1895  * SCIPvarGetActiveRepresentatives(), which is much faster, and sum up the solution values of the active variables by
1896  * hand for each original variable.
1897  */
1898  vars = origprob->vars;
1899  nvars = origprob->nvars;
1900  transvars = transprob->vars;
1901  ntransvars = transprob->nvars;
1902 
1903  /* allocate temporary memory for getting the active representation of the original variables, buffering the solution
1904  * values of all active variables and storing the original solution values
1905  */
1906  SCIP_CALL( SCIPsetAllocBufferArray(set, &transsolvals, ntransvars + 1) );
1907  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevars, ntransvars + 1) );
1908  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevals, ntransvars + 1) );
1909  SCIP_CALL( SCIPsetAllocBufferArray(set, &solvals, nvars) );
1910  assert(transsolvals != NULL); /* for flexelint */
1911  assert(solvals != NULL); /* for flexelint */
1912 
1913  /* get the solution values of all active variables */
1914  for( v = 0; v < ntransvars; ++v )
1915  {
1916  transsolvals[v] = SCIPsolGetVal(sol, set, stat, transvars[v]);
1917  }
1918 
1919  /* get the solution in original problem variables */
1920  for( v = 0; v < nvars; ++v )
1921  {
1922  activevars[0] = vars[v];
1923  activevals[0] = 1.0;
1924  nactivevars = 1;
1925  constant = 0.0;
1926 
1927  /* get active representation of the original variable */
1928  SCIP_CALL( SCIPvarGetActiveRepresentatives(set, activevars, activevals, &nactivevars, ntransvars + 1, &constant,
1929  &requiredsize, TRUE) );
1930  assert(requiredsize <= ntransvars);
1931 
1932  /* compute solution value of the original variable */
1933  solvals[v] = constant;
1934  for( i = 0; i < nactivevars; ++i )
1935  {
1936  assert(0 <= SCIPvarGetProbindex(activevars[i]) && SCIPvarGetProbindex(activevars[i]) < ntransvars);
1937  assert(!SCIPsetIsInfinity(set, -solvals[v]) || !SCIPsetIsInfinity(set, activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1938  assert(!SCIPsetIsInfinity(set, solvals[v]) || !SCIPsetIsInfinity(set, -activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1939  solvals[v] += activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])];
1940  }
1941 
1942  if( SCIPsetIsInfinity(set, solvals[v]) )
1943  {
1944  solvals[v] = SCIPsetInfinity(set);
1945  *hasinfval = TRUE;
1946  }
1947  else if( SCIPsetIsInfinity(set, -solvals[v]) )
1948  {
1949  solvals[v] = -SCIPsetInfinity(set);
1950  *hasinfval = TRUE;
1951  }
1952  }
1953 
1954  /* clear the solution and convert it into original space */
1955  SCIP_CALL( solClearArrays(sol) );
1957  sol->obj = origprob->objoffset;
1958 
1959  /* reinsert the values of the original variables */
1960  for( v = 0; v < nvars; ++v )
1961  {
1962  assert(SCIPvarGetUnchangedObj(vars[v]) == SCIPvarGetObj(vars[v])); /*lint !e777*/
1963 
1964  if( !SCIPsetIsZero(set, solvals[v]) )
1965  {
1966  SCIP_CALL( solSetArrayVal(sol, set, vars[v], solvals[v]) );
1967  if( solvals[v] != SCIP_UNKNOWN ) /*lint !e777*/
1968  sol->obj += SCIPvarGetUnchangedObj(vars[v]) * solvals[v];
1969  }
1970  }
1971 
1972  /**@todo remember the variables without original counterpart (priced variables) in the solution */
1973 
1974  /* free temporary memory */
1975  SCIPsetFreeBufferArray(set, &solvals);
1976  SCIPsetFreeBufferArray(set, &activevals);
1977  SCIPsetFreeBufferArray(set, &activevars);
1978  SCIPsetFreeBufferArray(set, &transsolvals);
1979 
1980  return SCIP_OKAY;
1981 }
1982 
1983 /** recomputes the objective value of an original solution, e.g., when transferring solutions
1984  * from the solution pool (objective coefficients might have changed in the meantime)
1985  */
1987  SCIP_SOL* sol, /**< primal CIP solution */
1988  SCIP_SET* set, /**< global SCIP settings */
1989  SCIP_STAT* stat, /**< problem statistics data */
1990  SCIP_PROB* origprob /**< original problem */
1991  )
1992 {
1993  SCIP_VAR** vars;
1994  SCIP_Real solval;
1995  int nvars;
1996  int v;
1997 
1998  assert(sol != NULL);
1999  assert(SCIPsolIsOriginal(sol));
2000  assert(origprob != NULL);
2001 
2002  vars = origprob->vars;
2003  nvars = origprob->nvars;
2004 
2005  /* recompute the objective value */
2006  sol->obj = SCIPprobGetObjoffset(origprob);
2007  for( v = 0; v < nvars; ++v )
2008  {
2009  solval = SCIPsolGetVal(sol, set, stat, vars[v]);
2010  if( !SCIPsetIsZero(set, solval) && solval != SCIP_UNKNOWN ) /*lint !e777*/
2011  {
2012  sol->obj += SCIPvarGetUnchangedObj(vars[v]) * solval;
2013  }
2014  }
2015 
2016  if( SCIPsetIsInfinity(set, -sol->obj) )
2017  sol->obj = -SCIPsetInfinity(set);
2018 }
2019 
2020 /** returns whether the given solutions are equal */
2022  SCIP_SOL* sol1, /**< first primal CIP solution */
2023  SCIP_SOL* sol2, /**< second primal CIP solution */
2024  SCIP_SET* set, /**< global SCIP settings */
2025  SCIP_STAT* stat, /**< problem statistics data */
2026  SCIP_PROB* origprob, /**< original problem */
2027  SCIP_PROB* transprob /**< transformed problem after presolve, or NULL if both solution are
2028  * defined in the original problem space */
2029  )
2030 {
2031  SCIP_PROB* prob;
2032  SCIP_Bool infobjs;
2033  SCIP_Real obj1;
2034  SCIP_Real obj2;
2035  int v;
2036 
2037  assert(sol1 != NULL);
2038  assert(sol2 != NULL);
2039  assert((SCIPsolIsOriginal(sol1) && SCIPsolIsOriginal(sol2)) || transprob != NULL);
2040 
2041  /* if both solutions are original or both are transformed, take the objective values stored in the solutions */
2042  if( SCIPsolIsOriginal(sol1) == SCIPsolIsOriginal(sol2) )
2043  {
2044  obj1 = sol1->obj;
2045  obj2 = sol2->obj;
2046  }
2047  /* one solution is original and the other not, so we have to get for both the objective in the transformed problem */
2048  else
2049  {
2050  obj1 = SCIPsolGetObj(sol1, set, transprob, origprob);
2051  obj2 = SCIPsolGetObj(sol2, set, transprob, origprob);
2052  }
2053 
2054  /* solutions with different objective values cannot be the same; we consider two infinite objective values with the
2055  * same sign always to be different
2056  */
2057  infobjs = (SCIPsetIsInfinity(set, obj1) && SCIPsetIsInfinity(set, obj2))
2058  || (SCIPsetIsInfinity(set, -obj1) && SCIPsetIsInfinity(set, -obj2));
2059  if( !infobjs && !SCIPsetIsEQ(set, obj1, obj2) )
2060  return FALSE;
2061 
2062  /* if one of the solutions is defined in the original space, the comparison has to be performed in the original
2063  * space
2064  */
2065  prob = transprob;
2066  if( SCIPsolIsOriginal(sol1) || SCIPsolIsOriginal(sol2) )
2067  prob = origprob;
2068  assert(prob != NULL);
2069 
2070  /* compare each variable value */
2071  for( v = 0; v < prob->nvars; ++v )
2072  {
2073  SCIP_Real val1;
2074  SCIP_Real val2;
2075 
2076  val1 = SCIPsolGetVal(sol1, set, stat, prob->vars[v]);
2077  val2 = SCIPsolGetVal(sol2, set, stat, prob->vars[v]);
2078  if( !SCIPsetIsEQ(set, val1, val2) )
2079  return FALSE;
2080  }
2081 
2082  return TRUE;
2083 }
2084 
2085 /** outputs non-zero elements of solution to file stream */
2087  SCIP_SOL* sol, /**< primal CIP solution */
2088  SCIP_SET* set, /**< global SCIP settings */
2089  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2090  SCIP_STAT* stat, /**< problem statistics data */
2091  SCIP_PROB* prob, /**< problem data (original or transformed) */
2092  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
2093  FILE* file, /**< output file (or NULL for standard output) */
2094  SCIP_Bool mipstart, /**< should only discrete variables be printed? */
2095  SCIP_Bool printzeros /**< should variables set to zero be printed? */
2096  )
2097 {
2098  SCIP_Real solval;
2099  int v;
2100 
2101  assert(sol != NULL);
2102  assert(prob != NULL);
2103  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
2104  assert(!mipstart || !SCIPsolIsPartial(sol));
2105 
2106  /* display variables of problem data */
2107  for( v = 0; v < prob->nfixedvars; ++v )
2108  {
2109  assert(prob->fixedvars[v] != NULL);
2110 
2111  /* skip non-discrete variables in a mip start */
2112  if( mipstart && !SCIPvarIsIntegral(prob->fixedvars[v]) )
2113  continue;
2114 
2115  solval = SCIPsolGetVal(sol, set, stat, prob->fixedvars[v]);
2116  if( printzeros || mipstart
2117  || (sol->solorigin != SCIP_SOLORIGIN_PARTIAL && !SCIPsetIsZero(set, solval))
2118  || (sol->solorigin == SCIP_SOLORIGIN_PARTIAL && solval != SCIP_UNKNOWN) ) /*lint !e777*/
2119  {
2120  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
2121  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2122  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2123  else if( SCIPsetIsInfinity(set, solval) )
2124  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2125  else if( SCIPsetIsInfinity(set, -solval) )
2126  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2127  else
2128  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2129  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->fixedvars[v]));
2130  }
2131  }
2132 
2133  for( v = 0; v < prob->nvars; ++v )
2134  {
2135  assert(prob->vars[v] != NULL);
2136 
2137  /* skip non-discrete variables in a mip start */
2138  if( mipstart && !SCIPvarIsIntegral(prob->vars[v]) )
2139  continue;
2140 
2141  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
2142  if( printzeros || mipstart
2143  || (sol->solorigin != SCIP_SOLORIGIN_PARTIAL && !SCIPsetIsZero(set, solval))
2144  || (sol->solorigin == SCIP_SOLORIGIN_PARTIAL && solval != SCIP_UNKNOWN) ) /*lint !e777*/
2145  {
2146  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
2147  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2148  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2149  else if( SCIPsetIsInfinity(set, solval) )
2150  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2151  else if( SCIPsetIsInfinity(set, -solval) )
2152  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2153  else
2154  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
2155  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->vars[v]));
2156  }
2157  }
2158 
2159  /* display additional priced variables (if given problem data is original problem); consider these variables only
2160  * if there is at least one active pricer, otherwise we might print variables that have been added by, e.g., the
2161  * dual sparsify presolver (see #2946)
2162  */
2163  if( !prob->transformed && !SCIPsolIsOriginal(sol) && set->nactivepricers > 0 )
2164  {
2165  assert(transprob != NULL);
2166  for( v = 0; v < transprob->nfixedvars; ++v )
2167  {
2168  assert(transprob->fixedvars[v] != NULL);
2169  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
2170  continue;
2171 
2172  /* skip non-discrete variables in a mip start */
2173  if( mipstart && !SCIPvarIsIntegral(transprob->fixedvars[v]) )
2174  continue;
2175 
2176  solval = SCIPsolGetVal(sol, set, stat, transprob->fixedvars[v]);
2177  if( printzeros || mipstart || !SCIPsetIsZero(set, solval) )
2178  {
2179  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[v]));
2180  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2181  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2182  else if( SCIPsetIsInfinity(set, solval) )
2183  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2184  else if( SCIPsetIsInfinity(set, -solval) )
2185  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2186  else
2187  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2188  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->fixedvars[v]));
2189  }
2190  }
2191  for( v = 0; v < transprob->nvars; ++v )
2192  {
2193  assert(transprob->vars[v] != NULL);
2194  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
2195  continue;
2196 
2197  /* skip non-discrete variables in a mip start */
2198  if( mipstart && !SCIPvarIsIntegral(transprob->vars[v]) )
2199  continue;
2200 
2201  solval = SCIPsolGetVal(sol, set, stat, transprob->vars[v]);
2202  if( printzeros || !SCIPsetIsZero(set, solval) )
2203  {
2204  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
2205  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2206  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2207  else if( SCIPsetIsInfinity(set, solval) )
2208  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2209  else if( SCIPsetIsInfinity(set, -solval) )
2210  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2211  else
2212  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2213  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->vars[v]));
2214  }
2215  }
2216  }
2217 
2218  return SCIP_OKAY;
2219 }
2220 
2221 /** outputs non-zero elements of solution representing a ray to file stream */
2223  SCIP_SOL* sol, /**< primal CIP solution */
2224  SCIP_SET* set, /**< global SCIP settings */
2225  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2226  SCIP_STAT* stat, /**< problem statistics data */
2227  SCIP_PROB* prob, /**< problem data (original or transformed) */
2228  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
2229  FILE* file, /**< output file (or NULL for standard output) */
2230  SCIP_Bool printzeros /**< should variables set to zero be printed? */
2231  )
2232 {
2233  SCIP_Real solval;
2234  int v;
2235 
2236  assert(sol != NULL);
2237  assert(prob != NULL);
2238  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
2239 
2240  /* display variables of problem data */
2241  for( v = 0; v < prob->nfixedvars; ++v )
2242  {
2243  assert(prob->fixedvars[v] != NULL);
2244  solval = SCIPsolGetRayVal(sol, set, stat, prob->fixedvars[v]);
2245  if( printzeros || !SCIPsetIsZero(set, solval) )
2246  {
2247  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
2248  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2249  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2250  else if( SCIPsetIsInfinity(set, solval) )
2251  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2252  else if( SCIPsetIsInfinity(set, -solval) )
2253  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2254  else
2255  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2256  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->fixedvars[v]));
2257  }
2258  }
2259  for( v = 0; v < prob->nvars; ++v )
2260  {
2261  assert(prob->vars[v] != NULL);
2262  solval = SCIPsolGetRayVal(sol, set, stat, prob->vars[v]);
2263  if( printzeros || !SCIPsetIsZero(set, solval) )
2264  {
2265  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
2266  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2267  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2268  else if( SCIPsetIsInfinity(set, solval) )
2269  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2270  else if( SCIPsetIsInfinity(set, -solval) )
2271  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2272  else
2273  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
2274  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->vars[v]));
2275  }
2276  }
2277 
2278  /* display additional priced variables (if given problem data is original problem) */
2279  if( !prob->transformed && !SCIPsolIsOriginal(sol) )
2280  {
2281  assert(transprob != NULL);
2282  for( v = 0; v < transprob->nfixedvars; ++v )
2283  {
2284  assert(transprob->fixedvars[v] != NULL);
2285  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
2286  continue;
2287 
2288  solval = SCIPsolGetRayVal(sol, set, stat, transprob->fixedvars[v]);
2289  if( printzeros || !SCIPsetIsZero(set, solval) )
2290  {
2291  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[v]));
2292  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2293  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2294  else if( SCIPsetIsInfinity(set, solval) )
2295  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2296  else if( SCIPsetIsInfinity(set, -solval) )
2297  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2298  else
2299  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2300  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->fixedvars[v]));
2301  }
2302  }
2303  for( v = 0; v < transprob->nvars; ++v )
2304  {
2305  assert(transprob->vars[v] != NULL);
2306  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
2307  continue;
2308 
2309  solval = SCIPsolGetRayVal(sol, set, stat, transprob->vars[v]);
2310  if( printzeros || !SCIPsetIsZero(set, solval) )
2311  {
2312  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
2313  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2314  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2315  else if( SCIPsetIsInfinity(set, solval) )
2316  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2317  else if( SCIPsetIsInfinity(set, -solval) )
2318  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2319  else
2320  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2321  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->vars[v]));
2322  }
2323  }
2324  }
2325 
2326  return SCIP_OKAY;
2327 }
2328 
2329 /*
2330  * methods for accumulated numerical violations of a solution
2331  */
2332 
2333 /** reset violations of a solution */
2335  SCIP_SOL* sol /**< primal CIP solution */
2336  )
2337 {
2338  assert(sol != NULL);
2339 
2340  sol->viol.absviolbounds = 0.0;
2341  sol->viol.relviolbounds = 0.0;
2342  sol->viol.absviolintegrality = 0.0;
2343  sol->viol.absviollprows = 0.0;
2344  sol->viol.relviollprows = 0.0;
2345  sol->viol.absviolcons = 0.0;
2346  sol->viol.relviolcons = 0.0;
2347 }
2348 
2349 /** update integrality violation of a solution */
2351  SCIP_SOL* sol, /**< primal CIP solution */
2352  SCIP_Real absviolintegrality /**< absolute violation of integrality */
2353  )
2354 {
2355  assert(sol != NULL);
2356 
2357  sol->viol.absviolintegrality = MAX(sol->viol.absviolintegrality, absviolintegrality);
2358 }
2359 
2360 /** update bound violation of a solution */
2362  SCIP_SOL* sol, /**< primal CIP solution */
2363  SCIP_Real absviolbounds, /**< absolute violation of bounds */
2364  SCIP_Real relviolbounds /**< relative violation of bounds */
2365  )
2366 {
2367  assert(sol != NULL);
2368 
2369  sol->viol.absviolbounds = MAX(sol->viol.absviolbounds, absviolbounds);
2370  sol->viol.relviolbounds = MAX(sol->viol.relviolbounds, relviolbounds);
2371 }
2372 
2373 /** update LP row violation of a solution */
2375  SCIP_SOL* sol, /**< primal CIP solution */
2376  SCIP_Real absviollprows, /**< absolute violation of LP rows */
2377  SCIP_Real relviollprows /**< relative violation of LP rows */
2378  )
2379 {
2380  assert(sol != NULL);
2381 
2382  sol->viol.absviollprows = MAX(sol->viol.absviollprows, absviollprows);
2383  sol->viol.relviollprows = MAX(sol->viol.relviollprows, relviollprows);
2384 }
2385 
2386 /** update constraint violation of a solution */
2388  SCIP_SOL* sol, /**< primal CIP solution */
2389  SCIP_Real absviolcons, /**< absolute violation of constraint */
2390  SCIP_Real relviolcons /**< relative violation of constraint */
2391  )
2392 {
2393  assert(sol != NULL);
2394 
2395  sol->viol.absviolcons = MAX(sol->viol.absviolcons, absviolcons);
2396  sol->viol.relviolcons = MAX(sol->viol.relviolcons, relviolcons);
2397 }
2398 
2399 /** update violation of a constraint that is represented in the LP */
2401  SCIP_SOL* sol, /**< primal CIP solution */
2402  SCIP_Real absviol, /**< absolute violation of constraint */
2403  SCIP_Real relviol /**< relative violation of constraint */
2404  )
2405 {
2406  assert(sol != NULL);
2407 
2408  SCIPsolUpdateConsViolation(sol, absviol, relviol);
2409  SCIPsolUpdateLPRowViolation(sol, absviol, relviol);
2410 }
2411 
2412 /** get maximum absolute bound violation of solution */
2414  SCIP_SOL* sol /**< primal CIP solution */
2415  )
2416 {
2417  assert(sol != NULL);
2418 
2419  return sol->viol.absviolbounds;
2420 }
2421 
2422 /** get maximum relative bound violation of solution */
2424  SCIP_SOL* sol /**< primal CIP solution */
2425  )
2426 {
2427  assert(sol != NULL);
2428 
2429  return sol->viol.relviolbounds;
2430 }
2431 
2432 /** get maximum absolute integrality violation of solution */
2434  SCIP_SOL* sol /**< primal CIP solution */
2435  )
2436 {
2437  assert(sol != NULL);
2438 
2439  return sol->viol.absviolintegrality;
2440 }
2441 
2442 /** get maximum absolute LP row violation of solution */
2444  SCIP_SOL* sol /**< primal CIP solution */
2445  )
2446 {
2447  assert(sol != NULL);
2448 
2449  return sol->viol.absviollprows;
2450 }
2451 
2452 /** get maximum relative LP row violation of solution */
2454  SCIP_SOL* sol /**< primal CIP solution */
2455  )
2456 {
2457  assert(sol != NULL);
2458 
2459  return sol->viol.relviollprows;
2460 }
2461 
2462 /** get maximum absolute constraint violation of solution */
2464  SCIP_SOL* sol /**< primal CIP solution */
2465  )
2466 {
2467  assert(sol != NULL);
2468 
2469  return sol->viol.absviolcons;
2470 }
2471 
2472 /** get maximum relative constraint violation of solution */
2474  SCIP_SOL* sol /**< primal CIP solution */
2475  )
2476 {
2477  assert(sol != NULL);
2478 
2479  return sol->viol.relviolcons;
2480 }
2481 
2482 /*
2483  * simple functions implemented as defines
2484  */
2485 
2486 /* In debug mode, the following methods are implemented as function calls to ensure
2487  * type validity.
2488  * In optimized mode, the methods are implemented as defines to improve performance.
2489  * However, we want to have them in the library anyways, so we have to undef the defines.
2490  */
2491 
2492 #undef SCIPsolGetOrigin
2493 #undef SCIPsolIsOriginal
2494 #undef SCIPsolGetOrigObj
2495 #undef SCIPsolGetTime
2496 #undef SCIPsolGetNodenum
2497 #undef SCIPsolGetRunnum
2498 #undef SCIPsolGetDepth
2499 #undef SCIPsolGetHeur
2500 #undef SCIPsolGetRelax
2501 #undef SCIPsolOrigAddObjval
2502 #undef SCIPsolGetPrimalIndex
2503 #undef SCIPsolSetPrimalIndex
2504 #undef SCIPsolGetIndex
2505 #undef SCIPsolGetType
2506 #undef SCIPsolSetLPRelaxation
2507 #undef SCIPsolSetStrongbranching
2508 #undef SCIPsolSetPseudo
2509 
2510 /** gets origin of solution */
2512  SCIP_SOL* sol /**< primal CIP solution */
2513  )
2514 {
2515  assert(sol != NULL);
2516 
2517  return sol->solorigin;
2518 }
2519 
2520 /** returns whether the given solution is defined on original variables */
2522  SCIP_SOL* sol /**< primal CIP solution */
2523  )
2524 {
2525  assert(sol != NULL);
2526 
2528 }
2529 
2530 /** returns whether the given solution is defined on original variables and containes unknown solution values */
2532  SCIP_SOL* sol /**< primal CIP solution */
2533  )
2534 {
2535  assert(sol != NULL);
2536 
2537  return (sol->solorigin == SCIP_SOLORIGIN_PARTIAL);
2538 }
2539 
2540 /** gets objective value of primal CIP solution which lives in the original problem space */
2542  SCIP_SOL* sol /**< primal CIP solution */
2543  )
2544 {
2545  assert(sol != NULL);
2546  assert(SCIPsolIsOriginal(sol));
2547 
2548  return sol->obj;
2549 }
2550 
2551 /** adds value to the objective value of a given original primal CIP solution */
2553  SCIP_SOL* sol, /**< primal CIP solution */
2554  SCIP_Real addval /**< offset value to add */
2555  )
2556 {
2557  assert(sol != NULL);
2558  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
2559 
2560  sol->obj += addval;
2561 }
2562 
2563 /** gets clock time, when this solution was found */
2565  SCIP_SOL* sol /**< primal CIP solution */
2566  )
2567 {
2568  assert(sol != NULL);
2569 
2570  return sol->time;
2571 }
2572 
2573 /** gets branch and bound run number, where this solution was found */
2575  SCIP_SOL* sol /**< primal CIP solution */
2576  )
2577 {
2578  assert(sol != NULL);
2579 
2580  return sol->runnum;
2581 }
2582 
2583 /** gets node number, where this solution was found */
2585  SCIP_SOL* sol /**< primal CIP solution */
2586  )
2587 {
2588  assert(sol != NULL);
2589 
2590  return sol->nodenum;
2591 }
2592 
2593 /** gets node's depth, where this solution was found */
2595  SCIP_SOL* sol /**< primal CIP solution */
2596  )
2597 {
2598  assert(sol != NULL);
2599 
2600  return sol->depth;
2601 }
2602 
2603 /** gets heuristic, that found this solution or NULL if solution has type different than SCIP_SOLTYPE_HEUR */
2605  SCIP_SOL* sol /**< primal CIP solution */
2606  )
2607 {
2608  assert(sol != NULL);
2609 
2610  return sol->type == SCIP_SOLTYPE_HEUR ? sol->creator.heur : NULL;
2611 }
2612 
2613 /** gets current position of solution in array of existing solutions of primal data */
2615  SCIP_SOL* sol /**< primal CIP solution */
2616  )
2617 {
2618  assert(sol != NULL);
2619 
2620  return sol->primalindex;
2621 }
2622 
2623 /** sets current position of solution in array of existing solutions of primal data */
2625  SCIP_SOL* sol, /**< primal CIP solution */
2626  int primalindex /**< new primal index of solution */
2627  )
2628 {
2629  assert(sol != NULL);
2630 
2631  sol->primalindex = primalindex;
2632 }
2633 
2634 /** returns unique index of given solution */
2636  SCIP_SOL* sol /**< primal CIP solution */
2637  )
2638 {
2639  assert(sol != NULL);
2640 
2641  return sol->index;
2642 }
2643 
2644 /** informs the solution that it now belongs to the given primal heuristic. For convenience and backwards compatibility,
2645  * the method accepts NULL as input for \p heur, in which case the solution type is set to SCIP_SOLTYPE_LPRELAX.
2646  *
2647  * @note Relaxation handlers should use SCIPsolSetRelax() instead.
2648  */
2650  SCIP_SOL* sol, /**< primal CIP solution */
2651  SCIP_HEUR* heur /**< primal heuristic that found the solution, or NULL for LP solutions */
2652  )
2653 {
2654  assert(sol != NULL);
2655 
2656  if( heur == NULL )
2658  else
2659  {
2660  sol->type = SCIP_SOLTYPE_HEUR;
2661  sol->creator.heur = heur;
2662  }
2663 }
2664 
2665 /** gets information if solution was found by the LP, a primal heuristic, or a custom relaxator */
2667  SCIP_SOL* sol /**< primal CIP solution */
2668  )
2669 {
2670  assert(sol != NULL);
2671 
2672  return sol->type;
2673 }
2674 
2675 /** gets relaxation handler that found this solution, or NULL if solution has different type than SCIP_SOLTYPE_RELAX */
2677  SCIP_SOL* sol /**< primal CIP solution */
2678  )
2679 {
2680  assert(sol != NULL);
2681 
2682  return sol->type == SCIP_SOLTYPE_RELAX ? sol->creator.relax : NULL;
2683 }
2684 
2685 /** informs the solution that it now belongs to the given relaxation handler */
2687  SCIP_SOL* sol, /**< primal CIP solution */
2688  SCIP_RELAX* relax /**< relaxator that found the solution */
2689  )
2690 {
2691  assert(sol != NULL);
2692  assert(relax != NULL);
2693 
2694  sol->type = SCIP_SOLTYPE_RELAX;
2695  sol->creator.relax = relax;
2696 }
2697 
2698 /** informs the solution that it is an LP relaxation solution */
2700  SCIP_SOL* sol /**< primal CIP solution */
2701  )
2702 {
2703  assert(sol != NULL);
2704 
2705  sol->type = SCIP_SOLTYPE_LPRELAX;
2706 }
2707 
2708 /** informs the solution that it is a solution found during strong branching */
2710  SCIP_SOL* sol /**< primal CIP solution */
2711  )
2712 {
2713  assert(sol != NULL);
2714 
2716 }
2717 
2718 /** informs the solution that it originates from a pseudo solution */
2720  SCIP_SOL* sol /**< primal CIP solution */
2721  )
2722 {
2723  assert(sol != NULL);
2724 
2725  sol->type = SCIP_SOLTYPE_PSEUDO;
2726 }
2727 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
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:643
SCIP_RETCODE SCIPsolUnlink(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *prob)
Definition: sol.c:1039
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17250
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5980
SCIP_RETCODE SCIPsolRound(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool *success)
Definition: sol.c:1759
SCIP_EXPORT SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17154
SCIP_RETCODE SCIPsolCreatePartial(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_HEUR *heur)
Definition: sol.c:721
void SCIPsolSetPseudo(SCIP_SOL *sol)
Definition: sol.c:2719
SCIP_RETCODE SCIPsolLinkPseudoSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:950
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6038
internal methods for storing primal CIP solutions
int solindex
Definition: struct_stat.h:258
int SCIPprobGetNBinVars(SCIP_PROB *prob)
Definition: prob.c:2327
SCIP_Real SCIPsolGetAbsLPRowViolation(SCIP_SOL *sol)
Definition: sol.c:2443
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17669
SCIP_EXPORT SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17408
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1661
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:824
internal methods for branch and bound tree
SCIP_Real absviolbounds
Definition: struct_sol.h:43
SCIP_EXPORT int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3250
#define SCIPstatDebugMsg
Definition: stat.h:313
SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6167
SCIP_EXPORT SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
Definition: var.c:17365
SCIP_EXPORT SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18049
int depth
Definition: struct_sol.h:84
SCIP_RETCODE SCIPsolLinkNLPSol(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_NLP *nlp)
Definition: sol.c:869
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2521
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17010
internal methods for clocks and timing issues
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6103
SCIP_Longint nodenum
Definition: struct_sol.h:68
SCIP_RETCODE SCIPrealarrayCreate(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem)
Definition: misc.c:3969
SCIP_Bool SCIPboolarrayGetVal(SCIP_BOOLARRAY *boolarray, int idx)
Definition: misc.c:4952
SCIP_EXPORT SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18036
int nintvars
Definition: struct_prob.h:63
SCIP_RETCODE SCIPsolLinkLPSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:811
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16975
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:757
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5845
SCIP_RETCODE SCIPsolLinkCurrentSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:979
SCIP_EXPORT SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18114
SCIP_HEUR * heur
Definition: struct_sol.h:79
SCIP_SOLTYPE type
Definition: struct_sol.h:92
SCIP_Real relviolcons
Definition: struct_sol.h:49
#define FALSE
Definition: def.h:73
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17000
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6521
SCIP_Real objoffset
Definition: struct_prob.h:41
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17510
SCIP_Bool solved
Definition: struct_lp.h:357
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2604
SCIP_RETCODE SCIPsolCopy(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_SOL *sourcesol)
Definition: sol.c:353
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6092
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17177
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Real SCIPsolGetRelBoundViolation(SCIP_SOL *sol)
Definition: sol.c:2423
void SCIPsolSetPrimalIndex(SCIP_SOL *sol, int primalindex)
Definition: sol.c:2624
SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2104
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1685
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8380
SCIP_Real SCIPsolGetRayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1468
SCIP_RETCODE SCIPsolSetUnknown(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: sol.c:1022
SCIP_EXPORT SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition: var.c:12627
SCIP_RETCODE SCIPboolarrayCopy(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem, SCIP_BOOLARRAY *sourceboolarray)
Definition: misc.c:4726
SCIP_Bool SCIPsolsAreEqual(SCIP_SOL *sol1, SCIP_SOL *sol2, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: sol.c:2021
SCIP_Real SCIPsolGetRelLPRowViolation(SCIP_SOL *sol)
Definition: sol.c:2453
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17335
public methods for problem variables
SCIP_VAR ** fixedvars
Definition: struct_prob.h:56
SCIP_RELAX * SCIPrelaxationGetSolRelax(SCIP_RELAXATION *relaxation)
Definition: relax.c:876
SCIP_Real SCIPsolGetAbsConsViolation(SCIP_SOL *sol)
Definition: sol.c:2463
SCIP_EXPORT void SCIPvarMarkNotDeletable(SCIP_VAR *var)
Definition: var.c:17256
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13246
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17131
void SCIPsolSetLPRelaxation(SCIP_SOL *sol)
Definition: sol.c:2699
SCIP_Real SCIPsolGetAbsIntegralityViolation(SCIP_SOL *sol)
Definition: sol.c:2433
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:793
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6114
SCIP_RETCODE SCIPsolClear(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: sol.c:1005
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1692
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2574
SCIP_EXPORT SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3336
SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6178
int runnum
Definition: struct_sol.h:83
SCIP_Real SCIPvarGetRelaxSolTransVar(SCIP_VAR *var)
Definition: var.c:13757
internal methods for LP management
Definition: heur_padm.c:125
union SCIP_Sol::@10 creator
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:1338
SCIP_EXPORT SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17454
SCIP_RETCODE SCIPboolarraySetVal(SCIP_BOOLARRAY *boolarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Bool val)
Definition: misc.c:4973
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17424
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6074
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17372
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4303
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6020
SCIP_Real SCIPclockGetLastTime(SCIP_CLOCK *clck)
Definition: clock.c:509
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8262
SCIP_Bool SCIPnlpIsDivingObjChanged(SCIP_NLP *nlp)
Definition: nlp.c:6379
static void solStamp(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_Bool checktime)
Definition: sol.c:251
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1537
int SCIPprobGetNImplVars(SCIP_PROB *prob)
Definition: prob.c:2345
void SCIPsolUpdateVarsum(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Real weight)
Definition: sol.c:1831
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17012
SCIP_RETCODE SCIPrealarrayCopy(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem, SCIP_REALARRAY *sourcerealarray)
Definition: misc.c:3989
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:2649
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17203
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:55
#define SCIPdebugPrintf
Definition: pub_message.h:90
SCIP_RELAX * SCIPsolGetRelax(SCIP_SOL *sol)
Definition: sol.c:2676
SCIP_Longint lpcount
Definition: struct_stat.h:178
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:694
SCIP_RETCODE SCIPboolarrayCreate(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem)
Definition: misc.c:4706
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17414
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2511
SCIP_Real SCIPrealarrayGetVal(SCIP_REALARRAY *realarray, int idx)
Definition: misc.c:4213
SCIP_Real primsolavg
Definition: struct_var.h:212
SCIP_Real SCIPnlpGetObjval(SCIP_NLP *nlp)
Definition: nlp.c:5614
SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:1068
int SCIPsolGetDepth(SCIP_SOL *sol)
Definition: sol.c:2594
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
internal methods for NLP management
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6556
static SCIP_RETCODE solIncArrayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var, SCIP_Real incval)
Definition: sol.c:97
internal miscellaneous methods
SCIP_RETCODE SCIPboolarrayClear(SCIP_BOOLARRAY *boolarray)
Definition: misc.c:4921
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_Real relviollprows
Definition: struct_sol.h:46
#define REALABS(x)
Definition: def.h:187
public methods for primal CIP solutions
static SCIP_RETCODE solUnlinkVar(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var)
Definition: sol.c:189
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:316
SCIP_SOLTYPE SCIPsolGetType(SCIP_SOL *sol)
Definition: sol.c:2666
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:364
SCIP_Real absviollprows
Definition: struct_sol.h:45
SCIP_Longint lpcount
Definition: struct_sol.h:70
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6466
SCIP_VAR * h
Definition: circlepacking.c:59
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:585
int primalindex
Definition: struct_sol.h:85
internal methods for relaxators
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6002
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13063
SCIP_EXPORT SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:17419
SCIP_EXPORT SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17499
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6422
datastructures for storing primal CIP solutions
int SCIPprobGetNIntVars(SCIP_PROB *prob)
Definition: prob.c:2336
SCIP_RETCODE SCIPsolTransform(SCIP_SOL *sol, SCIP_SOL **transsol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal)
Definition: sol.c:417
void SCIPsolRecomputeObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob)
Definition: sol.c:1986
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6454
SCIP_EXPORT SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3347
SCIP_EXPORT SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17376
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:456
internal methods for problem variables
#define SCIP_UNKNOWN
Definition: def.h:184
SCIP_EXPORT SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17488
SCIP_RETCODE SCIPprimalSolCreated(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_SOL *sol)
Definition: primal.c:1639
#define SCIP_Bool
Definition: def.h:70
SCIP_EXPORT SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:17466
SCIP_VIOL viol
Definition: struct_sol.h:82
int nbinvars
Definition: struct_prob.h:62
SCIP_Real SCIPprobGetObjoffset(SCIP_PROB *prob)
Definition: prob.c:2381
SCIP_NLPSOLSTAT SCIPnlpGetSolstat(SCIP_NLP *nlp)
Definition: nlp.c:6006
SCIP_RETCODE SCIPsolIncVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real incval)
Definition: sol.c:1262
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17672
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:279
SCIP_RETCODE SCIPrealarrayFree(SCIP_REALARRAY **realarray)
Definition: misc.c:4013
void SCIPsolResetViolations(SCIP_SOL *sol)
Definition: sol.c:2334
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17679
#define MAX(x, y)
Definition: tclique_def.h:83
SCIP_RETCODE SCIPsolRetransform(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_Bool *hasinfval)
Definition: sol.c:1859
SCIP_RETCODE SCIPsolMarkPartial(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **vars, int nvars)
Definition: sol.c:1573
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 mipstart, SCIP_Bool printzeros)
Definition: sol.c:2086
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17141
SCIP_EXPORT SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17520
void SCIPsolUpdateConsViolation(SCIP_SOL *sol, SCIP_Real absviolcons, SCIP_Real relviolcons)
Definition: sol.c:2387
public methods for LP management
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2709
#define SCIPsetDebugMsg
Definition: set.h:1721
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:2635
SCIP_Real SCIPsolGetAbsBoundViolation(SCIP_SOL *sol)
Definition: sol.c:2413
void SCIPsolOrigAddObjval(SCIP_SOL *sol, SCIP_Real addval)
Definition: sol.c:2552
SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
Definition: sol.c:2531
static SCIP_RETCODE solSetArrayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:66
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8397
int SCIPnlpGetNVars(SCIP_NLP *nlp)
Definition: nlp.c:5827
void SCIPsolUpdateBoundViolation(SCIP_SOL *sol, SCIP_Real absviolbounds, SCIP_Real relviolbounds)
Definition: sol.c:2361
datastructures for problem statistics
SCIP_Bool transformed
Definition: struct_prob.h:79
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6400
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17718
int nfixedvars
Definition: struct_prob.h:68
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:2222
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16901
void SCIPsolUpdateIntegralityViolation(SCIP_SOL *sol, SCIP_Real absviolintegrality)
Definition: sol.c:2350
SCIP_RETCODE SCIPsolAdjustImplicitSolVals(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_Bool uselprows)
Definition: sol.c:464
SCIP_EXPORT int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3193
SCIP_SOLORIGIN solorigin
Definition: struct_sol.h:87
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2541
static SCIP_RETCODE solClearArrays(SCIP_SOL *sol)
Definition: sol.c:52
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13102
datastructures for storing and manipulating the main problem
SCIP_Real * r
Definition: circlepacking.c:50
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17728
SCIP_RETCODE SCIPsolLinkRelaxSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_RELAXATION *relaxation)
Definition: sol.c:920
SCIP_Real SCIPsetFeasFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6545
SCIP_Real SCIPsolGetTime(SCIP_SOL *sol)
Definition: sol.c:2564
static const SCIP_Real scalars[]
Definition: lp.c:5731
void SCIPsolUpdateLPRowViolation(SCIP_SOL *sol, SCIP_Real absviollprows, SCIP_Real relviollprows)
Definition: sol.c:2374
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:599
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17662
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:3814
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:148
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2584
SCIP_EXPORT int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17430
SCIP_RETCODE SCIPboolarrayFree(SCIP_BOOLARRAY **boolarray)
Definition: misc.c:4750
public methods for message output
data structures for LP management
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6056
datastructures for problem variables
static SCIP_Real solGetArrayVal(SCIP_SOL *sol, SCIP_VAR *var)
Definition: sol.c:138
int SCIPsolGetPrimalIndex(SCIP_SOL *sol)
Definition: sol.c:2614
void SCIPsolUpdateVarObj(SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: sol.c:1554
SCIP_Real time
Definition: struct_sol.h:67
#define SCIP_Real
Definition: def.h:163
internal methods for problem statistics
SCIP_VAR ** vars
Definition: struct_prob.h:55
void SCIPsolSetRelax(SCIP_SOL *sol, SCIP_RELAX *relax)
Definition: sol.c:2686
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17629
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6499
enum SCIP_SolType SCIP_SOLTYPE
Definition: type_sol.h:62
#define SCIPsetDebugMsgPrint
Definition: set.h:1722
SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
Definition: prob.c:2363
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12540
#define SCIP_INVALID
Definition: def.h:183
enum SCIP_SolOrigin SCIP_SOLORIGIN
Definition: type_sol.h:46
internal methods for constraints and constraint handlers
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_REALARRAY * vals
Definition: struct_sol.h:74
#define SCIP_Longint
Definition: def.h:148
SCIP_Real relviolbounds
Definition: struct_sol.h:44
SCIP_VAR ** SCIPnlpGetVars(SCIP_NLP *nlp)
Definition: nlp.c:5817
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4179
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:622
#define SCIPisFinite(x)
Definition: pub_misc.h:1861
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6444
SCIP_RETCODE SCIPrealarraySetVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real val)
Definition: misc.c:4234
SCIP_BOOLARRAY * valid
Definition: struct_sol.h:75
void SCIPsolUpdateLPConsViolation(SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: sol.c:2400
SCIP_EXPORT int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17355
SCIP_RELAX * relax
Definition: struct_sol.h:80
SCIP_Real SCIPsolGetRelConsViolation(SCIP_SOL *sol)
Definition: sol.c:2473
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:443
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17151
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:669
SCIP_Real absviolintegrality
Definition: struct_sol.h:47
SCIP_EXPORT SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:17397
SCIP_Longint nnodes
Definition: struct_stat.h:73
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
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_Bool completely, SCIP_RESULT *result)
Definition: cons.c:3742
SCIP_Real absviolcons
Definition: struct_sol.h:48
#define SCIP_ALLOC(x)
Definition: def.h:375
#define SCIPABORT()
Definition: def.h:336
SCIP_Bool hasinfval
Definition: struct_sol.h:88
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 completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
Definition: sol.c:1638
datastructures for global SCIP settings
SCIP_Real obj
Definition: struct_sol.h:66
int index
Definition: struct_sol.h:86
SCIP_EXPORT SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17442
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6510
SCIP_EXPORT int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17345
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:792