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