Scippy

SCIP

Solving Constraint Integer Programs

sol.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */
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_CALL( solSetArrayVal(sol, set, var, val) );
1111 
1112  /* update the objective value; we do not need to do this for invalid objectives or partial solutions */
1113  if( sol->obj != SCIP_INVALID && !SCIPsolIsPartial(sol) ) /*lint !e777*/
1114  {
1115  SCIP_Real obj;
1116  SCIP_Real oldobjcont;
1117  SCIP_Real newobjcont;
1118 
1119  /* an unknown solution value does not count towards the objective */
1120  obj = SCIPvarGetUnchangedObj(var);
1121  oldobjcont = (oldval == SCIP_UNKNOWN ? 0.0 : obj * oldval); /*lint !e777*/
1122  newobjcont = (val == SCIP_UNKNOWN ? 0.0 : obj * val); /*lint !e777*/
1123 
1124  /* we want to use a safe invalid if the contribution exchange contradicts the infinity status of the objective value */
1125  if( SCIPsetIsInfinity(set, sol->obj) )
1126  {
1127  if( ( SCIPsetIsInfinity(set, oldobjcont) && !SCIPsetIsInfinity(set, newobjcont) )
1128  || ( !SCIPsetIsInfinity(set, -oldobjcont) && SCIPsetIsInfinity(set, -newobjcont) ) )
1129  sol->obj = SCIP_INVALID;
1130  }
1131  else if( SCIPsetIsInfinity(set, -sol->obj) )
1132  {
1133  if( ( SCIPsetIsInfinity(set, -oldobjcont) && !SCIPsetIsInfinity(set, -newobjcont) )
1134  || ( !SCIPsetIsInfinity(set, oldobjcont) && SCIPsetIsInfinity(set, newobjcont) ) )
1135  sol->obj = SCIP_INVALID;
1136  }
1137  /* we want to use a clean infinity if the contribution exchange or the resulting objective hits the infinity bound */
1138  else
1139  {
1140  if( !SCIPsetIsInfinity(set, MAX(ABS(oldobjcont), ABS(newobjcont))) )
1141  {
1142  sol->obj -= oldobjcont;
1143  sol->obj += newobjcont;
1144 
1145  if( SCIPsetIsInfinity(set, sol->obj) )
1146  sol->obj = SCIPsetInfinity(set);
1147  else if( SCIPsetIsInfinity(set, -sol->obj) )
1148  sol->obj = -SCIPsetInfinity(set);
1149  }
1150  else if( !SCIPsetIsInfinity(set, MAX(oldobjcont, -newobjcont)) )
1151  sol->obj = SCIPsetInfinity(set);
1152  else if( !SCIPsetIsInfinity(set, MAX(-oldobjcont, newobjcont)) )
1153  sol->obj = -SCIPsetInfinity(set);
1154  }
1155  }
1156 
1157  solStamp(sol, stat, tree, FALSE);
1158  }
1159  return SCIP_OKAY;
1160  }
1161  else
1162  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetTransVar(var), val);
1163 
1164  case SCIP_VARSTATUS_LOOSE:
1165  case SCIP_VARSTATUS_COLUMN:
1166  assert(!SCIPsolIsOriginal(sol));
1167  assert(sol->solorigin != SCIP_SOLORIGIN_LPSOL || SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var))
1168  || sol->lpcount == stat->lpcount);
1169  oldval = solGetArrayVal(sol, var);
1170  if( val != oldval ) /*lint !e777*/
1171  {
1172  SCIP_CALL( solSetArrayVal(sol, set, var, val) );
1173 
1174  /* update the objective value; we do not need to do this for invalid objectives */
1175  if( sol->obj != SCIP_INVALID ) /*lint !e777*/
1176  {
1177  SCIP_Real obj;
1178  SCIP_Real oldobjcont;
1179  SCIP_Real newobjcont;
1180 
1181  /* an unknown solution value does not count towards the objective */
1182  obj = SCIPvarGetUnchangedObj(var);
1183  oldobjcont = (oldval == SCIP_UNKNOWN ? 0.0 : obj * oldval); /*lint !e777*/
1184  newobjcont = (val == SCIP_UNKNOWN ? 0.0 : obj * val); /*lint !e777*/
1185 
1186  /* we want to use a safe invalid if the contribution exchange contradicts the infinity status of the objective value */
1187  if( SCIPsetIsInfinity(set, sol->obj) )
1188  {
1189  if( ( SCIPsetIsInfinity(set, oldobjcont) && !SCIPsetIsInfinity(set, newobjcont) )
1190  || ( !SCIPsetIsInfinity(set, -oldobjcont) && SCIPsetIsInfinity(set, -newobjcont) ) )
1191  sol->obj = SCIP_INVALID;
1192  }
1193  else if( SCIPsetIsInfinity(set, -sol->obj) )
1194  {
1195  if( ( SCIPsetIsInfinity(set, -oldobjcont) && !SCIPsetIsInfinity(set, -newobjcont) )
1196  || ( !SCIPsetIsInfinity(set, oldobjcont) && SCIPsetIsInfinity(set, newobjcont) ) )
1197  sol->obj = SCIP_INVALID;
1198  }
1199  /* we want to use a clean infinity if the contribution exchange or the resulting objective hits the infinity bound */
1200  else
1201  {
1202  if( !SCIPsetIsInfinity(set, MAX(ABS(oldobjcont), ABS(newobjcont))) )
1203  {
1204  sol->obj -= oldobjcont;
1205  sol->obj += newobjcont;
1206 
1207  if( SCIPsetIsInfinity(set, sol->obj) )
1208  sol->obj = SCIPsetInfinity(set);
1209  else if( SCIPsetIsInfinity(set, -sol->obj) )
1210  sol->obj = -SCIPsetInfinity(set);
1211  }
1212  else if( !SCIPsetIsInfinity(set, MAX(oldobjcont, -newobjcont)) )
1213  sol->obj = SCIPsetInfinity(set);
1214  else if( !SCIPsetIsInfinity(set, MAX(-oldobjcont, newobjcont)) )
1215  sol->obj = -SCIPsetInfinity(set);
1216  }
1217  }
1218 
1219  solStamp(sol, stat, tree, FALSE);
1220  }
1221  return SCIP_OKAY;
1222 
1223  case SCIP_VARSTATUS_FIXED:
1224  assert(!SCIPsolIsOriginal(sol));
1225  oldval = SCIPvarGetLbGlobal(var);
1226  if( val != oldval ) /*lint !e777*/
1227  {
1228  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1229  SCIPvarGetName(var), oldval, val);
1230  return SCIP_INVALIDDATA;
1231  }
1232  return SCIP_OKAY;
1233 
1234  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1235  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1238 
1239  if( val == SCIP_UNKNOWN )/*lint !e777*/
1240  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), val);
1241  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1242  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), SCIPvarGetAggrScalar(var) > 0 ? val : -val);
1243  else
1244  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), (val - SCIPvarGetAggrConstant(var))/SCIPvarGetAggrScalar(var));
1245 
1247  if ( SCIPvarGetMultaggrNVars(var) == 1 )
1248  {
1249  SCIP_VAR** multaggrvars;
1250  SCIP_Real* multaggrscalars;
1251  SCIP_Real multaggrconstant;
1252 
1253  multaggrvars = SCIPvarGetMultaggrVars(var);
1254  multaggrscalars = SCIPvarGetMultaggrScalars(var);
1255  multaggrconstant = SCIPvarGetMultaggrConstant(var);
1256 
1257  if( SCIPsetIsInfinity(set, multaggrconstant) || SCIPsetIsInfinity(set, -multaggrconstant) )
1258  {
1259  if( (SCIPsetIsInfinity(set, multaggrconstant) && !SCIPsetIsInfinity(set, val))
1260  || (SCIPsetIsInfinity(set, -multaggrconstant) && !SCIPsetIsInfinity(set, -val)) )
1261  {
1262  SCIPerrorMessage("cannot set solution value for variable <%s> fixed to %.15g to different value %.15g\n",
1263  SCIPvarGetName(var), multaggrconstant, val);
1264  return SCIP_INVALIDDATA;
1265  }
1266  return SCIP_OKAY;
1267  }
1268  else
1269  {
1270  if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1271  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], multaggrscalars[0] > 0 ? val : -val);
1272  else
1273  return SCIPsolSetVal(sol, set, stat, tree, multaggrvars[0], (val - multaggrconstant)/multaggrscalars[0]);
1274  }
1275  }
1276  SCIPerrorMessage("cannot set solution value for multiple aggregated variable\n");
1277  return SCIP_INVALIDDATA;
1278 
1281 
1282  if( val == SCIP_UNKNOWN )/*lint !e777*/
1283  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), val);
1284  else if( SCIPsetIsInfinity(set, val) || SCIPsetIsInfinity(set, -val) )
1285  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -val);
1286  else
1287  return SCIPsolSetVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), SCIPvarGetNegationConstant(var) - val);
1288 
1289  default:
1290  SCIPerrorMessage("unknown variable status\n");
1291  return SCIP_INVALIDDATA;
1292  }
1293 }
1294 
1295 /** increases value of variable in primal CIP solution */
1297  SCIP_SOL* sol, /**< primal CIP solution */
1298  SCIP_SET* set, /**< global SCIP settings */
1299  SCIP_STAT* stat, /**< problem statistics data */
1300  SCIP_TREE* tree, /**< branch and bound tree */
1301  SCIP_VAR* var, /**< variable to increase solution value for */
1302  SCIP_Real incval /**< increment for solution value of variable */
1303  )
1304 {
1305  SCIP_Real oldval;
1306 
1307  assert(sol != NULL);
1308  assert(stat != NULL);
1309  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1310  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1311  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1312  assert(var != NULL);
1313  assert(!SCIPsetIsInfinity(set, incval) && !SCIPsetIsInfinity(set, -incval));
1314 
1315  SCIPsetDebugMsg(set, "increasing value of <%s> in solution %p by %g\n", SCIPvarGetName(var), (void*)sol, incval);
1316 
1317  if( incval == 0.0 )
1318  return SCIP_OKAY;
1319 
1320  assert(sol->solorigin != SCIP_SOLORIGIN_LPSOL || SCIPboolarrayGetVal(sol->valid, SCIPvarGetIndex(var))
1321  || sol->lpcount == stat->lpcount);
1322 
1323  oldval = solGetArrayVal(sol, var);
1324  if( SCIPsetIsInfinity(set, oldval) || SCIPsetIsInfinity(set, -oldval) )
1325  return SCIP_OKAY;
1326 
1327  /* we want to store only values for non fixed variables (LOOSE or COLUMN); others have to be transformed */
1328  /* @todo: handle strange cases, such as sums that yield infinite values */
1329  switch( SCIPvarGetStatus(var) )
1330  {
1332  if( SCIPsolIsOriginal(sol) )
1333  {
1334  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1335  sol->obj += SCIPvarGetUnchangedObj(var) * incval;
1336  solStamp(sol, stat, tree, FALSE);
1337  return SCIP_OKAY;
1338  }
1339  else
1340  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetTransVar(var), incval);
1341 
1342  case SCIP_VARSTATUS_LOOSE:
1343  case SCIP_VARSTATUS_COLUMN:
1344  assert(!SCIPsolIsOriginal(sol));
1345  SCIP_CALL( solIncArrayVal(sol, set, var, incval) );
1346  sol->obj += SCIPvarGetUnchangedObj(var) * incval;
1347  solStamp(sol, stat, tree, FALSE);
1348  return SCIP_OKAY;
1349 
1350  case SCIP_VARSTATUS_FIXED:
1351  SCIPerrorMessage("cannot increase solution value for fixed variable\n");
1352  return SCIP_INVALIDDATA;
1353 
1354  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1355  assert(!SCIPsetIsZero(set, SCIPvarGetAggrScalar(var)));
1356  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetAggrVar(var), incval/SCIPvarGetAggrScalar(var));
1357 
1359  SCIPerrorMessage("cannot increase solution value for multiple aggregated variable\n");
1360  return SCIP_INVALIDDATA;
1361 
1363  return SCIPsolIncVal(sol, set, stat, tree, SCIPvarGetNegationVar(var), -incval);
1364 
1365  default:
1366  SCIPerrorMessage("unknown variable status\n");
1367  return SCIP_INVALIDDATA;
1368  }
1369 }
1370 
1371 /** returns value of variable in primal CIP solution */
1373  SCIP_SOL* sol, /**< primal CIP solution */
1374  SCIP_SET* set, /**< global SCIP settings */
1375  SCIP_STAT* stat, /**< problem statistics data */
1376  SCIP_VAR* var /**< variable to get value for */
1377  )
1378 {
1379  SCIP_VAR** vars;
1380  SCIP_Real* scalars;
1381  SCIP_Real solval;
1382  SCIP_Real solvalsum;
1383  int nvars;
1384  int i;
1385 
1386  assert(sol != NULL);
1387  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL
1388  || sol->solorigin == SCIP_SOLORIGIN_ZERO
1391  || (sol->nodenum == stat->nnodes && sol->runnum == stat->nruns));
1392  assert(var != NULL);
1393 
1394  /* if the value of a transformed variable in an original solution is requested, we need to project the variable back
1395  * to the original space, the opposite case is handled below
1396  */
1397  if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) )
1398  {
1399  SCIP_RETCODE retcode;
1400  SCIP_VAR* origvar;
1401  SCIP_Real scalar;
1402  SCIP_Real constant;
1403 
1404  /* we cannot get the value of a transformed variable for a solution that lives in the original problem space
1405  * -> get the corresponding original variable first
1406  */
1407  origvar = var;
1408  scalar = 1.0;
1409  constant = 0.0;
1410  retcode = SCIPvarGetOrigvarSum(&origvar, &scalar, &constant);
1411  if ( retcode != SCIP_OKAY )
1412  return SCIP_INVALID;
1413  if( origvar == NULL )
1414  {
1415  /* the variable has no original counterpart: in the original solution, it has a value of zero */
1416  return 0.0;
1417  }
1418  assert(!SCIPvarIsTransformed(origvar));
1419 
1420  solval = SCIPsolGetVal(sol, set, stat, origvar);
1421  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1422  return SCIP_UNKNOWN;
1423  else
1424  return scalar * solval + constant;
1425  }
1426 
1427  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1428  switch( SCIPvarGetStatus(var) )
1429  {
1431  if( SCIPsolIsOriginal(sol) )
1432  return solGetArrayVal(sol, var);
1433  else
1434  return SCIPsolGetVal(sol, set, stat, SCIPvarGetTransVar(var));
1435 
1436  case SCIP_VARSTATUS_LOOSE:
1437  case SCIP_VARSTATUS_COLUMN:
1438  assert(!SCIPsolIsOriginal(sol));
1440  || sol->lpcount == stat->lpcount);
1441  return solGetArrayVal(sol, var);
1442 
1443  case SCIP_VARSTATUS_FIXED:
1444  assert(!SCIPsolIsOriginal(sol));
1445  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1446  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1447  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1448  return SCIPvarGetLbGlobal(var);
1449 
1450  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1451  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetAggrVar(var));
1452  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1453  return SCIP_UNKNOWN;
1454  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1455  {
1456  if( SCIPvarGetAggrScalar(var) * solval > 0.0 )
1457  return SCIPsetInfinity(set);
1458  if( SCIPvarGetAggrScalar(var) * solval < 0.0 )
1459  return -SCIPsetInfinity(set);
1460  }
1461  return SCIPvarGetAggrScalar(var) * solval + SCIPvarGetAggrConstant(var);
1462 
1464  nvars = SCIPvarGetMultaggrNVars(var);
1465  vars = SCIPvarGetMultaggrVars(var);
1466  scalars = SCIPvarGetMultaggrScalars(var);
1467  solvalsum = SCIPvarGetMultaggrConstant(var);
1468  for( i = 0; i < nvars; ++i )
1469  {
1470  solval = SCIPsolGetVal(sol, set, stat, vars[i]);
1471  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1472  return SCIP_UNKNOWN;
1473  if( SCIPsetIsInfinity(set, solval) || SCIPsetIsInfinity(set, -solval) )
1474  {
1475  if( scalars[i] * solval > 0.0 )
1476  return SCIPsetInfinity(set);
1477  if( scalars[i] * solval < 0.0 )
1478  return -SCIPsetInfinity(set);
1479  }
1480  solvalsum += scalars[i] * solval;
1481  }
1482  return solvalsum;
1483 
1485  solval = SCIPsolGetVal(sol, set, stat, SCIPvarGetNegationVar(var));
1486  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1487  return SCIP_UNKNOWN;
1488  if( SCIPsetIsInfinity(set, solval) )
1489  return -SCIPsetInfinity(set);
1490  if( SCIPsetIsInfinity(set, -solval) )
1491  return SCIPsetInfinity(set);
1492  return SCIPvarGetNegationConstant(var) - solval;
1493 
1494  default:
1495  SCIPerrorMessage("unknown variable status\n");
1496  SCIPABORT();
1497  return 0.0; /*lint !e527*/
1498  }
1499 }
1500 
1501 /** returns value of variable in primal ray represented by primal CIP solution */
1503  SCIP_SOL* sol, /**< primal CIP solution, representing a primal ray */
1504  SCIP_SET* set, /**< global SCIP settings */
1505  SCIP_STAT* stat, /**< problem statistics data */
1506  SCIP_VAR* var /**< variable to get value for */
1507  )
1508 {
1509  SCIP_VAR** vars;
1510  SCIP_Real* scalars;
1511  SCIP_Real solval;
1512  SCIP_Real solvalsum;
1513  int nvars;
1514  int i;
1515 
1516  assert(sol != NULL);
1517  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1518  assert(var != NULL);
1519 
1520  /* only values for non fixed variables (LOOSE or COLUMN) are stored; others have to be transformed */
1521  switch( SCIPvarGetStatus(var) )
1522  {
1524  return SCIPsolGetRayVal(sol, set, stat, SCIPvarGetTransVar(var));
1525 
1526  case SCIP_VARSTATUS_LOOSE:
1527  case SCIP_VARSTATUS_COLUMN:
1528  return solGetArrayVal(sol, var);
1529 
1530  case SCIP_VARSTATUS_FIXED:
1531  assert(!SCIPsolIsOriginal(sol));
1532  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetUbGlobal(var)); /*lint !e777*/
1533  assert(SCIPvarGetLbLocal(var) == SCIPvarGetUbLocal(var)); /*lint !e777*/
1534  assert(SCIPvarGetLbGlobal(var) == SCIPvarGetLbLocal(var)); /*lint !e777*/
1535  return 0.0; /* constants are ignored for computing the ray direction */
1536 
1537  case SCIP_VARSTATUS_AGGREGATED: /* x = a*y + c => y = (x-c)/a */
1538  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetAggrVar(var));
1539  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1540  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1541  return SCIPvarGetAggrScalar(var) * solval; /* constants are ignored for computing the ray direction */
1542 
1544  nvars = SCIPvarGetMultaggrNVars(var);
1545  vars = SCIPvarGetMultaggrVars(var);
1546  scalars = SCIPvarGetMultaggrScalars(var);
1547  solvalsum = 0.0; /* constants are ignored for computing the ray direction */
1548  for( i = 0; i < nvars; ++i )
1549  {
1550  solval = SCIPsolGetRayVal(sol, set, stat, vars[i]);
1551  assert(solval != SCIP_UNKNOWN ); /*lint !e777*/
1552  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1553  solvalsum += scalars[i] * solval;
1554  }
1555  return solvalsum;
1556 
1558  solval = SCIPsolGetRayVal(sol, set, stat, SCIPvarGetNegationVar(var));
1559  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1560  assert(!SCIPsetIsInfinity(set, REALABS(solval)));
1561  return -solval; /* constants are ignored for computing the ray direction */
1562 
1563  default:
1564  SCIPerrorMessage("unknown variable status\n");
1565  SCIPABORT();
1566  return 0.0; /*lint !e527*/
1567  }
1568 }
1569 
1570 /** gets objective value of primal CIP solution in transformed problem */
1572  SCIP_SOL* sol, /**< primal CIP solution */
1573  SCIP_SET* set, /**< global SCIP settings */
1574  SCIP_PROB* transprob, /**< tranformed problem data */
1575  SCIP_PROB* origprob /**< original problem data */
1576  )
1577 {
1578  assert(sol != NULL);
1579 
1580  /* for original solutions, sol->obj contains the external objective value */
1581  if( SCIPsolIsOriginal(sol) )
1582  return SCIPprobInternObjval(transprob, origprob, set, sol->obj);
1583  else
1584  return sol->obj;
1585 }
1586 
1587 /** updates primal solutions after a change in a variable's objective value */
1589  SCIP_SOL* sol, /**< primal CIP solution */
1590  SCIP_VAR* var, /**< problem variable */
1591  SCIP_Real oldobj, /**< old objective value */
1592  SCIP_Real newobj /**< new objective value */
1593  )
1594 {
1595  SCIP_Real solval;
1596 
1597  assert(sol != NULL);
1598  assert(!SCIPsolIsOriginal(sol));
1600 
1601  solval = solGetArrayVal(sol, var);
1602  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1603  sol->obj += (newobj - oldobj) * solval;
1604 }
1605 
1606 /* mark the given solution as partial solution */
1608  SCIP_SOL* sol, /**< primal CIP solution */
1609  SCIP_SET* set, /**< global SCIP settings */
1610  SCIP_STAT* stat, /**< problem statistics */
1611  SCIP_VAR** vars, /**< problem variables */
1612  int nvars /**< number of problem variables */
1613  )
1614 {
1615  SCIP_Real* vals;
1616  int v;
1617 
1618  assert(sol != NULL);
1619  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
1620  assert(nvars == 0 || vars != NULL);
1621 
1622  if( nvars == 0 )
1623  return SCIP_OKAY;;
1624 
1625  SCIP_CALL( SCIPsetAllocBufferArray(set, &vals, nvars) );
1626 
1627  /* get values */
1628  for( v = 0; v < nvars; v++ )
1629  {
1630  assert(!SCIPvarIsTransformed(vars[v]));
1631  vals[v] = SCIPsolGetVal(sol, set, stat, vars[v]);
1632  }
1633 
1634  /* change origin to partial */
1636 
1637  /* set values */
1638  for( v = 0; v < nvars; v++ )
1639  {
1640  int idx = SCIPvarGetIndex(vars[v]);
1641 
1642  if( vals[v] != SCIP_UNKNOWN ) /*lint !e777*/
1643  {
1644  /* from now on, variable must not be deleted */
1645  SCIPvarMarkNotDeletable(vars[v]);
1646 
1647  /* mark the variable valid */
1648  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, TRUE) );
1649 
1650  /* set the value in the solution array */
1651  SCIP_CALL( SCIPrealarraySetVal(sol->vals, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, vals[v]) );
1652  }
1653  else
1654  {
1655  /* mark the variable invalid */
1656  SCIP_CALL( SCIPboolarraySetVal(sol->valid, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, FALSE) );
1657  }
1658  }
1659 
1660  /* free buffer */
1661  SCIPsetFreeBufferArray(set, &vals);
1662 
1663  return SCIP_OKAY;
1664 }
1665 
1666 /** checks primal CIP solution for feasibility
1667  *
1668  * @note The difference between SCIPsolCheck() and SCIPcheckSolOrig() is that modifiable constraints are handled
1669  * differently. There might be some variables which do not have an original counter part (e.g. in
1670  * branch-and-price). Therefore, modifiable constraints can not be double-checked in the original space.
1671  */
1673  SCIP_SOL* sol, /**< primal CIP solution */
1674  SCIP_SET* set, /**< global SCIP settings */
1675  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1676  BMS_BLKMEM* blkmem, /**< block memory */
1677  SCIP_STAT* stat, /**< problem statistics */
1678  SCIP_PROB* prob, /**< transformed problem data */
1679  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1680  SCIP_Bool completely, /**< Should all violations be checked? */
1681  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1682  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1683  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1684  SCIP_Bool* feasible /**< stores whether solution is feasible */
1685  )
1686 {
1687  SCIP_RESULT result;
1688  int h;
1689 
1690  assert(sol != NULL);
1691  assert(!SCIPsolIsOriginal(sol));
1692  assert(set != NULL);
1693  assert(prob != NULL);
1694  assert(feasible != NULL);
1695 
1696  SCIPsetDebugMsg(set, "checking solution with objective value %g (nodenum=%" SCIP_LONGINT_FORMAT ", origin=%d)\n",
1697  sol->obj, sol->nodenum, sol->solorigin);
1698 
1699  *feasible = TRUE;
1700 
1702 
1703  if( !printreason )
1704  completely = FALSE;
1705 
1706  /* check whether the solution respects the global bounds of the variables */
1707  if( checkbounds || sol->hasinfval )
1708  {
1709  int v;
1710 
1711  for( v = 0; v < prob->nvars && (*feasible || completely); ++v )
1712  {
1713  SCIP_VAR* var;
1714  SCIP_Real solval;
1715 
1716  var = prob->vars[v];
1717  solval = SCIPsolGetVal(sol, set, stat, var);
1718 
1719  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1720  {
1721  SCIP_Real lb;
1722  SCIP_Real ub;
1723 
1724  lb = SCIPvarGetLbGlobal(var);
1725  ub = SCIPvarGetUbGlobal(var);
1726 
1727  /* if we have to check bound and one of the current bounds is violated */
1728  if( checkbounds && ((!SCIPsetIsInfinity(set, -lb) && SCIPsetIsFeasLT(set, solval, lb))
1729  || (!SCIPsetIsInfinity(set, ub) && SCIPsetIsFeasGT(set, solval, ub))) )
1730  {
1731  *feasible = FALSE;
1732 
1733  if( printreason )
1734  {
1735  SCIPmessagePrintInfo(messagehdlr, "solution value %g violates bounds of <%s>[%g,%g] by %g\n", solval, SCIPvarGetName(var),
1736  SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), MAX(lb - solval, 0.0) + MAX(solval - ub, 0.0));
1737  }
1738 #ifdef SCIP_DEBUG
1739  else
1740  {
1741  SCIPsetDebugMsgPrint(set, " -> solution value %g violates bounds of <%s>[%g,%g]\n", solval, SCIPvarGetName(var),
1743  }
1744 #endif
1745  }
1746 
1747  /* check whether there are infinite variable values that lead to an objective value of +infinity */
1748  if( *feasible && sol->hasinfval )
1749  {
1750  *feasible = *feasible && (!SCIPsetIsInfinity(set, solval) || SCIPsetIsLE(set, SCIPvarGetUnchangedObj(var), 0.0) );
1751  *feasible = *feasible && (!SCIPsetIsInfinity(set, -solval) || SCIPsetIsGE(set, SCIPvarGetUnchangedObj(var), 0.0) );
1752 
1753  if( ((SCIPsetIsInfinity(set, solval) && SCIPsetIsGT(set, SCIPvarGetUnchangedObj(var), 0.0)) || (SCIPsetIsInfinity(set, -solval) && SCIPsetIsLT(set, SCIPvarGetUnchangedObj(var), 0.0))) )
1754  {
1755  if( printreason )
1756  {
1757  SCIPmessagePrintInfo(messagehdlr, "infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1758  solval, SCIPvarGetName(var), SCIPvarGetUnchangedObj(var));
1759  }
1760 #ifdef SCIP_DEBUG
1761  else
1762  {
1763  SCIPsetDebugMsgPrint(set, "infinite solution value %g for variable <%s> with obj %g implies objective value +infinity\n",
1764  solval, SCIPvarGetName(var), SCIPvarGetUnchangedObj(var));
1765  }
1766 #endif
1767  }
1768  }
1769  }
1770  }
1771  }
1772 
1773  /* check whether the solution fulfills all constraints */
1774  for( h = 0; h < set->nconshdlrs && (*feasible || completely); ++h )
1775  {
1776  SCIP_CALL( SCIPconshdlrCheck(set->conshdlrs[h], blkmem, set, stat, sol,
1777  checkintegrality, checklprows, printreason, completely, &result) );
1778  *feasible = *feasible && (result == SCIP_FEASIBLE);
1779 
1780 #ifdef SCIP_DEBUG
1781  if( !(*feasible) )
1782  {
1783  SCIPdebugPrintf(" -> infeasibility detected in constraint handler <%s>\n",
1784  SCIPconshdlrGetName(set->conshdlrs[h]));
1785  }
1786 #endif
1787  }
1788 
1789  return SCIP_OKAY;
1790 }
1791 
1792 /** try to round given solution */
1794  SCIP_SOL* sol, /**< primal solution */
1795  SCIP_SET* set, /**< global SCIP settings */
1796  SCIP_STAT* stat, /**< problem statistics data */
1797  SCIP_PROB* prob, /**< transformed problem data */
1798  SCIP_TREE* tree, /**< branch and bound tree */
1799  SCIP_Bool* success /**< pointer to store whether rounding was successful */
1800  )
1801 {
1802  int nvars;
1803  int v;
1804 
1805  assert(sol != NULL);
1806  assert(!SCIPsolIsOriginal(sol));
1807  assert(prob != NULL);
1808  assert(prob->transformed);
1809  assert(success != NULL);
1810 
1811  /* round all roundable fractional variables in the corresponding direction as long as no unroundable var was found */
1812  nvars = prob->nbinvars + prob->nintvars;
1813  for( v = 0; v < nvars; ++v )
1814  {
1815  SCIP_VAR* var;
1816  SCIP_Real solval;
1817  SCIP_Bool mayrounddown;
1818  SCIP_Bool mayroundup;
1819 
1820  var = prob->vars[v];
1823  || sol->lpcount == stat->lpcount);
1824  solval = solGetArrayVal(sol, var);
1825 
1826  /* solutions with unknown entries cannot be rounded */
1827  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1828  break;
1829 
1830  /* if solution value is already integral with feastol, continue */
1831  if( SCIPsetIsFeasIntegral(set, solval) )
1832  continue;
1833 
1834  /* get rounding possibilities */
1835  mayrounddown = SCIPvarMayRoundDown(var);
1836  mayroundup = SCIPvarMayRoundUp(var);
1837 
1838  /* choose rounding direction */
1839  if( mayrounddown && mayroundup )
1840  {
1841  /* we can round in both directions: round in objective function direction */
1842  if( SCIPvarGetUnchangedObj(var) >= 0.0 )
1843  solval = SCIPsetFeasFloor(set, solval);
1844  else
1845  solval = SCIPsetFeasCeil(set, solval);
1846  }
1847  else if( mayrounddown )
1848  solval = SCIPsetFeasFloor(set, solval);
1849  else if( mayroundup )
1850  solval = SCIPsetFeasCeil(set, solval);
1851  else
1852  break;
1853 
1854  /* store new solution value */
1855  SCIP_CALL( SCIPsolSetVal(sol, set, stat, tree, var, solval) );
1856  }
1857 
1858  /* check, if rounding was successful */
1859  *success = (v == nvars);
1860 
1861  return SCIP_OKAY;
1862 }
1863 
1864 /** updates the solution value sums in variables by adding the value in the given solution */
1866  SCIP_SOL* sol, /**< primal CIP solution */
1867  SCIP_SET* set, /**< global SCIP settings */
1868  SCIP_STAT* stat, /**< problem statistics data */
1869  SCIP_PROB* prob, /**< transformed problem data */
1870  SCIP_Real weight /**< weight of solution in weighted average */
1871  )
1872 {
1873  SCIP_Real solval;
1874  int v;
1875 
1876  assert(sol != NULL);
1877  assert(!SCIPsolIsOriginal(sol));
1878  assert(0.0 <= weight && weight <= 1.0);
1879 
1880  for( v = 0; v < prob->nvars; ++v )
1881  {
1882  assert(prob->vars[v] != NULL);
1883  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
1884  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
1885  {
1886  prob->vars[v]->primsolavg *= (1.0-weight);
1887  prob->vars[v]->primsolavg += weight*solval;
1888  }
1889  }
1890 }
1891 
1892 /** retransforms solution to original problem space */
1894  SCIP_SOL* sol, /**< primal CIP solution */
1895  SCIP_SET* set, /**< global SCIP settings */
1896  SCIP_STAT* stat, /**< problem statistics data */
1897  SCIP_PROB* origprob, /**< original problem */
1898  SCIP_PROB* transprob, /**< transformed problem */
1899  SCIP_Bool* hasinfval /**< pointer to store whether the solution has infinite values */
1900  )
1901 {
1902  SCIP_VAR** transvars;
1903  SCIP_VAR** vars;
1904  SCIP_VAR** activevars;
1905  SCIP_Real* solvals;
1906  SCIP_Real* activevals;
1907  SCIP_Real* transsolvals;
1908  SCIP_Real constant;
1909  int requiredsize;
1910  int ntransvars;
1911  int nactivevars;
1912  int nvars;
1913  int v;
1914  int i;
1915 
1916  assert(sol != NULL);
1917  assert(sol->solorigin == SCIP_SOLORIGIN_ZERO);
1918  assert(origprob != NULL);
1919  assert(transprob != NULL);
1920  assert(hasinfval != NULL);
1921  assert(!origprob->transformed);
1922  assert(transprob->transformed);
1923 
1924  *hasinfval = FALSE;
1925 
1926  /* This method was a performance bottleneck when retransforming a solution during presolving, before flattening the
1927  * aggregation graph. In that case, calling SCIPsolGetVal() on the original variable consumed too much
1928  * time. Therefore, we now first compute the active representation of each original variable using
1929  * SCIPvarGetActiveRepresentatives(), which is much faster, and sum up the solution values of the active variables by
1930  * hand for each original variable.
1931  */
1932  vars = origprob->vars;
1933  nvars = origprob->nvars;
1934  transvars = transprob->vars;
1935  ntransvars = transprob->nvars;
1936 
1937  /* allocate temporary memory for getting the active representation of the original variables, buffering the solution
1938  * values of all active variables and storing the original solution values
1939  */
1940  SCIP_CALL( SCIPsetAllocBufferArray(set, &transsolvals, ntransvars + 1) );
1941  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevars, ntransvars + 1) );
1942  SCIP_CALL( SCIPsetAllocBufferArray(set, &activevals, ntransvars + 1) );
1943  SCIP_CALL( SCIPsetAllocBufferArray(set, &solvals, nvars) );
1944  assert(transsolvals != NULL); /* for flexelint */
1945  assert(solvals != NULL); /* for flexelint */
1946 
1947  /* get the solution values of all active variables */
1948  for( v = 0; v < ntransvars; ++v )
1949  {
1950  transsolvals[v] = SCIPsolGetVal(sol, set, stat, transvars[v]);
1951  }
1952 
1953  /* get the solution in original problem variables */
1954  for( v = 0; v < nvars; ++v )
1955  {
1956  activevars[0] = vars[v];
1957  activevals[0] = 1.0;
1958  nactivevars = 1;
1959  constant = 0.0;
1960 
1961  /* get active representation of the original variable */
1962  SCIP_CALL( SCIPvarGetActiveRepresentatives(set, activevars, activevals, &nactivevars, ntransvars + 1, &constant,
1963  &requiredsize, TRUE) );
1964  assert(requiredsize <= ntransvars);
1965 
1966  /* compute solution value of the original variable */
1967  solvals[v] = constant;
1968  for( i = 0; i < nactivevars; ++i )
1969  {
1970  assert(0 <= SCIPvarGetProbindex(activevars[i]) && SCIPvarGetProbindex(activevars[i]) < ntransvars);
1971  assert(!SCIPsetIsInfinity(set, -solvals[v]) || !SCIPsetIsInfinity(set, activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1972  assert(!SCIPsetIsInfinity(set, solvals[v]) || !SCIPsetIsInfinity(set, -activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])]));
1973  solvals[v] += activevals[i] * transsolvals[SCIPvarGetProbindex(activevars[i])];
1974  }
1975 
1976  if( SCIPsetIsInfinity(set, solvals[v]) )
1977  {
1978  solvals[v] = SCIPsetInfinity(set);
1979  *hasinfval = TRUE;
1980  }
1981  else if( SCIPsetIsInfinity(set, -solvals[v]) )
1982  {
1983  solvals[v] = -SCIPsetInfinity(set);
1984  *hasinfval = TRUE;
1985  }
1986  }
1987 
1988  /* clear the solution and convert it into original space */
1989  SCIP_CALL( solClearArrays(sol) );
1991  sol->obj = origprob->objoffset;
1992 
1993  /* reinsert the values of the original variables */
1994  for( v = 0; v < nvars; ++v )
1995  {
1996  assert(SCIPvarGetUnchangedObj(vars[v]) == SCIPvarGetObj(vars[v])); /*lint !e777*/
1997 
1998  if( solvals[v] != 0.0 )
1999  {
2000  SCIP_CALL( solSetArrayVal(sol, set, vars[v], solvals[v]) );
2001  if( solvals[v] != SCIP_UNKNOWN ) /*lint !e777*/
2002  sol->obj += SCIPvarGetUnchangedObj(vars[v]) * solvals[v];
2003  }
2004  }
2005 
2006  /**@todo remember the variables without original counterpart (priced variables) in the solution */
2007 
2008  /* free temporary memory */
2009  SCIPsetFreeBufferArray(set, &solvals);
2010  SCIPsetFreeBufferArray(set, &activevals);
2011  SCIPsetFreeBufferArray(set, &activevars);
2012  SCIPsetFreeBufferArray(set, &transsolvals);
2013 
2014  return SCIP_OKAY;
2015 }
2016 
2017 /** recomputes the objective value of an original solution, e.g., when transferring solutions
2018  * from the solution pool (objective coefficients might have changed in the meantime)
2019  */
2021  SCIP_SOL* sol, /**< primal CIP solution */
2022  SCIP_SET* set, /**< global SCIP settings */
2023  SCIP_STAT* stat, /**< problem statistics data */
2024  SCIP_PROB* origprob /**< original problem */
2025  )
2026 {
2027  SCIP_VAR** vars;
2028  SCIP_Real solval;
2029  int nvars;
2030  int v;
2031 
2032  assert(sol != NULL);
2033  assert(SCIPsolIsOriginal(sol));
2034  assert(origprob != NULL);
2035 
2036  vars = origprob->vars;
2037  nvars = origprob->nvars;
2038 
2039  /* recompute the objective value */
2040  sol->obj = SCIPprobGetObjoffset(origprob);
2041  for( v = 0; v < nvars; ++v )
2042  {
2043  solval = SCIPsolGetVal(sol, set, stat, vars[v]);
2044  if( solval != 0.0 && solval != SCIP_UNKNOWN ) /*lint !e777*/
2045  {
2046  sol->obj += SCIPvarGetUnchangedObj(vars[v]) * solval;
2047  }
2048  }
2049 
2050  if( SCIPsetIsInfinity(set, -sol->obj) )
2051  sol->obj = -SCIPsetInfinity(set);
2052 }
2053 
2054 /** returns whether the given solutions are equal */
2056  SCIP_SOL* sol1, /**< first primal CIP solution */
2057  SCIP_SOL* sol2, /**< second primal CIP solution */
2058  SCIP_SET* set, /**< global SCIP settings */
2059  SCIP_STAT* stat, /**< problem statistics data */
2060  SCIP_PROB* origprob, /**< original problem */
2061  SCIP_PROB* transprob /**< transformed problem after presolve, or NULL if both solution are
2062  * defined in the original problem space */
2063  )
2064 {
2065  SCIP_PROB* prob;
2066  SCIP_Bool infobjs;
2067  SCIP_Real obj1;
2068  SCIP_Real obj2;
2069  int v;
2070 
2071  assert(sol1 != NULL);
2072  assert(sol2 != NULL);
2073  assert((SCIPsolIsOriginal(sol1) && SCIPsolIsOriginal(sol2)) || transprob != NULL);
2074 
2075  /* if both solutions are original or both are transformed, take the objective values stored in the solutions */
2076  if( SCIPsolIsOriginal(sol1) == SCIPsolIsOriginal(sol2) )
2077  {
2078  obj1 = sol1->obj;
2079  obj2 = sol2->obj;
2080  }
2081  /* one solution is original and the other not, so we have to get for both the objective in the transformed problem */
2082  else
2083  {
2084  obj1 = SCIPsolGetObj(sol1, set, transprob, origprob);
2085  obj2 = SCIPsolGetObj(sol2, set, transprob, origprob);
2086  }
2087 
2088  /* solutions with different objective values cannot be the same; we consider two infinite objective values with the
2089  * same sign always to be different
2090  */
2091  infobjs = (SCIPsetIsInfinity(set, obj1) && SCIPsetIsInfinity(set, obj2))
2092  || (SCIPsetIsInfinity(set, -obj1) && SCIPsetIsInfinity(set, -obj2));
2093  if( !infobjs && !SCIPsetIsEQ(set, obj1, obj2) )
2094  return FALSE;
2095 
2096  /* if one of the solutions is defined in the original space, the comparison has to be performed in the original
2097  * space
2098  */
2099  prob = transprob;
2100  if( SCIPsolIsOriginal(sol1) || SCIPsolIsOriginal(sol2) )
2101  prob = origprob;
2102  assert(prob != NULL);
2103 
2104  /* compare each variable value */
2105  for( v = 0; v < prob->nvars; ++v )
2106  {
2107  SCIP_Real val1;
2108  SCIP_Real val2;
2109 
2110  val1 = SCIPsolGetVal(sol1, set, stat, prob->vars[v]);
2111  val2 = SCIPsolGetVal(sol2, set, stat, prob->vars[v]);
2112  if( !SCIPsetIsEQ(set, val1, val2) )
2113  return FALSE;
2114  }
2115 
2116  return TRUE;
2117 }
2118 
2119 /** outputs non-zero elements of solution to file stream */
2121  SCIP_SOL* sol, /**< primal CIP solution */
2122  SCIP_SET* set, /**< global SCIP settings */
2123  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2124  SCIP_STAT* stat, /**< problem statistics data */
2125  SCIP_PROB* prob, /**< problem data (original or transformed) */
2126  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
2127  FILE* file, /**< output file (or NULL for standard output) */
2128  SCIP_Bool mipstart, /**< should only discrete variables be printed? */
2129  SCIP_Bool printzeros /**< should variables set to zero be printed? */
2130  )
2131 {
2132  SCIP_Real solval;
2133  int v;
2134 
2135  assert(sol != NULL);
2136  assert(prob != NULL);
2137  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
2138  assert(!mipstart || !SCIPsolIsPartial(sol));
2139 
2140  /* display variables of problem data */
2141  for( v = 0; v < prob->nfixedvars; ++v )
2142  {
2143  assert(prob->fixedvars[v] != NULL);
2144 
2145  /* skip non-discrete variables in a mip start */
2146  if( mipstart && !SCIPvarIsIntegral(prob->fixedvars[v]) )
2147  continue;
2148 
2149  solval = SCIPsolGetVal(sol, set, stat, prob->fixedvars[v]);
2150  if( printzeros || mipstart
2151  || (sol->solorigin != SCIP_SOLORIGIN_PARTIAL && !SCIPsetIsZero(set, solval))
2152  || (sol->solorigin == SCIP_SOLORIGIN_PARTIAL && solval != SCIP_UNKNOWN) ) /*lint !e777*/
2153  {
2154  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
2155  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2156  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2157  else if( SCIPsetIsInfinity(set, solval) )
2158  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2159  else if( SCIPsetIsInfinity(set, -solval) )
2160  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2161  else
2162  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2163  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->fixedvars[v]));
2164  }
2165  }
2166 
2167  for( v = 0; v < prob->nvars; ++v )
2168  {
2169  assert(prob->vars[v] != NULL);
2170 
2171  /* skip non-discrete variables in a mip start */
2172  if( mipstart && !SCIPvarIsIntegral(prob->vars[v]) )
2173  continue;
2174 
2175  solval = SCIPsolGetVal(sol, set, stat, prob->vars[v]);
2176  if( printzeros || mipstart
2177  || (sol->solorigin != SCIP_SOLORIGIN_PARTIAL && !SCIPsetIsZero(set, solval))
2178  || (sol->solorigin == SCIP_SOLORIGIN_PARTIAL && solval != SCIP_UNKNOWN) ) /*lint !e777*/
2179  {
2180  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
2181  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2182  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2183  else if( SCIPsetIsInfinity(set, solval) )
2184  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2185  else if( SCIPsetIsInfinity(set, -solval) )
2186  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2187  else
2188  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
2189  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->vars[v]));
2190  }
2191  }
2192 
2193  /* display additional priced variables (if given problem data is original problem); consider these variables only
2194  * if there is at least one active pricer, otherwise we might print variables that have been added by, e.g., the
2195  * dual sparsify presolver (see #2946)
2196  */
2197  if( !prob->transformed && !SCIPsolIsOriginal(sol) && set->nactivepricers > 0 )
2198  {
2199  assert(transprob != NULL);
2200  for( v = 0; v < transprob->nfixedvars; ++v )
2201  {
2202  assert(transprob->fixedvars[v] != NULL);
2203  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
2204  continue;
2205 
2206  /* skip non-discrete variables in a mip start */
2207  if( mipstart && !SCIPvarIsIntegral(transprob->fixedvars[v]) )
2208  continue;
2209 
2210  solval = SCIPsolGetVal(sol, set, stat, transprob->fixedvars[v]);
2211  if( printzeros || mipstart || !SCIPsetIsZero(set, solval) )
2212  {
2213  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[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->fixedvars[v]));
2223  }
2224  }
2225  for( v = 0; v < transprob->nvars; ++v )
2226  {
2227  assert(transprob->vars[v] != NULL);
2228  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
2229  continue;
2230 
2231  /* skip non-discrete variables in a mip start */
2232  if( mipstart && !SCIPvarIsIntegral(transprob->vars[v]) )
2233  continue;
2234 
2235  solval = SCIPsolGetVal(sol, set, stat, transprob->vars[v]);
2236  if( printzeros || !SCIPsetIsZero(set, solval) )
2237  {
2238  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
2239  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2240  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2241  else if( SCIPsetIsInfinity(set, solval) )
2242  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2243  else if( SCIPsetIsInfinity(set, -solval) )
2244  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2245  else
2246  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2247  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->vars[v]));
2248  }
2249  }
2250  }
2251 
2252  return SCIP_OKAY;
2253 }
2254 
2255 /** outputs non-zero elements of solution representing a ray to file stream */
2257  SCIP_SOL* sol, /**< primal CIP solution */
2258  SCIP_SET* set, /**< global SCIP settings */
2259  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
2260  SCIP_STAT* stat, /**< problem statistics data */
2261  SCIP_PROB* prob, /**< problem data (original or transformed) */
2262  SCIP_PROB* transprob, /**< transformed problem data or NULL (to display priced variables) */
2263  FILE* file, /**< output file (or NULL for standard output) */
2264  SCIP_Bool printzeros /**< should variables set to zero be printed? */
2265  )
2266 {
2267  SCIP_Real solval;
2268  int v;
2269 
2270  assert(sol != NULL);
2271  assert(prob != NULL);
2272  assert(SCIPsolIsOriginal(sol) || prob->transformed || transprob != NULL);
2273 
2274  /* display variables of problem data */
2275  for( v = 0; v < prob->nfixedvars; ++v )
2276  {
2277  assert(prob->fixedvars[v] != NULL);
2278  solval = SCIPsolGetRayVal(sol, set, stat, prob->fixedvars[v]);
2279  if( printzeros || !SCIPsetIsZero(set, solval) )
2280  {
2281  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->fixedvars[v]));
2282  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2283  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2284  else if( SCIPsetIsInfinity(set, solval) )
2285  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2286  else if( SCIPsetIsInfinity(set, -solval) )
2287  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2288  else
2289  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2290  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->fixedvars[v]));
2291  }
2292  }
2293  for( v = 0; v < prob->nvars; ++v )
2294  {
2295  assert(prob->vars[v] != NULL);
2296  solval = SCIPsolGetRayVal(sol, set, stat, prob->vars[v]);
2297  if( printzeros || !SCIPsetIsZero(set, solval) )
2298  {
2299  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(prob->vars[v]));
2300  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2301  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2302  else if( SCIPsetIsInfinity(set, solval) )
2303  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2304  else if( SCIPsetIsInfinity(set, -solval) )
2305  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2306  else
2307  SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g", solval);
2308  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(prob->vars[v]));
2309  }
2310  }
2311 
2312  /* display additional priced variables (if given problem data is original problem) */
2313  if( !prob->transformed && !SCIPsolIsOriginal(sol) )
2314  {
2315  assert(transprob != NULL);
2316  for( v = 0; v < transprob->nfixedvars; ++v )
2317  {
2318  assert(transprob->fixedvars[v] != NULL);
2319  if( SCIPvarIsTransformedOrigvar(transprob->fixedvars[v]) )
2320  continue;
2321 
2322  solval = SCIPsolGetRayVal(sol, set, stat, transprob->fixedvars[v]);
2323  if( printzeros || !SCIPsetIsZero(set, solval) )
2324  {
2325  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->fixedvars[v]));
2326  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2327  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2328  else if( SCIPsetIsInfinity(set, solval) )
2329  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2330  else if( SCIPsetIsInfinity(set, -solval) )
2331  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2332  else
2333  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2334  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->fixedvars[v]));
2335  }
2336  }
2337  for( v = 0; v < transprob->nvars; ++v )
2338  {
2339  assert(transprob->vars[v] != NULL);
2340  if( SCIPvarIsTransformedOrigvar(transprob->vars[v]) )
2341  continue;
2342 
2343  solval = SCIPsolGetRayVal(sol, set, stat, transprob->vars[v]);
2344  if( printzeros || !SCIPsetIsZero(set, solval) )
2345  {
2346  SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPvarGetName(transprob->vars[v]));
2347  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2348  SCIPmessageFPrintInfo(messagehdlr, file, " unknown");
2349  else if( SCIPsetIsInfinity(set, solval) )
2350  SCIPmessageFPrintInfo(messagehdlr, file, " +infinity");
2351  else if( SCIPsetIsInfinity(set, -solval) )
2352  SCIPmessageFPrintInfo(messagehdlr, file, " -infinity");
2353  else
2354  SCIPmessageFPrintInfo(messagehdlr, file, " % 20.15g", solval);
2355  SCIPmessageFPrintInfo(messagehdlr, file, " \t(obj:%.15g)\n", SCIPvarGetUnchangedObj(transprob->vars[v]));
2356  }
2357  }
2358  }
2359 
2360  return SCIP_OKAY;
2361 }
2362 
2363 /*
2364  * methods for accumulated numerical violations of a solution
2365  */
2366 
2367 /** reset violations of a solution */
2369  SCIP_SOL* sol /**< primal CIP solution */
2370  )
2371 {
2372  assert(sol != NULL);
2373 
2374  sol->viol.absviolbounds = 0.0;
2375  sol->viol.relviolbounds = 0.0;
2376  sol->viol.absviolintegrality = 0.0;
2377  sol->viol.absviollprows = 0.0;
2378  sol->viol.relviollprows = 0.0;
2379  sol->viol.absviolcons = 0.0;
2380  sol->viol.relviolcons = 0.0;
2381 }
2382 
2383 /** update integrality violation of a solution */
2385  SCIP_SOL* sol, /**< primal CIP solution */
2386  SCIP_Real absviolintegrality /**< absolute violation of integrality */
2387  )
2388 {
2389  assert(sol != NULL);
2390 
2391  sol->viol.absviolintegrality = MAX(sol->viol.absviolintegrality, absviolintegrality);
2392 }
2393 
2394 /** update bound violation of a solution */
2396  SCIP_SOL* sol, /**< primal CIP solution */
2397  SCIP_Real absviolbounds, /**< absolute violation of bounds */
2398  SCIP_Real relviolbounds /**< relative violation of bounds */
2399  )
2400 {
2401  assert(sol != NULL);
2402 
2403  sol->viol.absviolbounds = MAX(sol->viol.absviolbounds, absviolbounds);
2404  sol->viol.relviolbounds = MAX(sol->viol.relviolbounds, relviolbounds);
2405 }
2406 
2407 /** update LP row violation of a solution */
2409  SCIP_SOL* sol, /**< primal CIP solution */
2410  SCIP_Real absviollprows, /**< absolute violation of LP rows */
2411  SCIP_Real relviollprows /**< relative violation of LP rows */
2412  )
2413 {
2414  assert(sol != NULL);
2415 
2416  sol->viol.absviollprows = MAX(sol->viol.absviollprows, absviollprows);
2417  sol->viol.relviollprows = MAX(sol->viol.relviollprows, relviollprows);
2418 }
2419 
2420 /** update constraint violation of a solution */
2422  SCIP_SOL* sol, /**< primal CIP solution */
2423  SCIP_Real absviolcons, /**< absolute violation of constraint */
2424  SCIP_Real relviolcons /**< relative violation of constraint */
2425  )
2426 {
2427  assert(sol != NULL);
2428 
2429  sol->viol.absviolcons = MAX(sol->viol.absviolcons, absviolcons);
2430  sol->viol.relviolcons = MAX(sol->viol.relviolcons, relviolcons);
2431 }
2432 
2433 /** update violation of a constraint that is represented in the LP */
2435  SCIP_SOL* sol, /**< primal CIP solution */
2436  SCIP_Real absviol, /**< absolute violation of constraint */
2437  SCIP_Real relviol /**< relative violation of constraint */
2438  )
2439 {
2440  assert(sol != NULL);
2441 
2442  SCIPsolUpdateConsViolation(sol, absviol, relviol);
2443  SCIPsolUpdateLPRowViolation(sol, absviol, relviol);
2444 }
2445 
2446 /** get maximum absolute bound violation of solution */
2448  SCIP_SOL* sol /**< primal CIP solution */
2449  )
2450 {
2451  assert(sol != NULL);
2452 
2453  return sol->viol.absviolbounds;
2454 }
2455 
2456 /** get maximum relative bound violation of solution */
2458  SCIP_SOL* sol /**< primal CIP solution */
2459  )
2460 {
2461  assert(sol != NULL);
2462 
2463  return sol->viol.relviolbounds;
2464 }
2465 
2466 /** get maximum absolute integrality violation of solution */
2468  SCIP_SOL* sol /**< primal CIP solution */
2469  )
2470 {
2471  assert(sol != NULL);
2472 
2473  return sol->viol.absviolintegrality;
2474 }
2475 
2476 /** get maximum absolute LP row violation of solution */
2478  SCIP_SOL* sol /**< primal CIP solution */
2479  )
2480 {
2481  assert(sol != NULL);
2482 
2483  return sol->viol.absviollprows;
2484 }
2485 
2486 /** get maximum relative LP row violation of solution */
2488  SCIP_SOL* sol /**< primal CIP solution */
2489  )
2490 {
2491  assert(sol != NULL);
2492 
2493  return sol->viol.relviollprows;
2494 }
2495 
2496 /** get maximum absolute constraint violation of solution */
2498  SCIP_SOL* sol /**< primal CIP solution */
2499  )
2500 {
2501  assert(sol != NULL);
2502 
2503  return sol->viol.absviolcons;
2504 }
2505 
2506 /** get maximum relative constraint violation of solution */
2508  SCIP_SOL* sol /**< primal CIP solution */
2509  )
2510 {
2511  assert(sol != NULL);
2512 
2513  return sol->viol.relviolcons;
2514 }
2515 
2516 /*
2517  * simple functions implemented as defines
2518  */
2519 
2520 /* In debug mode, the following methods are implemented as function calls to ensure
2521  * type validity.
2522  * In optimized mode, the methods are implemented as defines to improve performance.
2523  * However, we want to have them in the library anyways, so we have to undef the defines.
2524  */
2525 
2526 #undef SCIPsolGetOrigin
2527 #undef SCIPsolIsOriginal
2528 #undef SCIPsolGetOrigObj
2529 #undef SCIPsolGetTime
2530 #undef SCIPsolGetNodenum
2531 #undef SCIPsolGetRunnum
2532 #undef SCIPsolGetDepth
2533 #undef SCIPsolGetHeur
2534 #undef SCIPsolGetRelax
2535 #undef SCIPsolOrigAddObjval
2536 #undef SCIPsolGetPrimalIndex
2537 #undef SCIPsolSetPrimalIndex
2538 #undef SCIPsolGetIndex
2539 #undef SCIPsolGetType
2540 #undef SCIPsolSetLPRelaxation
2541 #undef SCIPsolSetStrongbranching
2542 #undef SCIPsolSetPseudo
2543 
2544 /** gets origin of solution */
2546  SCIP_SOL* sol /**< primal CIP solution */
2547  )
2548 {
2549  assert(sol != NULL);
2550 
2551  return sol->solorigin;
2552 }
2553 
2554 /** returns whether the given solution is defined on original variables */
2556  SCIP_SOL* sol /**< primal CIP solution */
2557  )
2558 {
2559  assert(sol != NULL);
2560 
2562 }
2563 
2564 /** returns whether the given solution is defined on original variables and containes unknown solution values */
2566  SCIP_SOL* sol /**< primal CIP solution */
2567  )
2568 {
2569  assert(sol != NULL);
2570 
2571  return (sol->solorigin == SCIP_SOLORIGIN_PARTIAL);
2572 }
2573 
2574 /** gets objective value of primal CIP solution which lives in the original problem space */
2576  SCIP_SOL* sol /**< primal CIP solution */
2577  )
2578 {
2579  assert(sol != NULL);
2580  assert(SCIPsolIsOriginal(sol));
2581 
2582  return sol->obj;
2583 }
2584 
2585 /** adds value to the objective value of a given original primal CIP solution */
2587  SCIP_SOL* sol, /**< primal CIP solution */
2588  SCIP_Real addval /**< offset value to add */
2589  )
2590 {
2591  assert(sol != NULL);
2592  assert(sol->solorigin == SCIP_SOLORIGIN_ORIGINAL);
2593 
2594  sol->obj += addval;
2595 }
2596 
2597 /** gets clock time, when this solution was found */
2599  SCIP_SOL* sol /**< primal CIP solution */
2600  )
2601 {
2602  assert(sol != NULL);
2603 
2604  return sol->time;
2605 }
2606 
2607 /** gets branch and bound run number, where this solution was found */
2609  SCIP_SOL* sol /**< primal CIP solution */
2610  )
2611 {
2612  assert(sol != NULL);
2613 
2614  return sol->runnum;
2615 }
2616 
2617 /** gets node number, where this solution was found */
2619  SCIP_SOL* sol /**< primal CIP solution */
2620  )
2621 {
2622  assert(sol != NULL);
2623 
2624  return sol->nodenum;
2625 }
2626 
2627 /** gets node's depth, where this solution was found */
2629  SCIP_SOL* sol /**< primal CIP solution */
2630  )
2631 {
2632  assert(sol != NULL);
2633 
2634  return sol->depth;
2635 }
2636 
2637 /** gets heuristic, that found this solution or NULL if solution has type different than SCIP_SOLTYPE_HEUR */
2639  SCIP_SOL* sol /**< primal CIP solution */
2640  )
2641 {
2642  assert(sol != NULL);
2643 
2644  return sol->type == SCIP_SOLTYPE_HEUR ? sol->creator.heur : NULL;
2645 }
2646 
2647 /** gets current position of solution in array of existing solutions of primal data */
2649  SCIP_SOL* sol /**< primal CIP solution */
2650  )
2651 {
2652  assert(sol != NULL);
2653 
2654  return sol->primalindex;
2655 }
2656 
2657 /** sets current position of solution in array of existing solutions of primal data */
2659  SCIP_SOL* sol, /**< primal CIP solution */
2660  int primalindex /**< new primal index of solution */
2661  )
2662 {
2663  assert(sol != NULL);
2664 
2665  sol->primalindex = primalindex;
2666 }
2667 
2668 /** returns unique index of given solution */
2670  SCIP_SOL* sol /**< primal CIP solution */
2671  )
2672 {
2673  assert(sol != NULL);
2674 
2675  return sol->index;
2676 }
2677 
2678 /** informs the solution that it now belongs to the given primal heuristic. For convenience and backwards compatibility,
2679  * the method accepts NULL as input for \p heur, in which case the solution type is set to SCIP_SOLTYPE_LPRELAX.
2680  *
2681  * @note Relaxation handlers should use SCIPsolSetRelax() instead.
2682  */
2684  SCIP_SOL* sol, /**< primal CIP solution */
2685  SCIP_HEUR* heur /**< primal heuristic that found the solution, or NULL for LP solutions */
2686  )
2687 {
2688  assert(sol != NULL);
2689 
2690  if( heur == NULL )
2692  else
2693  {
2694  sol->type = SCIP_SOLTYPE_HEUR;
2695  sol->creator.heur = heur;
2696  }
2697 }
2698 
2699 /** gets information if solution was found by the LP, a primal heuristic, or a custom relaxator */
2701  SCIP_SOL* sol /**< primal CIP solution */
2702  )
2703 {
2704  assert(sol != NULL);
2705 
2706  return sol->type;
2707 }
2708 
2709 /** gets relaxation handler that found this solution, or NULL if solution has different type than SCIP_SOLTYPE_RELAX */
2711  SCIP_SOL* sol /**< primal CIP solution */
2712  )
2713 {
2714  assert(sol != NULL);
2715 
2716  return sol->type == SCIP_SOLTYPE_RELAX ? sol->creator.relax : NULL;
2717 }
2718 
2719 /** informs the solution that it now belongs to the given relaxation handler */
2721  SCIP_SOL* sol, /**< primal CIP solution */
2722  SCIP_RELAX* relax /**< relaxator that found the solution */
2723  )
2724 {
2725  assert(sol != NULL);
2726  assert(relax != NULL);
2727 
2728  sol->type = SCIP_SOLTYPE_RELAX;
2729  sol->creator.relax = relax;
2730 }
2731 
2732 /** informs the solution that it is an LP relaxation solution */
2734  SCIP_SOL* sol /**< primal CIP solution */
2735  )
2736 {
2737  assert(sol != NULL);
2738 
2739  sol->type = SCIP_SOLTYPE_LPRELAX;
2740 }
2741 
2742 /** informs the solution that it is a solution found during strong branching */
2744  SCIP_SOL* sol /**< primal CIP solution */
2745  )
2746 {
2747  assert(sol != NULL);
2748 
2750 }
2751 
2752 /** informs the solution that it originates from a pseudo solution */
2754  SCIP_SOL* sol /**< primal CIP solution */
2755  )
2756 {
2757  assert(sol != NULL);
2758 
2759  sol->type = SCIP_SOLTYPE_PSEUDO;
2760 }
2761 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2555
void SCIPsolSetLPRelaxation(SCIP_SOL *sol)
Definition: sol.c:2733
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:1793
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:17486
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3296
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17847
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1701
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17693
SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
Definition: relax.c:839
SCIP_Real SCIPsolGetRelBoundViolation(SCIP_SOL *sol)
Definition: sol.c:2457
void SCIPsolSetRelax(SCIP_SOL *sol, SCIP_RELAX *relax)
Definition: sol.c:2720
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:17901
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:3354
union SCIP_Sol::@17 creator
internal methods for clocks and timing issues
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17161
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:17681
SCIP_RETCODE SCIPrealarrayCreate(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem)
Definition: misc.c:3980
SCIP_Bool SCIPboolarrayGetVal(SCIP_BOOLARRAY *boolarray, int idx)
Definition: misc.c:4963
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17957
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:17292
#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:17738
void SCIPsolSetPrimalIndex(SCIP_SOL *sol, int primalindex)
Definition: sol.c:2658
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:8404
SCIP_Real SCIPsolGetRayVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1502
SCIP_RETCODE SCIPsolSetUnknown(SCIP_SOL *sol, SCIP_STAT *stat, SCIP_TREE *tree)
Definition: sol.c:1031
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17591
SCIP_RETCODE SCIPboolarrayCopy(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem, SCIP_BOOLARRAY *sourceboolarray)
Definition: misc.c:4737
SCIP_Bool SCIPsolsAreEqual(SCIP_SOL *sol1, SCIP_SOL *sol2, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: sol.c:2055
SCIP_Real SCIPsolGetTime(SCIP_SOL *sol)
Definition: sol.c:2598
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17645
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:13302
SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
Definition: relax.c:808
SCIP_Real SCIPsolGetAbsConsViolation(SCIP_SOL *sol)
Definition: sol.c:2497
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:17727
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:13985
internal methods for LP management
Definition: heur_padm.c:132
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2575
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:1372
SCIP_RETCODE SCIPboolarraySetVal(SCIP_BOOLARRAY *boolarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Bool val)
Definition: misc.c:4984
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17575
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:17523
SCIP_Real SCIPsolGetRelConsViolation(SCIP_SOL *sol)
Definition: sol.c:2507
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4314
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17911
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:529
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8286
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:1571
SCIP_Real SCIPsolGetAbsIntegralityViolation(SCIP_SOL *sol)
Definition: sol.c:2467
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:1865
SCIP_RETCODE SCIPrealarrayCopy(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem, SCIP_REALARRAY *sourcerealarray)
Definition: misc.c:4000
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:4182
#define SCIPdebugPrintf
Definition: pub_message.h:99
SCIP_Longint lpcount
Definition: struct_stat.h:190
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17151
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:4717
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17565
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17401
SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition: var.c:12851
SCIP_Real SCIPrealarrayGetVal(SCIP_REALARRAY *realarray, int idx)
Definition: misc.c:4224
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:17657
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17242
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:2710
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:4932
#define NULL
Definition: lpi_spx1.cpp:164
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2638
SCIP_Real relviollprows
Definition: struct_sol.h:55
#define REALABS(x)
Definition: def.h:210
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18275
public methods for primal CIP solutions
void SCIPsolSetPseudo(SCIP_SOL *sol)
Definition: sol.c:2753
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:394
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:17705
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:17302
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:13119
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:2700
void SCIPsolRecomputeObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob)
Definition: sol.c:2020
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6466
#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:1679
#define SCIP_Bool
Definition: def.h:93
SCIP_VIOL viol
Definition: struct_sol.h:86
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2618
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:1296
SCIP_Real SCIPsolGetAbsBoundViolation(SCIP_SOL *sol)
Definition: sol.c:2447
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18288
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:4024
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:2683
void SCIPsolResetViolations(SCIP_SOL *sol)
Definition: sol.c:2368
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17857
#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:1893
SCIP_RETCODE SCIPsolMarkPartial(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR **vars, int nvars)
Definition: sol.c:1607
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:2120
void SCIPsolUpdateConsViolation(SCIP_SOL *sol, SCIP_Real absviolcons, SCIP_Real relviolcons)
Definition: sol.c:2421
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17759
public methods for LP management
#define SCIPsetDebugMsg
Definition: set.h:1770
void SCIPsolOrigAddObjval(SCIP_SOL *sol, SCIP_Real addval)
Definition: sol.c:2586
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17749
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:17633
SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
Definition: tree.c:8421
int SCIPnlpGetNVars(SCIP_NLP *nlp)
Definition: nlp.c:4212
void SCIPsolUpdateBoundViolation(SCIP_SOL *sol, SCIP_Real absviolbounds, SCIP_Real relviolbounds)
Definition: sol.c:2395
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17612
datastructures for problem statistics
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17669
SCIP_Bool transformed
Definition: struct_prob.h:88
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12764
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:2256
void SCIPsolUpdateIntegralityViolation(SCIP_SOL *sol, SCIP_Real absviolintegrality)
Definition: sol.c:2384
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:13158
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:17126
SCIP_Real SCIPsolGetRelLPRowViolation(SCIP_SOL *sol)
Definition: sol.c:2487
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17042
static const SCIP_Real scalars[]
Definition: lp.c:5743
void SCIPsolUpdateLPRowViolation(SCIP_SOL *sol, SCIP_Real absviollprows, SCIP_Real relviollprows)
Definition: sol.c:2408
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:3919
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:160
SCIP_RETCODE SCIPboolarrayFree(SCIP_BOOLARRAY **boolarray)
Definition: misc.c:4761
public methods for message output
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2545
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:17361
static SCIP_Real solGetArrayVal(SCIP_SOL *sol, SCIP_VAR *var)
Definition: sol.c:147
int SCIPsolGetPrimalIndex(SCIP_SOL *sol)
Definition: sol.c:2648
void SCIPsolUpdateVarObj(SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: sol.c:1588
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:17807
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:2628
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:17581
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:4245
SCIP_BOOLARRAY * valid
Definition: struct_sol.h:79
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17407
void SCIPsolUpdateLPConsViolation(SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: sol.c:2434
void SCIPsolSetStrongbranching(SCIP_SOL *sol)
Definition: sol.c:2743
SCIP_RELAX * relax
Definition: struct_sol.h:84
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17967
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17384
#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:2565
SCIP_Longint nnodes
Definition: struct_stat.h:82
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2608
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:3745
SCIP_Real SCIPvarGetPseudoSol(SCIP_VAR *var)
Definition: var.c:18353
SCIP_Real absviolcons
Definition: struct_sol.h:57
SCIP_VAR * SCIPvarGetTransVar(SCIP_VAR *var)
Definition: var.c:17601
#define SCIP_ALLOC(x)
Definition: def.h:405
#define SCIPABORT()
Definition: def.h:366
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17433
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:1672
SCIP_Bool SCIPnlpHasSolution(SCIP_NLP *nlp)
Definition: nlp.c:4430
datastructures for global SCIP settings
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:2669
SCIP_Real obj
Definition: struct_sol.h:75
int index
Definition: struct_sol.h:90
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3452
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3441
SCIP_Real SCIPsolGetAbsLPRowViolation(SCIP_SOL *sol)
Definition: sol.c:2477
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6745
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17571
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:801