Scippy

SCIP

Solving Constraint Integer Programs

primal.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-2018 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file primal.c
17  * @brief methods for collecting primal CIP solutions and primal informations
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 
25 #include "scip/def.h"
26 #include "scip/set.h"
27 #include "scip/stat.h"
28 #include "scip/visual.h"
29 #include "scip/event.h"
30 #include "scip/lp.h"
31 #include "scip/var.h"
32 #include "scip/prob.h"
33 #include "scip/sol.h"
34 #include "scip/primal.h"
35 #include "scip/tree.h"
36 #include "scip/reopt.h"
37 #include "scip/disp.h"
38 #include "scip/pub_message.h"
39 #include "scip/pub_var.h"
40 
41 
42 /*
43  * memory growing methods for dynamically allocated arrays
44  */
45 
46 /** ensures, that sols array can store at least num entries */
47 static
49  SCIP_PRIMAL* primal, /**< primal data */
50  SCIP_SET* set, /**< global SCIP settings */
51  int num /**< minimum number of entries to store */
52  )
53 {
54  assert(primal->nsols <= primal->solssize);
55 
56  if( num > primal->solssize )
57  {
58  int newsize;
59 
60  newsize = SCIPsetCalcMemGrowSize(set, num);
61  SCIP_ALLOC( BMSreallocMemoryArray(&primal->sols, newsize) );
62  primal->solssize = newsize;
63  }
64  assert(num <= primal->solssize);
65 
66  return SCIP_OKAY;
67 }
68 
69 /** ensures, that partialsols array can store at least num entries */
70 static
72  SCIP_PRIMAL* primal, /**< primal data */
73  SCIP_SET* set, /**< global SCIP settings */
74  int num /**< minimum number of entries to store */
75  )
76 {
77  assert(primal->npartialsols <= primal->partialsolssize);
78 
79  if( num > primal->partialsolssize )
80  {
81  int newsize;
82 
83  newsize = SCIPsetCalcMemGrowSize(set, num);
84  newsize = MIN(newsize, set->limit_maxorigsol);
85 
86  SCIP_ALLOC( BMSreallocMemoryArray(&primal->partialsols, newsize) );
87  primal->partialsolssize = newsize;
88  }
89  assert(num <= primal->partialsolssize);
90 
91  return SCIP_OKAY;
92 }
93 
94 /** ensures, that existingsols array can store at least num entries */
95 static
97  SCIP_PRIMAL* primal, /**< primal data */
98  SCIP_SET* set, /**< global SCIP settings */
99  int num /**< minimum number of entries to store */
100  )
101 {
102  assert(primal->nexistingsols <= primal->existingsolssize);
103 
104  if( num > primal->existingsolssize )
105  {
106  int newsize;
107 
108  newsize = SCIPsetCalcMemGrowSize(set, num);
109  SCIP_ALLOC( BMSreallocMemoryArray(&primal->existingsols, newsize) );
110  primal->existingsolssize = newsize;
111  }
112  assert(num <= primal->existingsolssize);
113 
114  return SCIP_OKAY;
115 }
116 
117 /** creates primal data */
119  SCIP_PRIMAL** primal /**< pointer to primal data */
120  )
121 {
122  assert(primal != NULL);
123 
124  SCIP_ALLOC( BMSallocMemory(primal) );
125  (*primal)->sols = NULL;
126  (*primal)->partialsols = NULL;
127  (*primal)->existingsols = NULL;
128  (*primal)->currentsol = NULL;
129  (*primal)->primalray = NULL;
130  (*primal)->solssize = 0;
131  (*primal)->partialsolssize = 0;
132  (*primal)->nsols = 0;
133  (*primal)->npartialsols = 0;
134  (*primal)->existingsolssize = 0;
135  (*primal)->nexistingsols = 0;
136  (*primal)->nsolsfound = 0;
137  (*primal)->nlimsolsfound = 0;
138  (*primal)->nbestsolsfound = 0;
139  (*primal)->nlimbestsolsfound = 0;
140  (*primal)->upperbound = SCIP_INVALID;
141  (*primal)->cutoffbound = SCIP_INVALID;
142  (*primal)->updateviolations = TRUE;
143 
144  return SCIP_OKAY;
145 }
146 
147 /** frees primal data */
149  SCIP_PRIMAL** primal, /**< pointer to primal data */
150  BMS_BLKMEM* blkmem /**< block memory */
151  )
152 {
153  int s;
154 
155  assert(primal != NULL);
156  assert(*primal != NULL);
157 
158  /* free temporary solution for storing current solution */
159  if( (*primal)->currentsol != NULL )
160  {
161  SCIP_CALL( SCIPsolFree(&(*primal)->currentsol, blkmem, *primal) );
162  }
163 
164  /* free solution for storing primal ray */
165  if( (*primal)->primalray != NULL )
166  {
167  SCIP_CALL( SCIPsolFree(&(*primal)->primalray, blkmem, *primal) );
168  }
169 
170  /* free feasible primal CIP solutions */
171  for( s = 0; s < (*primal)->nsols; ++s )
172  {
173  SCIP_CALL( SCIPsolFree(&(*primal)->sols[s], blkmem, *primal) );
174  }
175  /* free partial CIP solutions */
176  for( s = 0; s < (*primal)->npartialsols; ++s )
177  {
178  SCIP_CALL( SCIPsolFree(&(*primal)->partialsols[s], blkmem, *primal) );
179  }
180  assert((*primal)->nexistingsols == 0);
181 
182  BMSfreeMemoryArrayNull(&(*primal)->sols);
183  BMSfreeMemoryArrayNull(&(*primal)->partialsols);
184  BMSfreeMemoryArrayNull(&(*primal)->existingsols);
185  BMSfreeMemory(primal);
186 
187  return SCIP_OKAY;
188 }
189 
190 /** clears primal data */
192  SCIP_PRIMAL** primal, /**< pointer to primal data */
193  BMS_BLKMEM* blkmem /**< block memory */
194  )
195 {
196  int s;
197 
198  assert(primal != NULL);
199  assert(*primal != NULL);
200 
201  /* free temporary solution for storing current solution */
202  if( (*primal)->currentsol != NULL )
203  {
204  SCIP_CALL( SCIPsolFree(&(*primal)->currentsol, blkmem, *primal) );
205  }
206 
207  /* free solution for storing primal ray */
208  if( (*primal)->primalray != NULL )
209  {
210  SCIP_CALL( SCIPsolFree(&(*primal)->primalray, blkmem, *primal) );
211  }
212 
213  /* free feasible primal CIP solutions */
214  for( s = 0; s < (*primal)->nsols; ++s )
215  {
216  SCIP_CALL( SCIPsolFree(&(*primal)->sols[s], blkmem, *primal) );
217  }
218 
219  (*primal)->currentsol = NULL;
220  (*primal)->primalray = NULL;
221  (*primal)->nsols = 0;
222  (*primal)->nsolsfound = 0;
223  (*primal)->nlimsolsfound = 0;
224  (*primal)->nbestsolsfound = 0;
225  (*primal)->nlimbestsolsfound = 0;
226  (*primal)->upperbound = SCIP_INVALID;
227  (*primal)->cutoffbound = SCIP_INVALID;
228  (*primal)->updateviolations = TRUE;
229 
230  return SCIP_OKAY;
231 }
232 
233 /** sets the cutoff bound in primal data and in LP solver */
234 static
236  SCIP_PRIMAL* primal, /**< primal data */
237  BMS_BLKMEM* blkmem, /**< block memory */
238  SCIP_SET* set, /**< global SCIP settings */
239  SCIP_STAT* stat, /**< problem statistics data */
240  SCIP_PROB* prob, /**< problem data */
241  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
242  SCIP_TREE* tree, /**< branch and bound tree */
243  SCIP_REOPT* reopt, /**< reoptimization data structure */
244  SCIP_LP* lp, /**< current LP data */
245  SCIP_Real cutoffbound /**< new cutoff bound */
246  )
247 {
248  assert(primal != NULL);
249  assert(cutoffbound <= SCIPsetInfinity(set));
250  assert(primal->upperbound == SCIP_INVALID || SCIPsetIsLE(set, cutoffbound, primal->upperbound)); /*lint !e777*/
251  assert(!SCIPtreeInRepropagation(tree));
252 
253  SCIPsetDebugMsg(set, "changing cutoff bound from %g to %g\n", primal->cutoffbound, cutoffbound);
254 
255  primal->cutoffbound = MIN(cutoffbound, primal->upperbound); /* get rid of numerical issues */
256 
257  /* set cut off value in LP solver */
258  SCIP_CALL( SCIPlpSetCutoffbound(lp, set, prob, primal->cutoffbound) );
259 
260  /* cut off leaves of the tree */
261  SCIP_CALL( SCIPtreeCutoff(tree, reopt, blkmem, set, stat, eventqueue, lp, primal->cutoffbound) );
262 
263  return SCIP_OKAY;
264 }
265 
266 /** sets the cutoff bound in primal data and in LP solver */
268  SCIP_PRIMAL* primal, /**< primal data */
269  BMS_BLKMEM* blkmem, /**< block memory */
270  SCIP_SET* set, /**< global SCIP settings */
271  SCIP_STAT* stat, /**< problem statistics data */
272  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
273  SCIP_PROB* transprob, /**< transformed problem data */
274  SCIP_PROB* origprob, /**< original problem data */
275  SCIP_TREE* tree, /**< branch and bound tree */
276  SCIP_REOPT* reopt, /**< reoptimization data structure */
277  SCIP_LP* lp, /**< current LP data */
278  SCIP_Real cutoffbound, /**< new cutoff bound */
279  SCIP_Bool useforobjlimit /**< should the cutoff bound be used to update the objective limit, if
280  * better? */
281  )
282 {
283  assert(primal != NULL);
284  assert(cutoffbound <= SCIPsetInfinity(set));
285  assert(cutoffbound <= primal->upperbound);
286  assert(transprob != NULL);
287  assert(origprob != NULL);
288 
289  if( cutoffbound < primal->cutoffbound )
290  {
291  if( useforobjlimit )
292  {
293  SCIP_Real objval;
294 
295  objval = SCIPprobExternObjval(transprob, origprob, set, cutoffbound);
296 
297  if( objval < SCIPprobGetObjlim(origprob, set) )
298  {
299  SCIPsetDebugMsg(set, "changing cutoff bound from %g to %g changes objective limit from %g to %g\n",
300  primal->cutoffbound, cutoffbound, SCIPprobGetObjlim(origprob, set), objval);
301  SCIPprobSetObjlim(origprob, objval);
302  SCIPprobSetObjlim(transprob, objval);
303  }
304  }
305 
306  /* update cutoff bound */
307  SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventqueue, tree, reopt, lp, cutoffbound) );
308  }
309  else if( cutoffbound > primal->cutoffbound )
310  {
311  SCIPerrorMessage("invalid increase in cutoff bound\n");
312  return SCIP_INVALIDDATA;
313  }
314 
315  return SCIP_OKAY;
316 }
317 
318 /** sets upper bound in primal data and in LP solver */
319 static
321  SCIP_PRIMAL* primal, /**< primal data */
322  BMS_BLKMEM* blkmem, /**< block memory */
323  SCIP_SET* set, /**< global SCIP settings */
324  SCIP_STAT* stat, /**< problem statistics data */
325  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
326  SCIP_PROB* prob, /**< transformed problem after presolve */
327  SCIP_TREE* tree, /**< branch and bound tree */
328  SCIP_REOPT* reopt, /**< reoptimization data structure */
329  SCIP_LP* lp, /**< current LP data */
330  SCIP_Real upperbound /**< new upper bound */
331  )
332 {
333  SCIP_Real cutoffbound;
334 
335  assert(primal != NULL);
336  assert(stat != NULL);
337  assert(upperbound <= SCIPsetInfinity(set));
338  assert(upperbound <= primal->upperbound || stat->nnodes == 0);
339 
340  SCIPsetDebugMsg(set, "changing upper bound from %g to %g\n", primal->upperbound, upperbound);
341 
342  primal->upperbound = upperbound;
343 
344  /* if objective value is always integral, the cutoff bound can be reduced to nearly the previous integer number */
345  if( SCIPprobIsObjIntegral(prob) && !SCIPsetIsInfinity(set, upperbound) )
346  {
347  SCIP_Real delta;
348 
349  delta = SCIPsetCutoffbounddelta(set);
350 
351  cutoffbound = SCIPsetFeasCeil(set, upperbound) - (1.0 - delta);
352  cutoffbound = MIN(cutoffbound, upperbound); /* SCIPsetFeasCeil() can increase bound by almost 1.0 due to numerics
353  * and very large upperbound value */
354  }
355  else
356  cutoffbound = upperbound;
357 
358  /* update cutoff bound */
359  if( cutoffbound < primal->cutoffbound )
360  {
361  SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, prob, eventqueue, tree, reopt, lp, cutoffbound) );
362  }
363 
364  /* update upper bound in visualization output */
365  if( SCIPtreeGetCurrentDepth(tree) >= 0 )
366  {
367  SCIPvisualUpperbound(stat->visual, set, stat, primal->upperbound);
368  }
369 
370  return SCIP_OKAY;
371 }
372 
373 /** sets upper bound in primal data and in LP solver */
375  SCIP_PRIMAL* primal, /**< primal data */
376  BMS_BLKMEM* blkmem, /**< block memory */
377  SCIP_SET* set, /**< global SCIP settings */
378  SCIP_STAT* stat, /**< problem statistics data */
379  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
380  SCIP_PROB* prob, /**< transformed problem after presolve */
381  SCIP_TREE* tree, /**< branch and bound tree */
382  SCIP_REOPT* reopt, /**< reoptimization data structure */
383  SCIP_LP* lp, /**< current LP data */
384  SCIP_Real upperbound /**< new upper bound */
385  )
386 {
387  assert(primal != NULL);
388  assert(upperbound <= SCIPsetInfinity(set));
389 
390  if( upperbound < primal->upperbound )
391  {
392  /* update primal bound */
393  SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventqueue, prob, tree, reopt, lp, upperbound) );
394  }
395  else if( upperbound > primal->upperbound )
396  {
397  SCIPerrorMessage("invalid increase in upper bound\n");
398  return SCIP_INVALIDDATA;
399  }
400 
401  return SCIP_OKAY;
402 }
403 
404 /** updates upper bound and cutoff bound in primal data after a tightening of the problem's objective limit */
406  SCIP_PRIMAL* primal, /**< primal data */
407  BMS_BLKMEM* blkmem, /**< block memory */
408  SCIP_SET* set, /**< global SCIP settings */
409  SCIP_STAT* stat, /**< problem statistics data */
410  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
411  SCIP_PROB* transprob, /**< transformed problem data */
412  SCIP_PROB* origprob, /**< original problem data */
413  SCIP_TREE* tree, /**< branch and bound tree */
414  SCIP_REOPT* reopt, /**< reoptimization data structure */
415  SCIP_LP* lp /**< current LP data */
416  )
417 {
418  SCIP_Real objlimit;
419  SCIP_Real inf;
420 
421  assert(primal != NULL);
422 
423  /* get internal objective limit */
424  objlimit = SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set));
425  inf = SCIPsetInfinity(set);
426  objlimit = MIN(objlimit, inf);
427 
428  /* update the cutoff bound */
429  if( objlimit < primal->cutoffbound )
430  {
431  SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventqueue, tree, reopt, lp, objlimit) );
432  }
433 
434  /* set new upper bound (and decrease cutoff bound, if objective value is always integral) */
435  if( objlimit < primal->upperbound )
436  {
437  SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, objlimit) );
438  }
439 
440  return SCIP_OKAY;
441 }
442 
443 /** recalculates upper bound and cutoff bound in primal data after a change of the problem's objective offset */
445  SCIP_PRIMAL* primal, /**< primal data */
446  BMS_BLKMEM* blkmem, /**< block memory */
447  SCIP_SET* set, /**< global SCIP settings */
448  SCIP_STAT* stat, /**< problem statistics data */
449  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
450  SCIP_PROB* transprob, /**< tranformed problem data */
451  SCIP_PROB* origprob, /**< original problem data */
452  SCIP_TREE* tree, /**< branch and bound tree */
453  SCIP_REOPT* reopt, /**< reoptimization data structure */
454  SCIP_LP* lp /**< current LP data */
455  )
456 {
457  SCIP_SOL* sol;
458  SCIP_Real upperbound;
459  SCIP_Real objval;
460  SCIP_Real inf;
461  int i;
462  int j;
463 
464  assert(primal != NULL);
465  assert(SCIPsetGetStage(set) <= SCIP_STAGE_PRESOLVED);
466 
467  /* recalculate internal objective limit */
468  upperbound = SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set));
469  inf = SCIPsetInfinity(set);
470  upperbound = MIN(upperbound, inf);
471 
472  /* resort current primal solutions */
473  for( i = 1; i < primal->nsols; ++i )
474  {
475  sol = primal->sols[i];
476  objval = SCIPsolGetObj(sol, set, transprob, origprob);
477  for( j = i; j > 0 && objval < SCIPsolGetObj(primal->sols[j-1], set, transprob, origprob); --j )
478  primal->sols[j] = primal->sols[j-1];
479  primal->sols[j] = sol;
480  }
481 
482  /* compare objective limit to currently best solution */
483  if( primal->nsols > 0 )
484  {
485  SCIP_Real obj;
486 
487  assert(SCIPsolIsOriginal(primal->sols[0]));
488  obj = SCIPsolGetObj(primal->sols[0], set, transprob, origprob);
489 
490  upperbound = MIN(upperbound, obj);
491  }
492 
493  /* invalidate old upper bound */
494  SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, SCIPsetInfinity(set)) );
495 
496  /* reset the cutoff bound
497  *
498  * @note we might need to relax the bound since in presolving the objective correction of an
499  * aggregation is still in progress
500  */
501  SCIP_CALL( primalSetCutoffbound(primal, blkmem, set, stat, transprob, eventqueue, tree, reopt, lp, upperbound) );
502 
503  /* set new upper bound (and decrease cutoff bound, if objective value is always integral) */
504  SCIP_CALL( primalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, upperbound) );
505 
506  return SCIP_OKAY;
507 }
508 
509 /** adds additional objective offset in original space to all existing solution (in original space) */
511  SCIP_PRIMAL* primal, /**< primal data */
512  SCIP_SET* set, /**< global SCIP settings */
513  SCIP_Real addval /**< additional objective offset in original space */
514  )
515 {
516  int i;
517 
518  assert(primal != NULL);
519  assert(set != NULL);
520  assert(SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM);
521 
522 #ifndef NDEBUG
523  assert(primal->nsols == 0 || SCIPsolGetOrigin(primal->sols[0]) == SCIP_SOLORIGIN_ORIGINAL);
524 
525  /* check current order of primal solutions */
526  for( i = 1; i < primal->nsols; ++i )
527  {
528  assert(SCIPsolGetOrigin(primal->sols[i]) == SCIP_SOLORIGIN_ORIGINAL);
529  assert(SCIPsetIsLE(set, SCIPsolGetOrigObj(primal->sols[i-1]), SCIPsolGetOrigObj(primal->sols[i])));
530  }
531 #endif
532 
533  /* check current order of primal solutions */
534  for( i = 0; i < primal->nexistingsols; ++i )
535  {
536  assert(primal->existingsols[i] != NULL);
537  SCIPsolOrigAddObjval(primal->existingsols[i], addval);
538  }
539 }
540 
541 /** returns whether the current primal bound is justified with a feasible primal solution; if not, the primal bound
542  * was set from the user as objective limit
543  */
545  SCIP_PRIMAL* primal, /**< primal data */
546  SCIP_SET* set, /**< global SCIP settings */
547  SCIP_PROB* transprob, /**< tranformed problem data */
548  SCIP_PROB* origprob /**< original problem data */
549  )
550 {
551  assert(primal != NULL);
552 
553  return (primal->nsols > 0 && SCIPsetIsEQ(set, primal->upperbound, SCIPsolGetObj(primal->sols[0], set, transprob, origprob)));
554 }
555 
556 /** returns the primal ray thats proves unboundedness */
558  SCIP_PRIMAL* primal /**< primal data */
559  )
560 {
561  assert(primal != NULL);
562 
563  return primal->primalray;
564 }
565 
566 /** update the primal ray thats proves unboundedness */
568  SCIP_PRIMAL* primal, /**< primal data */
569  SCIP_SET* set, /**< global SCIP settings */
570  SCIP_STAT* stat, /**< dynamic SCIP statistics */
571  SCIP_SOL* primalray, /**< the new primal ray */
572  BMS_BLKMEM* blkmem /**< block memory */
573  )
574 {
575  assert(primal != NULL);
576  assert(set != NULL);
577  assert(stat != NULL);
578  assert(primalray != NULL);
579  assert(blkmem != NULL);
580 
581  /* clear previously stored primal ray, if any */
582  if( primal->primalray != NULL )
583  {
584  SCIP_CALL( SCIPsolFree(&primal->primalray, blkmem, primal) );
585  }
586 
587  assert(primal->primalray == NULL);
588 
589  SCIP_CALL( SCIPsolCopy(&primal->primalray, blkmem, set, stat, primal, primalray) );
590 
591  return SCIP_OKAY;
592 }
593 
594 /** adds primal solution to solution storage at given position */
595 static
597  SCIP_PRIMAL* primal, /**< primal data */
598  BMS_BLKMEM* blkmem, /**< block memory */
599  SCIP_SET* set, /**< global SCIP settings */
600  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
601  SCIP_STAT* stat, /**< problem statistics data */
602  SCIP_PROB* origprob, /**< original problem */
603  SCIP_PROB* transprob, /**< transformed problem after presolve */
604  SCIP_TREE* tree, /**< branch and bound tree */
605  SCIP_REOPT* reopt, /**< reoptimization data structure */
606  SCIP_LP* lp, /**< current LP data */
607  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
608  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
609  SCIP_SOL** solptr, /**< pointer to primal CIP solution */
610  int insertpos, /**< position in solution storage to add solution to */
611  SCIP_Bool replace /**< should the solution at insertpos be replaced by the new solution? */
612  )
613 {
614  SCIP_SOL* sol;
615  /* cppcheck-suppress unassignedVariable */
616  SCIP_EVENT event;
617  SCIP_Real obj;
618  int pos;
619 
620  assert(primal != NULL);
621  assert(set != NULL);
622  assert(solptr != NULL);
623  assert(stat != NULL);
624  assert(transprob != NULL);
625  assert(origprob != NULL);
626  assert(0 <= insertpos && insertpos < set->limit_maxsol);
627  assert(tree == NULL || !SCIPtreeInRepropagation(tree));
628 
629  sol = *solptr;
630  assert(sol != NULL);
631  obj = SCIPsolGetObj(sol, set, transprob, origprob);
632 
633  SCIPsetDebugMsg(set, "insert primal solution %p with obj %g at position %d (replace=%u):\n",
634  (void*)sol, obj, insertpos, replace);
635 
636  SCIPdebug( SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, transprob, NULL, NULL, FALSE, FALSE) ) );
637 
638 #if 0 /* this is not a valid debug check, but can be used to track down numerical troubles */
639 #ifndef NDEBUG
640  /* check solution again completely
641  * it fail for different reasons:
642  * - in the LP solver, the feasibility tolerance is a relative measure against the row's norm
643  * - in SCIP, the feasibility tolerance is a relative measure against the row's rhs/lhs
644  * - the rhs/lhs of a row might drastically change during presolving when variables are fixed or (multi-)aggregated
645  */
646  if( !SCIPsolIsOriginal(sol) )
647  {
648  SCIP_Bool feasible;
649 
650  SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, TRUE, TRUE, TRUE, TRUE, &feasible) );
651 
652  if( !feasible )
653  {
654  SCIPerrorMessage("infeasible solution accepted:\n");
655  SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, origprob, transprob, NULL, FALSE, FALSE) );
656  }
657  assert(feasible);
658  }
659 #endif
660 #endif
661 
662  /* completely fill the solution's own value array to unlink it from the LP or pseudo solution */
663  SCIP_CALL( SCIPsolUnlink(sol, set, transprob) );
664 
665  /* allocate memory for solution storage */
666  SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxsol) );
667 
668  /* if set->limit_maxsol was decreased in the meantime, free all solutions exceeding the limit */
669  for( pos = set->limit_maxsol; pos < primal->nsols; ++pos )
670  {
671  SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
672  }
673  primal->nsols = MIN(primal->nsols, set->limit_maxsol);
674 
675  /* if the solution should replace an existing one, free this solution, otherwise,
676  * free the last solution if the solution storage is full;
677  */
678  if( replace )
679  {
680  SCIP_CALL( SCIPsolTransform(primal->sols[insertpos], solptr, blkmem, set, primal) );
681  sol = primal->sols[insertpos];
682  }
683  else
684  {
685  if( primal->nsols == set->limit_maxsol )
686  {
687  SCIP_CALL( SCIPsolFree(&primal->sols[set->limit_maxsol - 1], blkmem, primal) );
688  }
689  else
690  {
691  primal->nsols = primal->nsols + 1;
692  assert(primal->nsols <= set->limit_maxsol);
693  }
694 
695  /* move all solutions with worse objective value than the new solution */
696  for( pos = primal->nsols-1; pos > insertpos; --pos )
697  primal->sols[pos] = primal->sols[pos-1];
698 
699  /* insert solution at correct position */
700  assert(0 <= insertpos && insertpos < primal->nsols);
701  primal->sols[insertpos] = sol;
702  primal->nsolsfound++;
703 
704  /* check if solution is better than objective limit */
705  if( SCIPsetIsFeasLE(set, obj, SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set))) )
706  primal->nlimsolsfound++;
707  }
708 
709  /* if its the first primal solution, store the relevant statistics */
710  if( primal->nsolsfound == 1 )
711  {
712  SCIP_Real primalsolval;
713 
715  stat->nrunsbeforefirst = SCIPsolGetRunnum(sol);
716  stat->firstprimalheur = SCIPsolGetHeur(sol);
717  stat->firstprimaltime = SCIPsolGetTime(sol);
718  stat->firstprimaldepth = SCIPsolGetDepth(sol);
719 
720  primalsolval = obj;
721  stat->firstprimalbound = SCIPprobExternObjval(transprob, origprob, set, primalsolval);
722 
723  SCIPsetDebugMsg(set, "First Solution stored in problem specific statistics.\n");
724  SCIPsetDebugMsg(set, "-> %" SCIP_LONGINT_FORMAT " nodes, %d runs, %.2g time, %d depth, %.15g objective\n", stat->nnodesbeforefirst, stat->nrunsbeforefirst,
726  }
727 
728  SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
729  insertpos, primal->nsols, primal->nsolsfound);
730 
731  /* update the solution value sums in variables */
732  if( !SCIPsolIsOriginal(sol) )
733  {
734  SCIPsolUpdateVarsum(sol, set, stat, transprob,
735  (SCIP_Real)(primal->nsols - insertpos)/(SCIP_Real)(2.0*primal->nsols - 1.0));
736  }
737 
738  /* change color of node in visualization output */
739  SCIPvisualFoundSolution(stat->visual, set, stat, SCIPtreeGetCurrentNode(tree), insertpos == 0 ? TRUE : FALSE, sol);
740 
741  /* check, if the global upper bound has to be updated */
742  if( obj < primal->cutoffbound && insertpos == 0 )
743  {
744  /* update the upper bound */
745  SCIP_CALL( SCIPprimalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, obj) );
746 
747  /* issue BESTSOLFOUND event */
749  primal->nbestsolsfound++;
750  stat->bestsolnode = stat->nnodes;
751  }
752  else
753  {
754  /* issue POORSOLFOUND event */
756  }
757  SCIP_CALL( SCIPeventChgSol(&event, sol) );
758  SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
759 
760  /* display node information line */
761  if( insertpos == 0 && !replace && set->stage >= SCIP_STAGE_SOLVING )
762  {
763  SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, TRUE, TRUE) );
764  }
765 
766  /* if an original solution was added during solving, try to transfer it to the transformed space */
767  if( SCIPsolIsOriginal(sol) && SCIPsetGetStage(set) == SCIP_STAGE_SOLVING && set->misc_transorigsols )
768  {
769  SCIP_Bool added;
770 
771  SCIP_CALL( SCIPprimalTransformSol(primal, sol, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt,
772  lp, eventqueue, eventfilter, NULL, NULL, 0, &added) );
773 
774  SCIPsetDebugMsg(set, "original solution %p was successfully transferred to the transformed problem space\n",
775  (void*)sol);
776  }
777 
778  return SCIP_OKAY;
779 }
780 
781 /** adds primal solution to solution storage at given position */
782 static
784  SCIP_PRIMAL* primal, /**< primal data */
785  BMS_BLKMEM* blkmem, /**< block memory */
786  SCIP_SET* set, /**< global SCIP settings */
787  SCIP_PROB* prob, /**< original problem data */
788  SCIP_SOL* sol, /**< primal CIP solution */
789  int insertpos /**< position in solution storage to add solution to */
790  )
791 {
792  int pos;
793 
794  assert(primal != NULL);
795  assert(set != NULL);
796  assert(prob != NULL);
797  assert(sol != NULL);
798  assert(0 <= insertpos && insertpos < set->limit_maxorigsol);
799  assert(!set->reopt_enable);
800 
801  SCIPsetDebugMsg(set, "insert primal solution candidate %p with obj %g at position %d:\n", (void*)sol, SCIPsolGetOrigObj(sol), insertpos);
802 
803  /* allocate memory for solution storage */
804  SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxorigsol) );
805 
806  /* if the solution storage is full, free the last solution(s)
807  * more than one solution may be freed, if set->limit_maxorigsol was decreased in the meantime
808  */
809  for( pos = set->limit_maxorigsol-1; pos < primal->nsols; ++pos )
810  {
811  SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
812  }
813 
814  /* insert solution at correct position */
815  primal->nsols = MIN(primal->nsols+1, set->limit_maxorigsol);
816  for( pos = primal->nsols-1; pos > insertpos; --pos )
817  primal->sols[pos] = primal->sols[pos-1];
818 
819  assert(0 <= insertpos && insertpos < primal->nsols);
820  primal->sols[insertpos] = sol;
821  primal->nsolsfound++;
822 
823  /* check if solution is better than objective limit */
824  if( SCIPsetIsFeasLE(set, SCIPsolGetOrigObj(sol), SCIPprobGetObjlim(prob, set)) )
825  primal->nlimsolsfound++;
826 
827  SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
828  insertpos, primal->nsols, primal->nsolsfound);
829 
830  return SCIP_OKAY;
831 }
832 
833 /** adds primal solution to solution storage */
834 static
836  SCIP_PRIMAL* primal, /**< primal data */
837  BMS_BLKMEM* blkmem, /**< block memory */
838  SCIP_SET* set, /**< global SCIP settings */
839  SCIP_PROB* prob, /**< original problem data */
840  SCIP_SOL* sol /**< primal CIP solution */
841  )
842 { /*lint --e{715}*/
843  assert(primal != NULL);
844  assert(set != NULL);
845  assert(prob != NULL);
846  assert(sol != NULL);
847 
848  if( primal->npartialsols >= set->limit_maxorigsol )
849  {
850  SCIPerrorMessage("Cannot add partial solution to storage: limit reached.\n");
851  return SCIP_INVALIDCALL;
852  }
853 
854  SCIPsetDebugMsg(set, "insert partial solution candidate %p:\n", (void*)sol);
855 
856  /* allocate memory for solution storage */
857  SCIP_CALL( ensurePartialsolsSize(primal, set, primal->npartialsols+1) );
858 
859  primal->partialsols[primal->npartialsols] = sol;
860  ++primal->npartialsols;
861 
862  return SCIP_OKAY;
863 }
864 
865 /** uses binary search to find position in solution storage */
866 static
868  SCIP_PRIMAL* primal, /**< primal data */
869  SCIP_SET* set, /**< global SCIP settings */
870  SCIP_PROB* transprob, /**< tranformed problem data */
871  SCIP_PROB* origprob, /**< original problem data */
872  SCIP_SOL* sol /**< primal solution to search position for */
873  )
874 {
875  SCIP_SOL** sols;
876  SCIP_Real obj;
877  SCIP_Real middleobj;
878  int left;
879  int right;
880  int middle;
881 
882  assert(primal != NULL);
883 
884  obj = SCIPsolGetObj(sol, set, transprob, origprob);
885  sols = primal->sols;
886 
887  left = -1;
888  right = primal->nsols;
889  while( left < right-1 )
890  {
891  middle = (left+right)/2;
892  assert(left < middle && middle < right);
893  assert(0 <= middle && middle < primal->nsols);
894 
895  middleobj = SCIPsolGetObj(sols[middle], set, transprob, origprob);
896 
897  if( obj < middleobj )
898  right = middle;
899  else
900  left = middle;
901  }
902  assert(left == right-1);
903 
904  /* prefer solutions that live in the transformed space */
905  if( !SCIPsolIsOriginal(sol) )
906  {
907  while( right > 0 && SCIPsolIsOriginal(sols[right-1])
908  && SCIPsetIsEQ(set, SCIPsolGetObj(sols[right-1], set, transprob, origprob), obj) )
909  --right;
910  }
911 
912  return right;
913 }
914 
915 /** uses binary search to find position in solution storage */
916 static
918  SCIP_PRIMAL* primal, /**< primal data */
919  SCIP_SOL* sol /**< primal solution to search position for */
920  )
921 {
922  SCIP_Real obj;
923  SCIP_Real middleobj;
924  int left;
925  int right;
926  int middle;
927 
928  assert(primal != NULL);
929 
930  obj = SCIPsolGetOrigObj(sol);
931 
932  left = -1;
933  right = primal->nsols;
934  while( left < right-1 )
935  {
936  middle = (left+right)/2;
937  assert(left < middle && middle < right);
938  assert(0 <= middle && middle < primal->nsols);
939  middleobj = SCIPsolGetOrigObj(primal->sols[middle]);
940  if( obj < middleobj )
941  right = middle;
942  else
943  left = middle;
944  }
945  assert(left == right-1);
946 
947  return right;
948 }
949 
950 /** returns whether the given primal solution is already existent in the solution storage */
951 static
953  SCIP_PRIMAL* primal, /**< primal data */
954  SCIP_SET* set, /**< global SCIP settings */
955  SCIP_STAT* stat, /**< problem statistics data */
956  SCIP_PROB* origprob, /**< original problem */
957  SCIP_PROB* transprob, /**< transformed problem after presolve */
958  SCIP_SOL* sol, /**< primal solution to search position for */
959  int* insertpos, /**< pointer to insertion position returned by primalSearchSolPos(); the
960  * position might be changed if an existing solution should be replaced */
961  SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced */
962  )
963 {
964  SCIP_Real obj;
965  int i;
966 
967  assert(primal != NULL);
968  assert(insertpos != NULL);
969  assert(replace != NULL);
970  assert(0 <= (*insertpos) && (*insertpos) <= primal->nsols);
971 
972  obj = SCIPsolGetObj(sol, set, transprob, origprob);
973 
974  assert(primal->sols != NULL || primal->nsols == 0);
975  assert(primal->sols != NULL || (*insertpos) == 0);
976 
977  /* search in the better solutions */
978  for( i = (*insertpos)-1; i >= 0; --i )
979  {
980  SCIP_Real solobj;
981 
982  solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
983 
984  /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
985  * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
986  */
987  assert(SCIPsetIsLE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasLE(set, solobj, obj)));
988 
989  if( SCIPsetIsLT(set, solobj, obj) )
990  break;
991 
992  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
993  {
994  if( SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
995  {
996  (*insertpos) = i;
997  (*replace) = TRUE;
998  }
999  return TRUE;
1000  }
1001  }
1002 
1003  /* search in the worse solutions */
1004  for( i = (*insertpos); i < primal->nsols; ++i )
1005  {
1006  SCIP_Real solobj;
1007 
1008  solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
1009 
1010  /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
1011  * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
1012  */
1013  assert( SCIPsetIsGE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasGE(set, solobj, obj)));
1014 
1015  if( SCIPsetIsGT(set, solobj, obj) )
1016  break;
1017 
1018  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
1019  {
1020  if( SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
1021  {
1022  (*insertpos) = i;
1023  (*replace) = TRUE;
1024  }
1025  return TRUE;
1026  }
1027  }
1028 
1029  return FALSE;
1030 }
1031 
1032 /** returns whether the given primal solution is already existent in the original solution candidate storage */
1033 static
1035  SCIP_PRIMAL* primal, /**< primal data */
1036  SCIP_SET* set, /**< global SCIP settings */
1037  SCIP_STAT* stat, /**< problem statistics data */
1038  SCIP_PROB* prob, /**< original problem */
1039  SCIP_SOL* sol, /**< primal solution to search position for */
1040  int insertpos /**< insertion position returned by primalSearchOrigSolPos() */
1041  )
1042 {
1043  SCIP_Real obj;
1044  int i;
1045 
1046  assert(primal != NULL);
1047  assert(0 <= insertpos && insertpos <= primal->nsols);
1048 
1049  obj = SCIPsolGetOrigObj(sol);
1050 
1051  /* search in the better solutions */
1052  for( i = insertpos-1; i >= 0; --i )
1053  {
1054  SCIP_Real solobj;
1055 
1056  solobj = SCIPsolGetOrigObj(primal->sols[i]);
1057  assert( SCIPsetIsLE(set, solobj, obj) );
1058 
1059  if( SCIPsetIsLT(set, solobj, obj) )
1060  break;
1061 
1062  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1063  return TRUE;
1064  }
1065 
1066  /* search in the worse solutions */
1067  for( i = insertpos; i < primal->nsols; ++i )
1068  {
1069  SCIP_Real solobj;
1070 
1071  solobj = SCIPsolGetOrigObj(primal->sols[i]);
1072  assert( SCIPsetIsGE(set, solobj, obj) );
1073 
1074  if( SCIPsetIsGT(set, solobj, obj) )
1075  break;
1076 
1077  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1078  return TRUE;
1079  }
1080 
1081  return FALSE;
1082 }
1083 
1084 /** check if we are willing to check the solution for feasibility */
1085 static
1087  SCIP_PRIMAL* primal, /**< primal data */
1088  SCIP_SET* set, /**< global SCIP settings */
1089  SCIP_STAT* stat, /**< problem statistics data */
1090  SCIP_PROB* origprob, /**< original problem */
1091  SCIP_PROB* transprob, /**< transformed problem after presolve */
1092  SCIP_SOL* sol, /**< primal CIP solution */
1093  int* insertpos, /**< pointer to store the insert position of that solution */
1094  SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced
1095  * (e.g., because it lives in the original space) */
1096  )
1097 {
1098  SCIP_Real obj;
1099 
1100  obj = SCIPsolGetObj(sol, set, transprob, origprob);
1101 
1102  /* check if we are willing to check worse solutions; a solution is better if the objective is smaller than the
1103  * current cutoff bound; solutions with infinite objective value are never accepted
1104  */
1105  if( (!set->misc_improvingsols || obj < primal->cutoffbound) && !SCIPsetIsInfinity(set, obj) )
1106  {
1107  /* find insert position for the solution */
1108  (*insertpos) = primalSearchSolPos(primal, set, transprob, origprob, sol);
1109  (*replace) = FALSE;
1110 
1111  /* the solution should be added, if the insertpos is smaller than the maximum number of solutions to be stored
1112  * and it does not already exist or it does exist, but the existing solution should be replaced by the new one
1113  */
1114  if( (*insertpos) < set->limit_maxsol &&
1115  (!primalExistsSol(primal, set, stat, origprob, transprob, sol, insertpos, replace) || (*replace)) )
1116  return TRUE;
1117  }
1118 
1119  return FALSE;
1120 }
1121 
1122 /** check if we are willing to store the solution candidate for later checking */
1123 static
1125  SCIP_PRIMAL* primal, /**< primal data */
1126  SCIP_SET* set, /**< global SCIP settings */
1127  SCIP_STAT* stat, /**< problem statistics data */
1128  SCIP_PROB* origprob, /**< original problem */
1129  SCIP_SOL* sol, /**< primal CIP solution */
1130  int* insertpos /**< pointer to store the insert position of that solution */
1131  )
1132 {
1133  assert(SCIPsolIsOriginal(sol));
1134 
1135  /* find insert position for the solution */
1136  (*insertpos) = primalSearchOrigSolPos(primal, sol);
1137 
1138  if( !set->reopt_enable && (*insertpos) < set->limit_maxorigsol && !primalExistsOrigSol(primal, set, stat, origprob, sol, *insertpos) )
1139  return TRUE;
1140 
1141  return FALSE;
1142 }
1143 
1144 /** adds primal solution to solution storage by copying it */
1146  SCIP_PRIMAL* primal, /**< primal data */
1147  BMS_BLKMEM* blkmem, /**< block memory */
1148  SCIP_SET* set, /**< global SCIP settings */
1149  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1150  SCIP_STAT* stat, /**< problem statistics data */
1151  SCIP_PROB* origprob, /**< original problem */
1152  SCIP_PROB* transprob, /**< transformed problem after presolve */
1153  SCIP_TREE* tree, /**< branch and bound tree */
1154  SCIP_REOPT* reopt, /**< reoptimization data structure */
1155  SCIP_LP* lp, /**< current LP data */
1156  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1157  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1158  SCIP_SOL* sol, /**< primal CIP solution */
1159  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1160  )
1161 {
1162  SCIP_Bool replace;
1163  int insertpos;
1164 
1165  assert(primal != NULL);
1166  assert(blkmem != NULL);
1167  assert(set != NULL);
1168  assert(messagehdlr != NULL);
1169  assert(stat != NULL);
1170  assert(origprob != NULL);
1171  assert(transprob != NULL);
1172  assert(tree != NULL);
1173  assert(lp != NULL);
1174  assert(eventqueue != NULL);
1175  assert(eventfilter != NULL);
1176  assert(sol != NULL);
1177  assert(stored != NULL);
1178 
1179  insertpos = -1;
1180 
1181  assert(!SCIPsolIsPartial(sol));
1182 
1183  if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1184  {
1185  SCIP_SOL* solcopy;
1186 #ifdef SCIP_MORE_DEBUG
1187  int i;
1188 #endif
1189 
1190  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1191 
1192  /* create a copy of the solution */
1193  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1194 
1195  /* insert copied solution into solution storage */
1196  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1197  tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1198 #ifdef SCIP_MORE_DEBUG
1199  for( i = 0; i < primal->nsols - 1; ++i )
1200  {
1201  assert(SCIPsetIsLE(set, SCIPsolGetObj(primal->sols[i], set, transprob, origprob), SCIPsolGetObj(primal->sols[i+1], set, transprob, origprob)));
1202  }
1203 #endif
1204  *stored = TRUE;
1205  }
1206  else
1207  *stored = FALSE;
1208 
1209  return SCIP_OKAY;
1210 }
1211 
1212 /** adds primal solution to solution storage, frees the solution afterwards */
1214  SCIP_PRIMAL* primal, /**< primal data */
1215  BMS_BLKMEM* blkmem, /**< block memory */
1216  SCIP_SET* set, /**< global SCIP settings */
1217  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1218  SCIP_STAT* stat, /**< problem statistics data */
1219  SCIP_PROB* origprob, /**< original problem */
1220  SCIP_PROB* transprob, /**< transformed problem after presolve */
1221  SCIP_TREE* tree, /**< branch and bound tree */
1222  SCIP_REOPT* reopt, /**< reoptimization data structure */
1223  SCIP_LP* lp, /**< current LP data */
1224  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1225  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1226  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1227  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1228  )
1229 {
1230  SCIP_Bool replace;
1231  int insertpos;
1232 
1233  assert(primal != NULL);
1234  assert(transprob != NULL);
1235  assert(origprob != NULL);
1236  assert(sol != NULL);
1237  assert(*sol != NULL);
1238  assert(stored != NULL);
1239 
1240  insertpos = -1;
1241 
1242  if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1243  {
1244  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1245 
1246  /* insert solution into solution storage */
1247  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1248  tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1249 
1250  /* clear the pointer, such that the user cannot access the solution anymore */
1251  *sol = NULL;
1252 
1253  *stored = TRUE;
1254  }
1255  else
1256  {
1257  /* the solution is too bad -> free it immediately */
1258  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1259 
1260  *stored = FALSE;
1261  }
1262  assert(*sol == NULL);
1263 
1264  return SCIP_OKAY;
1265 }
1266 
1267 /** adds primal solution to solution candidate storage of original problem space */
1269  SCIP_PRIMAL* primal, /**< primal data */
1270  BMS_BLKMEM* blkmem, /**< block memory */
1271  SCIP_SET* set, /**< global SCIP settings */
1272  SCIP_STAT* stat, /**< problem statistics data */
1273  SCIP_PROB* prob, /**< original problem data */
1274  SCIP_SOL* sol, /**< primal CIP solution; is cleared in function call */
1275  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1276  )
1277 {
1278  int insertpos;
1279 
1280  assert(primal != NULL);
1281  assert(blkmem != NULL);
1282  assert(set != NULL);
1283  assert(stat != NULL);
1284  assert(sol != NULL);
1285  assert(SCIPsolIsOriginal(sol));
1286  assert(stored != NULL);
1287 
1288  insertpos = -1;
1289 
1290  if( SCIPsolIsPartial(sol) )
1291  {
1292  SCIP_SOL* solcopy;
1293 
1294  /* create a copy of the solution */
1295  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1296 
1297  SCIP_CALL( primalAddOrigPartialSol(primal, blkmem, set, prob, solcopy) );
1298 
1299  *stored = TRUE;
1300  }
1301  else if( origsolOfInterest(primal, set, stat, prob, sol, &insertpos) )
1302  {
1303  SCIP_SOL* solcopy;
1304 
1305  assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1306  assert(!set->reopt_enable);
1307 
1308  /* create a copy of the solution */
1309  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1310 
1311  /* insert solution into solution storage */
1312  SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, solcopy, insertpos) );
1313 
1314  *stored = TRUE;
1315  }
1316  else
1317  *stored = FALSE;
1318 
1319  return SCIP_OKAY;
1320 }
1321 
1322 /** adds primal solution to solution candidate storage of original problem space, frees the solution afterwards */
1324  SCIP_PRIMAL* primal, /**< primal data */
1325  BMS_BLKMEM* blkmem, /**< block memory */
1326  SCIP_SET* set, /**< global SCIP settings */
1327  SCIP_STAT* stat, /**< problem statistics data */
1328  SCIP_PROB* prob, /**< original problem data */
1329  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1330  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1331  )
1332 {
1333  int insertpos;
1334 
1335  assert(primal != NULL);
1336  assert(sol != NULL);
1337  assert(*sol != NULL);
1338  assert(SCIPsolIsOriginal(*sol));
1339  assert(stored != NULL);
1340 
1341  insertpos = -1;
1342 
1343  if( SCIPsolIsPartial(*sol) )
1344  {
1345  /* insert solution into solution storage */
1346  SCIP_CALL( primalAddOrigPartialSol(primal, blkmem, set, prob, *sol) );
1347 
1348  /* clear the pointer, such that the user cannot access the solution anymore */
1349  *sol = NULL;
1350 
1351  *stored = TRUE;
1352  }
1353  else if( origsolOfInterest(primal, set, stat, prob, *sol, &insertpos) )
1354  {
1355  assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1356  assert(!set->reopt_enable);
1357 
1358  /* insert solution into solution storage */
1359  SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, *sol, insertpos) );
1360 
1361  /* clear the pointer, such that the user cannot access the solution anymore */
1362  *sol = NULL;
1363 
1364  *stored = TRUE;
1365  }
1366  else
1367  {
1368  /* the solution is too bad -> free it immediately */
1369  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1370 
1371  *stored = FALSE;
1372  }
1373  assert(*sol == NULL);
1374 
1375  return SCIP_OKAY;
1376 }
1377 
1378 /** links temporary solution of primal data to current solution */
1379 static
1381  SCIP_PRIMAL* primal, /**< primal data */
1382  BMS_BLKMEM* blkmem, /**< block memory */
1383  SCIP_SET* set, /**< global SCIP settings */
1384  SCIP_STAT* stat, /**< problem statistics data */
1385  SCIP_PROB* prob, /**< transformed problem data */
1386  SCIP_TREE* tree, /**< branch and bound tree */
1387  SCIP_LP* lp, /**< current LP data */
1388  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
1389  )
1390 {
1391  assert(primal != NULL);
1392 
1393  if( primal->currentsol == NULL )
1394  {
1395  SCIP_CALL( SCIPsolCreateCurrentSol(&primal->currentsol, blkmem, set, stat, prob, primal, tree, lp, heur) );
1396  }
1397  else
1398  {
1399  SCIP_CALL( SCIPsolLinkCurrentSol(primal->currentsol, set, stat, prob, tree, lp) );
1400  SCIPsolSetHeur(primal->currentsol, heur);
1401  }
1402 
1403  return SCIP_OKAY;
1404 }
1405 
1406 /** adds current LP/pseudo solution to solution storage */
1408  SCIP_PRIMAL* primal, /**< primal data */
1409  BMS_BLKMEM* blkmem, /**< block memory */
1410  SCIP_SET* set, /**< global SCIP settings */
1411  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1412  SCIP_STAT* stat, /**< problem statistics data */
1413  SCIP_PROB* origprob, /**< original problem */
1414  SCIP_PROB* transprob, /**< transformed problem after presolve */
1415  SCIP_TREE* tree, /**< branch and bound tree */
1416  SCIP_REOPT* reopt, /**< reoptimization data structure */
1417  SCIP_LP* lp, /**< current LP data */
1418  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1419  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1420  SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1421  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1422  )
1423 {
1424  assert(primal != NULL);
1425 
1426  /* link temporary solution to current solution */
1427  SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1428 
1429  /* add solution to solution storage */
1430  SCIP_CALL( SCIPprimalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1431  tree, reopt, lp, eventqueue, eventfilter, primal->currentsol, stored) );
1432 
1433  return SCIP_OKAY;
1434 }
1435 
1436 /** checks primal solution; if feasible, adds it to storage by copying it */
1438  SCIP_PRIMAL* primal, /**< primal data */
1439  BMS_BLKMEM* blkmem, /**< block memory */
1440  SCIP_SET* set, /**< global SCIP settings */
1441  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1442  SCIP_STAT* stat, /**< problem statistics data */
1443  SCIP_PROB* origprob, /**< original problem */
1444  SCIP_PROB* transprob, /**< transformed problem after presolve */
1445  SCIP_TREE* tree, /**< branch and bound tree */
1446  SCIP_REOPT* reopt, /**< reoptimization data structure */
1447  SCIP_LP* lp, /**< current LP data */
1448  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1449  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1450  SCIP_SOL* sol, /**< primal CIP solution */
1451  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1452  SCIP_Bool completely, /**< Should all violations be checked? */
1453  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1454  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1455  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1456  SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */
1457  )
1458 {
1459  SCIP_Bool feasible;
1460  SCIP_Bool replace;
1461  int insertpos;
1462 
1463  assert(primal != NULL);
1464  assert(set != NULL);
1465  assert(transprob != NULL);
1466  assert(origprob != NULL);
1467  assert(tree != NULL);
1468  assert(sol != NULL);
1469  assert(stored != NULL);
1470 
1471  /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1472  checklprows = checklprows || set->misc_exactsolve;
1473 
1474  insertpos = -1;
1475 
1476  if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1477  {
1478  /* check solution for feasibility */
1479  SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1480  checkintegrality, checklprows, &feasible) );
1481  }
1482  else
1483  feasible = FALSE;
1484 
1485  if( feasible )
1486  {
1487  SCIP_SOL* solcopy;
1488 
1489  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1490 
1491  /* create a copy of the solution */
1492  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1493 
1494  /* insert copied solution into solution storage */
1495  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1496  tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1497 
1498  *stored = TRUE;
1499  }
1500  else
1501  *stored = FALSE;
1502 
1503  return SCIP_OKAY;
1504 }
1505 
1506 /** checks primal solution; if feasible, adds it to storage; solution is freed afterwards */
1508  SCIP_PRIMAL* primal, /**< primal data */
1509  BMS_BLKMEM* blkmem, /**< block memory */
1510  SCIP_SET* set, /**< global SCIP settings */
1511  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1512  SCIP_STAT* stat, /**< problem statistics data */
1513  SCIP_PROB* origprob, /**< original problem */
1514  SCIP_PROB* transprob, /**< transformed problem after presolve */
1515  SCIP_TREE* tree, /**< branch and bound tree */
1516  SCIP_REOPT* reopt, /**< reoptimization data structure */
1517  SCIP_LP* lp, /**< current LP data */
1518  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1519  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1520  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1521  SCIP_Bool printreason, /**< Should all the reasons of violations be printed? */
1522  SCIP_Bool completely, /**< Should all violations be checked? */
1523  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1524  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1525  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1526  SCIP_Bool* stored /**< stores whether solution was feasible and good enough to keep */
1527  )
1528 {
1529  SCIP_Bool feasible;
1530  SCIP_Bool replace;
1531  int insertpos;
1532 
1533  assert(primal != NULL);
1534  assert(transprob != NULL);
1535  assert(origprob != NULL);
1536  assert(tree != NULL);
1537  assert(sol != NULL);
1538  assert(*sol != NULL);
1539  assert(stored != NULL);
1540 
1541  *stored = FALSE;
1542 
1543  /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1544  checklprows = checklprows || set->misc_exactsolve;
1545 
1546  insertpos = -1;
1547 
1548  if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1549  {
1550  /* check solution for feasibility */
1551  SCIP_CALL( SCIPsolCheck(*sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1552  checkintegrality, checklprows, &feasible) );
1553  }
1554  else
1555  feasible = FALSE;
1556 
1557  if( feasible )
1558  {
1559  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1560 
1561  /* insert solution into solution storage */
1562  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1563  tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1564 
1565  /* clear the pointer, such that the user cannot access the solution anymore */
1566  *sol = NULL;
1567  *stored = TRUE;
1568  }
1569  else
1570  {
1571  /* the solution is too bad or infeasible -> free it immediately */
1572  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1573  *stored = FALSE;
1574  }
1575  assert(*sol == NULL);
1576 
1577  return SCIP_OKAY;
1578 }
1579 
1580 /** checks current LP/pseudo solution; if feasible, adds it to storage */
1582  SCIP_PRIMAL* primal, /**< primal data */
1583  BMS_BLKMEM* blkmem, /**< block memory */
1584  SCIP_SET* set, /**< global SCIP settings */
1585  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1586  SCIP_STAT* stat, /**< problem statistics data */
1587  SCIP_PROB* origprob, /**< original problem */
1588  SCIP_PROB* transprob, /**< transformed problem after presolve */
1589  SCIP_TREE* tree, /**< branch and bound tree */
1590  SCIP_REOPT* reopt, /**< reoptimization data structure */
1591  SCIP_LP* lp, /**< current LP data */
1592  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1593  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1594  SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1595  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1596  SCIP_Bool completely, /**< Should all violations be checked? */
1597  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1598  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1599  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1600  )
1601 {
1602  assert(primal != NULL);
1603 
1604  /* link temporary solution to current solution */
1605  SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1606 
1607  /* add solution to solution storage */
1608  SCIP_CALL( SCIPprimalTrySol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1609  tree, reopt, lp, eventqueue, eventfilter, primal->currentsol,
1610  printreason, completely, FALSE, checkintegrality, checklprows, stored) );
1611 
1612  return SCIP_OKAY;
1613 }
1614 
1615 /** inserts solution into the global array of all existing primal solutions */
1617  SCIP_PRIMAL* primal, /**< primal data */
1618  SCIP_SET* set, /**< global SCIP settings */
1619  SCIP_SOL* sol /**< primal CIP solution */
1620  )
1621 {
1622  assert(primal != NULL);
1623  assert(sol != NULL);
1624  assert(SCIPsolGetPrimalIndex(sol) == -1);
1625 
1626  /* allocate memory for solution storage */
1627  SCIP_CALL( ensureExistingsolsSize(primal, set, primal->nexistingsols+1) );
1628 
1629  /* append solution */
1630  SCIPsolSetPrimalIndex(sol, primal->nexistingsols);
1631  primal->existingsols[primal->nexistingsols] = sol;
1632  primal->nexistingsols++;
1633 
1634  return SCIP_OKAY;
1635 }
1636 
1637 /** removes solution from the global array of all existing primal solutions */
1639  SCIP_PRIMAL* primal, /**< primal data */
1640  SCIP_SOL* sol /**< primal CIP solution */
1641  )
1642 {
1643  int idx;
1644 
1645  assert(primal != NULL);
1646  assert(sol != NULL);
1647 
1648 #ifndef NDEBUG
1649  for( idx = 0; idx < primal->nexistingsols; ++idx )
1650  {
1651  assert(idx == SCIPsolGetPrimalIndex(primal->existingsols[idx]));
1652  }
1653 #endif
1654 
1655  /* remove solution */
1656  idx = SCIPsolGetPrimalIndex(sol);
1657  assert(0 <= idx && idx < primal->nexistingsols);
1658  assert(sol == primal->existingsols[idx]);
1659  if( idx < primal->nexistingsols-1 )
1660  {
1661  primal->existingsols[idx] = primal->existingsols[primal->nexistingsols-1];
1662  SCIPsolSetPrimalIndex(primal->existingsols[idx], idx);
1663  }
1664  primal->nexistingsols--;
1665 }
1666 
1667 /** updates all existing primal solutions after a change in a variable's objective value */
1669  SCIP_PRIMAL* primal, /**< primal data */
1670  SCIP_VAR* var, /**< problem variable */
1671  SCIP_Real oldobj, /**< old objective value */
1672  SCIP_Real newobj /**< new objective value */
1673  )
1674 {
1675  int i;
1676 
1677  assert(primal != NULL);
1678 
1679  for( i = 0; i < primal->nexistingsols; ++i )
1680  {
1681  if( !SCIPsolIsOriginal(primal->existingsols[i]) )
1682  SCIPsolUpdateVarObj(primal->existingsols[i], var, oldobj, newobj);
1683  }
1684 }
1685 
1686 /** retransforms all existing solutions to original problem space
1687  *
1688  * @note as a side effect, the objective value of the solutions can change (numerical errors)
1689  * so we update the objective cutoff value and upper bound accordingly
1690  */
1692  SCIP_PRIMAL* primal, /**< primal data */
1693  BMS_BLKMEM* blkmem, /**< block memory */
1694  SCIP_SET* set, /**< global SCIP settings */
1695  SCIP_STAT* stat, /**< problem statistics data */
1696  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1697  SCIP_PROB* origprob, /**< original problem */
1698  SCIP_PROB* transprob, /**< transformed problem */
1699  SCIP_TREE* tree, /**< branch and bound tree */
1700  SCIP_REOPT* reopt, /**< reoptimization data structure */
1701  SCIP_LP* lp /**< current LP data */
1702  )
1703 {
1704  SCIP_Bool hasinfval;
1705  int i;
1706 
1707  assert(primal != NULL);
1708 
1709  for( i = 0; i < primal->nsols; ++i )
1710  {
1711  if( SCIPsolGetOrigin(primal->sols[i]) == SCIP_SOLORIGIN_ZERO )
1712  {
1713  SCIP_CALL( SCIPsolRetransform(primal->sols[i], set, stat, origprob, transprob, &hasinfval) );
1714  }
1715  }
1716 
1717  /* check if the global upper bound has to be updated
1718  * @todo we do not inform anybody about this change; if this leads to some
1719  * problem, a possible solution is to issue a BESTSOLFOUND event
1720  */
1721  if( primal->nsols > 0 )
1722  {
1723  SCIP_Real obj;
1724 
1725  obj = SCIPsolGetObj(primal->sols[0], set, transprob, origprob);
1726  if( obj < primal->cutoffbound )
1727  {
1728  /* update the upper bound */
1729  SCIP_CALL( SCIPprimalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, obj) );
1730  }
1731  }
1732 
1733  return SCIP_OKAY;
1734 }
1735 
1736 /** tries to transform original solution to the transformed problem space */
1738  SCIP_PRIMAL* primal, /**< primal data */
1739  SCIP_SOL* sol, /**< primal solution */
1740  BMS_BLKMEM* blkmem, /**< block memory */
1741  SCIP_SET* set, /**< global SCIP settings */
1742  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1743  SCIP_STAT* stat, /**< problem statistics data */
1744  SCIP_PROB* origprob, /**< original problem */
1745  SCIP_PROB* transprob, /**< transformed problem after presolve */
1746  SCIP_TREE* tree, /**< branch and bound tree */
1747  SCIP_REOPT* reopt, /**< reoptimization data structure */
1748  SCIP_LP* lp, /**< current LP data */
1749  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1750  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1751  SCIP_Real* solvals, /**< array for internal use to store solution values, or NULL;
1752  * if the method is called multiple times in a row, an array with size >=
1753  * number of active variables should be given for performance reasons */
1754  SCIP_Bool* solvalset, /**< array for internal use to store which solution values were set, or NULL;
1755  * if the method is called multiple times in a row, an array with size >=
1756  * number of active variables should be given for performance reasons */
1757  int solvalssize, /**< size of solvals and solvalset arrays, should be >= number of active
1758  * variables */
1759  SCIP_Bool* added /**< pointer to store whether the solution was added */
1760  )
1761 {
1762  SCIP_VAR** origvars;
1763  SCIP_VAR** transvars;
1764  SCIP_VAR* var;
1765  SCIP_Real* localsolvals;
1766  SCIP_Bool* localsolvalset;
1767  SCIP_Real solval;
1768  SCIP_Real scalar;
1769  SCIP_Real constant;
1770  SCIP_Bool localarrays;
1771  SCIP_Bool feasible;
1772  int norigvars;
1773  int ntransvars;
1774  int nvarsset;
1775  int v;
1776 
1777  assert(origprob != NULL);
1778  assert(transprob != NULL);
1779  assert(SCIPsolIsOriginal(sol));
1780  assert(solvalssize == 0 || solvals != NULL);
1781  assert(solvalssize == 0 || solvalset != NULL);
1782 
1783  origvars = origprob->vars;
1784  norigvars = origprob->nvars;
1785  transvars = transprob->vars;
1786  ntransvars = transprob->nvars;
1787  assert(solvalssize == 0 || solvalssize >= ntransvars);
1788 
1789  SCIPsetDebugMsg(set, "try to transfer original solution %p with objective %g into the transformed problem space\n",
1790  (void*)sol, SCIPsolGetOrigObj(sol));
1791 
1792  /* if no solvals and solvalset arrays are given, allocate local ones, otherwise use the given ones */
1793  localarrays = (solvalssize == 0);
1794  if( localarrays )
1795  {
1796  SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvals, ntransvars) );
1797  SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvalset, ntransvars) );
1798  }
1799  else
1800  {
1801  localsolvals = solvals;
1802  localsolvalset = solvalset;
1803  }
1804 
1805  BMSclearMemoryArray(localsolvalset, ntransvars);
1806  feasible = TRUE;
1807  (*added) = FALSE;
1808  nvarsset = 0;
1809 
1810  /* for each original variable, get the corresponding active, fixed or multi-aggregated variable;
1811  * if it resolves to an active variable, we set its solution value or check whether an already stored solution value
1812  * is consistent; if it resolves to a fixed variable, we check that the fixing matches the original solution value;
1813  * multi-aggregated variables are skipped, because their value is defined by setting solution values for the active
1814  * variables, anyway
1815  */
1816  for( v = 0; v < norigvars && feasible; ++v )
1817  {
1818  var = origvars[v];
1819 
1820  solval = SCIPsolGetVal(sol, set, stat, var);
1821 
1822  /* get corresponding active, fixed, or multi-aggregated variable */
1823  scalar = 1.0;
1824  constant = 0.0;
1825  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
1828 
1829  /* check whether the fixing corresponds to the solution value of the original variable */
1830  if( scalar == 0.0 )
1831  {
1832  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED ||
1833  (SCIPsetIsInfinity(set, constant) || SCIPsetIsInfinity(set, -constant)));
1834 
1835  if( !SCIPsetIsEQ(set, solval, constant) )
1836  {
1837  SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to fixed variable <%s> (original solval=%g)\n",
1838  SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), constant);
1839  feasible = FALSE;
1840  }
1841  }
1842  else if( SCIPvarIsActive(var) )
1843  {
1844  /* if we already assigned a solution value to the transformed variable, check that it corresponds to the
1845  * value obtained from the currently regarded original variable
1846  */
1847  if( localsolvalset[SCIPvarGetProbindex(var)] )
1848  {
1849  if( !SCIPsetIsEQ(set, solval, scalar * localsolvals[SCIPvarGetProbindex(var)] + constant) )
1850  {
1851  SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to active variable <%s> with assigned solval %g (original solval=%g)\n",
1852  SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), localsolvals[SCIPvarGetProbindex(var)],
1853  scalar * localsolvals[SCIPvarGetProbindex(var)] + constant);
1854  feasible = FALSE;
1855  }
1856  }
1857  /* assign solution value to the transformed variable */
1858  else
1859  {
1860  assert(scalar != 0.0);
1861 
1862  localsolvals[SCIPvarGetProbindex(var)] = (solval - constant) / scalar;
1863  localsolvalset[SCIPvarGetProbindex(var)] = TRUE;
1864  ++nvarsset;
1865  }
1866  }
1867 #ifndef NDEBUG
1868  /* we do not have to handle multi-aggregated variables here, since by assigning values to all active variabes,
1869  * we implicitly assign values to the multi-aggregated variables, too
1870  */
1871  else
1872  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
1873 #endif
1874  }
1875 
1876  /* if the solution values of fixed and active variables lead to no contradiction, construct solution and try it */
1877  if( feasible )
1878  {
1879  SCIP_SOL* transsol;
1880 
1881  SCIP_CALL( SCIPsolCreate(&transsol, blkmem, set, stat, primal, tree, SCIPsolGetHeur(sol)) );
1882 
1883  /* set solution values for variables to which we assigned a value */
1884  for( v = 0; v < ntransvars; ++v )
1885  {
1886  if( localsolvalset[v] )
1887  {
1888  SCIP_CALL( SCIPsolSetVal(transsol, set, stat, tree, transvars[v], localsolvals[v]) );
1889  }
1890  }
1891 
1892  SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1893  tree, reopt, lp, eventqueue, eventfilter, &transsol, FALSE, FALSE, TRUE, TRUE, TRUE, added) );
1894 
1895  SCIPsetDebugMsg(set, "solution transferred, %d/%d active variables set (stored=%u)\n", nvarsset, ntransvars, *added);
1896  }
1897  else
1898  (*added) = FALSE;
1899 
1900  /* free local arrays, if needed */
1901  if( localarrays )
1902  {
1903  SCIPsetFreeBufferArray(set, &localsolvalset);
1904  SCIPsetFreeBufferArray(set, &localsolvals);
1905  }
1906 
1907  return SCIP_OKAY;
1908 }
1909 
1910 
1911 /** is the updating of violations enabled for this problem? */
1913  SCIP_PRIMAL* primal /**< problem data */
1914  )
1915 {
1916  assert(primal != NULL);
1917 
1918  return primal->updateviolations;
1919 }
1920 
1921 /** set whether the updating of violations is turned on */
1923  SCIP_PRIMAL* primal, /**< problem data */
1924  SCIP_Bool updateviolations /**< marks whether the updating of violations is turned on */
1925  )
1926 {
1927  assert(primal != NULL);
1928 
1929  primal->updateviolations = updateviolations;
1930 }
SCIP_Real cutoffbound
Definition: struct_primal.h:46
static SCIP_RETCODE primalLinkCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
Definition: primal.c:1380
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:2470
SCIP_SOL * primalray
Definition: struct_primal.h:52
SCIP_RETCODE SCIPsolUnlink(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *prob)
Definition: sol.c:1000
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5953
SCIP_RETCODE SCIPprimalClear(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:191
#define NULL
Definition: def.h:239
internal methods for managing events
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6011
internal methods for storing primal CIP solutions
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1638
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
internal methods for branch and bound tree
static SCIP_RETCODE primalAddOrigSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_SOL *sol, int insertpos)
Definition: primal.c:783
static SCIP_RETCODE primalSetUpperbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real upperbound)
Definition: primal.c:320
SCIP_RETCODE SCIPdispPrintLine(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, FILE *file, SCIP_Bool forcedisplay, SCIP_Bool endline)
Definition: disp.c:405
int nrunsbeforefirst
Definition: struct_stat.h:254
int partialsolssize
Definition: struct_primal.h:55
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:1005
SCIP_RETCODE SCIPprimalTrySol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1437
SCIP_RETCODE SCIPprimalRetransformSolutions(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:1691
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5813
SCIP_RETCODE SCIPprimalAddOrigSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1268
SCIP_RETCODE SCIPsolLinkCurrentSol(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
Definition: sol.c:940
SCIP_SOL ** sols
Definition: struct_primal.h:48
SCIP_SOL * currentsol
Definition: struct_primal.h:51
#define FALSE
Definition: def.h:65
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1496
SCIP_RETCODE SCIPsolCopy(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_SOL *sourcesol)
Definition: sol.c:346
#define TRUE
Definition: def.h:64
#define SCIPdebug(x)
Definition: pub_message.h:74
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
static SCIP_RETCODE ensureSolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:48
void SCIPsolSetPrimalIndex(SCIP_SOL *sol, int primalindex)
Definition: sol.c:2573
SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2096
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1904
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8304
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17036
SCIP_Bool SCIPsolsAreEqual(SCIP_SOL *sol1, SCIP_SOL *sol2, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: sol.c:1982
SCIP_Real SCIPsetCutoffbounddelta(SCIP_SET *set)
Definition: set.c:5918
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5503
SCIP_Real SCIPsolGetTime(SCIP_SOL *sol)
Definition: sol.c:2513
public methods for problem variables
SCIP_Longint nsolsfound
Definition: struct_primal.h:39
methods for creating output for visualization tools (VBC, BAK)
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1911
#define BMSfreeMemory(ptr)
Definition: memory.h:127
SCIP_VISUAL * visual
Definition: struct_stat.h:168
internal methods for LP management
SCIP_SOL * SCIPprimalGetRay(SCIP_PRIMAL *primal)
Definition: primal.c:557
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2490
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:1299
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6047
SCIP_RETCODE SCIPprimalAddCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_HEUR *heur, SCIP_Bool *stored)
Definition: primal.c:1407
SCIP_RETCODE SCIPprimalUpdateObjlimit(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:405
SCIP_Real SCIPprobGetObjlim(SCIP_PROB *prob, SCIP_SET *set)
Definition: prob.c:2279
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5993
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1276
SCIP_Bool updateviolations
Definition: struct_primal.h:61
SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: sol.c:1498
void SCIPsolUpdateVarsum(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Real weight)
Definition: sol.c:1792
SCIP_RETCODE SCIPprimalTrySolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1507
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint nbestsolsfound
Definition: struct_primal.h:42
static int primalSearchOrigSolPos(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:917
SCIP_Longint bestsolnode
Definition: struct_stat.h:104
SCIP_Bool SCIPtreeInRepropagation(SCIP_TREE *tree)
Definition: tree.c:8277
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:659
SCIP_HEUR * firstprimalheur
Definition: struct_stat.h:169
SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
Definition: sol.c:1029
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16729
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6529
static SCIP_Bool primalExistsSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_SOL *sol, int *insertpos, SCIP_Bool *replace)
Definition: primal.c:952
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2553
#define REALABS(x)
Definition: def.h:174
static SCIP_RETCODE primalAddSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **solptr, int insertpos, SCIP_Bool replace)
Definition: primal.c:596
SCIP_Bool SCIPprimalUpdateViolations(SCIP_PRIMAL *primal)
Definition: primal.c:1912
SCIP_Bool SCIPprobIsObjIntegral(SCIP_PROB *prob)
Definition: prob.c:2255
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:351
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6439
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5975
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6395
SCIP_RETCODE SCIPsolTransform(SCIP_SOL *sol, SCIP_SOL **transsol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal)
Definition: sol.c:391
SCIP_RETCODE SCIPprimalSetCutoffbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound, SCIP_Bool useforobjlimit)
Definition: primal.c:267
data structures and methods for collecting reoptimization information
internal methods for problem variables
SCIP_RETCODE SCIPprimalSolCreated(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_SOL *sol)
Definition: primal.c:1616
#define SCIP_Bool
Definition: def.h:62
static SCIP_Bool origsolOfInterest(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_SOL *sol, int *insertpos)
Definition: primal.c:1124
void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: primal.c:1668
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2533
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:278
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:2594
SCIP_RETCODE SCIPsolRetransform(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_Bool *hasinfval)
Definition: sol.c:1820
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:2042
SCIP_SOL ** partialsols
Definition: struct_primal.h:49
#define MIN(x, y)
Definition: def.h:209
#define SCIPsetDebugMsg
Definition: set.h:1940
void SCIPsolOrigAddObjval(SCIP_SOL *sol, SCIP_Real addval)
Definition: sol.c:2501
static SCIP_RETCODE primalAddOrigPartialSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_SOL *sol)
Definition: primal.c:835
static SCIP_RETCODE primalSetCutoffbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound)
Definition: primal.c:235
void SCIPprobSetObjlim(SCIP_PROB *prob, SCIP_Real objlim)
Definition: prob.c:1449
SCIP_Longint nnodesbeforefirst
Definition: struct_stat.h:113
void SCIPprimalSetUpdateViolations(SCIP_PRIMAL *primal, SCIP_Bool updateviolations)
Definition: primal.c:1922
static SCIP_Bool solOfInterest(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_SOL *sol, int *insertpos, SCIP_Bool *replace)
Definition: primal.c:1086
SCIP_RETCODE SCIPprimalAddOrigSolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL **sol, SCIP_Bool *stored)
Definition: primal.c:1323
#define SCIP_LONGINT_FORMAT
Definition: def.h:142
SCIP_RETCODE SCIPprimalSetUpperbound(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real upperbound)
Definition: primal.c:374
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:88
SCIP_RETCODE SCIPprimalAddSolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool *stored)
Definition: primal.c:1213
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:87
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10076
SCIP_Bool SCIPprimalUpperboundIsSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
Definition: primal.c:544
SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
Definition: tree.c:8287
public methods for message output
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2460
SCIP_Real upperbound
Definition: struct_primal.h:45
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6029
SCIP_RETCODE SCIPprimalAddSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool *stored)
Definition: primal.c:1145
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16848
int SCIPsolGetPrimalIndex(SCIP_SOL *sol)
Definition: sol.c:2563
void SCIPsolUpdateVarObj(SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: sol.c:1515
#define SCIP_Real
Definition: def.h:150
internal methods for problem statistics
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Real firstprimaltime
Definition: struct_stat.h:122
SCIP_Real firstprimalbound
Definition: struct_stat.h:121
#define BMSallocMemory(ptr)
Definition: memory.h:101
#define SCIP_INVALID
Definition: def.h:170
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:109
static SCIP_RETCODE ensurePartialsolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:71
SCIP_RETCODE SCIPprimalUpdateObjoffset(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp)
Definition: primal.c:444
int SCIPsolGetDepth(SCIP_SOL *sol)
Definition: sol.c:2543
SCIP_RETCODE SCIPprimalTransformSol(SCIP_PRIMAL *primal, SCIP_SOL *sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real *solvals, SCIP_Bool *solvalset, int solvalssize, SCIP_Bool *added)
Definition: primal.c:1737
SCIP_Real SCIPsetEpsilon(SCIP_SET *set)
Definition: set.c:5835
SCIP_STAGE SCIPsetGetStage(SCIP_SET *set)
Definition: set.c:2847
SCIP_Real SCIPprobExternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2074
static int primalSearchSolPos(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SOL *sol)
Definition: primal.c:867
void SCIPprimalAddOrigObjoffset(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_Real addval)
Definition: primal.c:510
SCIP_RETCODE SCIPprimalCreate(SCIP_PRIMAL **primal)
Definition: primal.c:118
SCIP_RETCODE SCIPtreeCutoff(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real cutoffbound)
Definition: tree.c:5052
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:112
SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
Definition: sol.c:2480
common defines and data types used in all packages of SCIP
SCIP_Longint nnodes
Definition: struct_stat.h:73
static SCIP_RETCODE ensureExistingsolsSize(SCIP_PRIMAL *primal, SCIP_SET *set, int num)
Definition: primal.c:96
static SCIP_Bool primalExistsOrigSol(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_SOL *sol, int insertpos)
Definition: primal.c:1034
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2523
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
SCIP_RETCODE SCIPvarGetProbvarSum(SCIP_VAR **var, SCIP_SET *set, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12126
SCIP_RETCODE SCIPprimalFree(SCIP_PRIMAL **primal, BMS_BLKMEM *blkmem)
Definition: primal.c:148
SCIP_RETCODE SCIPprimalUpdateRay(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *primalray, BMS_BLKMEM *blkmem)
Definition: primal.c:567
int firstprimaldepth
Definition: struct_stat.h:255
#define SCIP_ALLOC(x)
Definition: def.h:362
int existingsolssize
Definition: struct_primal.h:58
void SCIPvisualUpperbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real upperbound)
Definition: visual.c:795
SCIP_Longint nlimsolsfound
Definition: struct_primal.h:40
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:1599
SCIP_SOL ** existingsols
Definition: struct_primal.h:50
void SCIPvisualFoundSolution(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node, SCIP_Bool bettersol, SCIP_SOL *sol)
Definition: visual.c:659
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17016
SCIP_RETCODE SCIPprimalTryCurrentSol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_HEUR *heur, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: primal.c:1581
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:753
internal methods for displaying runtime statistics