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