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  /* cppcheck-suppress unassignedVariable */
613  SCIP_EVENT event;
614  SCIP_Real obj;
615  int pos;
616 
617  assert(primal != NULL);
618  assert(set != NULL);
619  assert(solptr != NULL);
620  assert(stat != NULL);
621  assert(transprob != NULL);
622  assert(origprob != NULL);
623  assert(0 <= insertpos && insertpos < set->limit_maxsol);
624  assert(tree == NULL || !SCIPtreeInRepropagation(tree));
625 
626  sol = *solptr;
627  assert(sol != NULL);
628  obj = SCIPsolGetObj(sol, set, transprob, origprob);
629 
630  SCIPsetDebugMsg(set, "insert primal solution %p with obj %g at position %d (replace=%u):\n",
631  (void*)sol, obj, insertpos, replace);
632 
633  SCIPdebug( SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, transprob, NULL, NULL, FALSE, FALSE) ) );
634 
635 #if 0 /* this is not a valid debug check, but can be used to track down numerical troubles */
636 #ifndef NDEBUG
637  /* check solution again completely
638  * it fail for different reasons:
639  * - in the LP solver, the feasibility tolerance is a relative measure against the row's norm
640  * - in SCIP, the feasibility tolerance is a relative measure against the row's rhs/lhs
641  * - the rhs/lhs of a row might drastically change during presolving when variables are fixed or (multi-)aggregated
642  */
643  if( !SCIPsolIsOriginal(sol) )
644  {
645  SCIP_Bool feasible;
646 
647  SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, TRUE, TRUE, TRUE, TRUE, &feasible) );
648 
649  if( !feasible )
650  {
651  SCIPerrorMessage("infeasible solution accepted:\n");
652  SCIP_CALL( SCIPsolPrint(sol, set, messagehdlr, stat, origprob, transprob, NULL, FALSE, FALSE) );
653  }
654  assert(feasible);
655  }
656 #endif
657 #endif
658 
659  /* completely fill the solution's own value array to unlink it from the LP or pseudo solution */
660  SCIP_CALL( SCIPsolUnlink(sol, set, transprob) );
661 
662  /* allocate memory for solution storage */
663  SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxsol) );
664 
665  /* if set->limit_maxsol was decreased in the meantime, free all solutions exceeding the limit */
666  for( pos = set->limit_maxsol; pos < primal->nsols; ++pos )
667  {
668  SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
669  }
670  primal->nsols = MIN(primal->nsols, set->limit_maxsol);
671 
672  /* if the solution should replace an existing one, free this solution, otherwise,
673  * free the last solution if the solution storage is full;
674  */
675  if( replace )
676  {
677  SCIP_CALL( SCIPsolTransform(primal->sols[insertpos], solptr, blkmem, set, primal) );
678  sol = primal->sols[insertpos];
679  }
680  else
681  {
682  if( primal->nsols == set->limit_maxsol )
683  {
684  SCIP_CALL( SCIPsolFree(&primal->sols[set->limit_maxsol - 1], blkmem, primal) );
685  }
686  else
687  {
688  primal->nsols = primal->nsols + 1;
689  assert(primal->nsols <= set->limit_maxsol);
690  }
691 
692  /* move all solutions with worse objective value than the new solution */
693  for( pos = primal->nsols-1; pos > insertpos; --pos )
694  primal->sols[pos] = primal->sols[pos-1];
695 
696  /* insert solution at correct position */
697  assert(0 <= insertpos && insertpos < primal->nsols);
698  primal->sols[insertpos] = sol;
699  primal->nsolsfound++;
700 
701  /* check if solution is better than objective limit */
702  if( SCIPsetIsFeasLE(set, obj, SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(origprob, set))) )
703  primal->nlimsolsfound++;
704  }
705 
706  /* if its the first primal solution, store the relevant statistics */
707  if( primal->nsolsfound == 1 )
708  {
709  SCIP_Real primalsolval;
710 
712  stat->nrunsbeforefirst = SCIPsolGetRunnum(sol);
713  stat->firstprimalheur = SCIPsolGetHeur(sol);
714  stat->firstprimaltime = SCIPsolGetTime(sol);
715  stat->firstprimaldepth = SCIPsolGetDepth(sol);
716 
717  primalsolval = obj;
718  stat->firstprimalbound = SCIPprobExternObjval(transprob, origprob, set, primalsolval);
719 
720  SCIPsetDebugMsg(set, "First Solution stored in problem specific statistics.\n");
721  SCIPsetDebugMsg(set, "-> %" SCIP_LONGINT_FORMAT " nodes, %d runs, %.2g time, %d depth, %.15g objective\n", stat->nnodesbeforefirst, stat->nrunsbeforefirst,
723  }
724 
725  SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
726  insertpos, primal->nsols, primal->nsolsfound);
727 
728  /* update the solution value sums in variables */
729  if( !SCIPsolIsOriginal(sol) )
730  {
731  SCIPsolUpdateVarsum(sol, set, stat, transprob,
732  (SCIP_Real)(primal->nsols - insertpos)/(SCIP_Real)(2.0*primal->nsols - 1.0));
733  }
734 
735  /* change color of node in visualization output */
736  SCIPvisualFoundSolution(stat->visual, set, stat, SCIPtreeGetCurrentNode(tree), insertpos == 0 ? TRUE : FALSE, sol);
737 
738  /* check, if the global upper bound has to be updated */
739  if( obj < primal->cutoffbound && insertpos == 0 )
740  {
741  /* update the upper bound */
742  SCIP_CALL( SCIPprimalSetUpperbound(primal, blkmem, set, stat, eventqueue, transprob, tree, reopt, lp, obj) );
743 
744  /* issue BESTSOLFOUND event */
746  primal->nbestsolsfound++;
747  stat->bestsolnode = stat->nnodes;
748  }
749  else
750  {
751  /* issue POORSOLFOUND event */
753  }
754  SCIP_CALL( SCIPeventChgSol(&event, sol) );
755  SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
756 
757  /* display node information line */
758  if( insertpos == 0 && !replace && set->stage >= SCIP_STAGE_SOLVING )
759  {
760  SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, TRUE, TRUE) );
761  }
762 
763  /* if an original solution was added during solving, try to transfer it to the transformed space */
764  if( SCIPsolIsOriginal(sol) && SCIPsetGetStage(set) == SCIP_STAGE_SOLVING && set->misc_transorigsols )
765  {
766  SCIP_Bool added;
767 
768  SCIP_CALL( SCIPprimalTransformSol(primal, sol, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt,
769  lp, eventqueue, eventfilter, NULL, NULL, 0, &added) );
770 
771  SCIPsetDebugMsg(set, "original solution %p was successfully transferred to the transformed problem space\n",
772  (void*)sol);
773 
774  }
775 
776  return SCIP_OKAY;
777 }
778 
779 /** adds primal solution to solution storage at given position */
780 static
782  SCIP_PRIMAL* primal, /**< primal data */
783  BMS_BLKMEM* blkmem, /**< block memory */
784  SCIP_SET* set, /**< global SCIP settings */
785  SCIP_PROB* prob, /**< original problem data */
786  SCIP_SOL* sol, /**< primal CIP solution */
787  int insertpos /**< position in solution storage to add solution to */
788  )
789 {
790  int pos;
791 
792  assert(primal != NULL);
793  assert(set != NULL);
794  assert(prob != NULL);
795  assert(sol != NULL);
796  assert(0 <= insertpos && insertpos < set->limit_maxorigsol);
797  assert(!set->reopt_enable);
798 
799  SCIPsetDebugMsg(set, "insert primal solution candidate %p with obj %g at position %d:\n", (void*)sol, SCIPsolGetOrigObj(sol), insertpos);
800 
801  /* allocate memory for solution storage */
802  SCIP_CALL( ensureSolsSize(primal, set, set->limit_maxorigsol) );
803 
804  /* if the solution storage is full, free the last solution(s)
805  * more than one solution may be freed, if set->limit_maxorigsol was decreased in the meantime
806  */
807  for( pos = set->limit_maxorigsol-1; pos < primal->nsols; ++pos )
808  {
809  SCIP_CALL( SCIPsolFree(&primal->sols[pos], blkmem, primal) );
810  }
811 
812  /* insert solution at correct position */
813  primal->nsols = MIN(primal->nsols+1, set->limit_maxorigsol);
814  for( pos = primal->nsols-1; pos > insertpos; --pos )
815  primal->sols[pos] = primal->sols[pos-1];
816 
817  assert(0 <= insertpos && insertpos < primal->nsols);
818  primal->sols[insertpos] = sol;
819  primal->nsolsfound++;
820 
821  /* check if solution is better than objective limit */
822  if( SCIPsetIsFeasLE(set, SCIPsolGetOrigObj(sol), SCIPprobGetObjlim(prob, set)) )
823  primal->nlimsolsfound++;
824 
825  SCIPsetDebugMsg(set, " -> stored at position %d of %d solutions, found %" SCIP_LONGINT_FORMAT " solutions\n",
826  insertpos, primal->nsols, primal->nsolsfound);
827 
828  return SCIP_OKAY;
829 }
830 
831 /** adds primal solution to solution storage */
832 static
834  SCIP_PRIMAL* primal, /**< primal data */
835  BMS_BLKMEM* blkmem, /**< block memory */
836  SCIP_SET* set, /**< global SCIP settings */
837  SCIP_PROB* prob, /**< original problem data */
838  SCIP_SOL* sol /**< primal CIP solution */
839  )
840 { /*lint --e{715}*/
841  assert(primal != NULL);
842  assert(set != NULL);
843  assert(prob != NULL);
844  assert(sol != NULL);
845 
846  if( primal->npartialsols >= set->limit_maxorigsol )
847  {
848  SCIPerrorMessage("Cannot add partial solution to storage: limit reached.\n");
849  return SCIP_INVALIDCALL;
850  }
851 
852  SCIPsetDebugMsg(set, "insert partial solution candidate %p:\n", (void*)sol);
853 
854  /* allocate memory for solution storage */
855  SCIP_CALL( ensurePartialsolsSize(primal, set, primal->npartialsols+1) );
856 
857  primal->partialsols[primal->npartialsols] = sol;
858  ++primal->npartialsols;
859 
860  return SCIP_OKAY;
861 }
862 
863 /** uses binary search to find position in solution storage */
864 static
866  SCIP_PRIMAL* primal, /**< primal data */
867  SCIP_SET* set, /**< global SCIP settings */
868  SCIP_PROB* transprob, /**< tranformed problem data */
869  SCIP_PROB* origprob, /**< original problem data */
870  SCIP_SOL* sol /**< primal solution to search position for */
871  )
872 {
873  SCIP_SOL** sols;
874  SCIP_Real obj;
875  SCIP_Real middleobj;
876  int left;
877  int right;
878  int middle;
879 
880  assert(primal != NULL);
881 
882  obj = SCIPsolGetObj(sol, set, transprob, origprob);
883  sols = primal->sols;
884 
885  left = -1;
886  right = primal->nsols;
887  while( left < right-1 )
888  {
889  middle = (left+right)/2;
890  assert(left < middle && middle < right);
891  assert(0 <= middle && middle < primal->nsols);
892 
893  middleobj = SCIPsolGetObj(sols[middle], set, transprob, origprob);
894 
895  if( obj < middleobj )
896  right = middle;
897  else
898  left = middle;
899  }
900  assert(left == right-1);
901 
902  /* prefer solutions that live in the transformed space */
903  if( !SCIPsolIsOriginal(sol) )
904  {
905  while( right > 0 && SCIPsolIsOriginal(sols[right-1])
906  && SCIPsetIsEQ(set, SCIPsolGetObj(sols[right-1], set, transprob, origprob), obj) )
907  --right;
908  }
909 
910  return right;
911 }
912 
913 /** uses binary search to find position in solution storage */
914 static
916  SCIP_PRIMAL* primal, /**< primal data */
917  SCIP_SOL* sol /**< primal solution to search position for */
918  )
919 {
920  SCIP_Real obj;
921  SCIP_Real middleobj;
922  int left;
923  int right;
924  int middle;
925 
926  assert(primal != NULL);
927 
928  obj = SCIPsolGetOrigObj(sol);
929 
930  left = -1;
931  right = primal->nsols;
932  while( left < right-1 )
933  {
934  middle = (left+right)/2;
935  assert(left < middle && middle < right);
936  assert(0 <= middle && middle < primal->nsols);
937  middleobj = SCIPsolGetOrigObj(primal->sols[middle]);
938  if( obj < middleobj )
939  right = middle;
940  else
941  left = middle;
942  }
943  assert(left == right-1);
944 
945  return right;
946 }
947 
948 /** returns whether the given primal solution is already existent in the solution storage */
949 static
951  SCIP_PRIMAL* primal, /**< primal data */
952  SCIP_SET* set, /**< global SCIP settings */
953  SCIP_STAT* stat, /**< problem statistics data */
954  SCIP_PROB* origprob, /**< original problem */
955  SCIP_PROB* transprob, /**< transformed problem after presolve */
956  SCIP_SOL* sol, /**< primal solution to search position for */
957  int* insertpos, /**< pointer to insertion position returned by primalSearchSolPos(); the
958  * position might be changed if an existing solution should be replaced */
959  SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced */
960  )
961 {
962  SCIP_Real obj;
963  int i;
964 
965  assert(primal != NULL);
966  assert(insertpos != NULL);
967  assert(replace != NULL);
968  assert(0 <= (*insertpos) && (*insertpos) <= primal->nsols);
969 
970  obj = SCIPsolGetObj(sol, set, transprob, origprob);
971 
972  assert(primal->sols != NULL || primal->nsols == 0);
973  assert(primal->sols != NULL || (*insertpos) == 0);
974 
975  /* search in the better solutions */
976  for( i = (*insertpos)-1; i >= 0; --i )
977  {
978  SCIP_Real solobj;
979 
980  solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
981 
982  /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
983  * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
984  */
985  assert(SCIPsetIsLE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasLE(set, solobj, obj)));
986 
987  if( SCIPsetIsLT(set, solobj, obj) )
988  break;
989 
990  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
991  {
992  if( SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
993  {
994  (*insertpos) = i;
995  (*replace) = TRUE;
996  }
997  return TRUE;
998  }
999  }
1000 
1001  /* search in the worse solutions */
1002  for( i = (*insertpos); i < primal->nsols; ++i )
1003  {
1004  SCIP_Real solobj;
1005 
1006  solobj = SCIPsolGetObj(primal->sols[i], set, transprob, origprob);
1007 
1008  /* due to transferring the objective value of transformed solutions to the original space, small numerical errors might occur
1009  * which can lead to SCIPsetIsLE() failing in case of high absolute numbers
1010  */
1011  assert( SCIPsetIsGE(set, solobj, obj) || (REALABS(obj) > 1e+13 * SCIPsetEpsilon(set) && SCIPsetIsFeasGE(set, solobj, obj)));
1012 
1013  if( SCIPsetIsGT(set, solobj, obj) )
1014  break;
1015 
1016  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, origprob, transprob) )
1017  {
1018  if( SCIPsolIsOriginal(primal->sols[i]) && !SCIPsolIsOriginal(sol) )
1019  {
1020  (*insertpos) = i;
1021  (*replace) = TRUE;
1022  }
1023  return TRUE;
1024  }
1025  }
1026 
1027  return FALSE;
1028 }
1029 
1030 /** returns whether the given primal solution is already existent in the original solution candidate storage */
1031 static
1033  SCIP_PRIMAL* primal, /**< primal data */
1034  SCIP_SET* set, /**< global SCIP settings */
1035  SCIP_STAT* stat, /**< problem statistics data */
1036  SCIP_PROB* prob, /**< original problem */
1037  SCIP_SOL* sol, /**< primal solution to search position for */
1038  int insertpos /**< insertion position returned by primalSearchOrigSolPos() */
1039  )
1040 {
1041  SCIP_Real obj;
1042  int i;
1043 
1044  assert(primal != NULL);
1045  assert(0 <= insertpos && insertpos <= primal->nsols);
1046 
1047  obj = SCIPsolGetOrigObj(sol);
1048 
1049  /* search in the better solutions */
1050  for( i = insertpos-1; i >= 0; --i )
1051  {
1052  SCIP_Real solobj;
1053 
1054  solobj = SCIPsolGetOrigObj(primal->sols[i]);
1055  assert( SCIPsetIsLE(set, solobj, obj) );
1056 
1057  if( SCIPsetIsLT(set, solobj, obj) )
1058  break;
1059 
1060  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1061  return TRUE;
1062  }
1063 
1064  /* search in the worse solutions */
1065  for( i = insertpos; i < primal->nsols; ++i )
1066  {
1067  SCIP_Real solobj;
1068 
1069  solobj = SCIPsolGetOrigObj(primal->sols[i]);
1070  assert( SCIPsetIsGE(set, solobj, obj) );
1071 
1072  if( SCIPsetIsGT(set, solobj, obj) )
1073  break;
1074 
1075  if( SCIPsolsAreEqual(sol, primal->sols[i], set, stat, prob, NULL) )
1076  return TRUE;
1077  }
1078 
1079  return FALSE;
1080 }
1081 
1082 /** check if we are willing to check the solution for feasibility */
1083 static
1085  SCIP_PRIMAL* primal, /**< primal data */
1086  SCIP_SET* set, /**< global SCIP settings */
1087  SCIP_STAT* stat, /**< problem statistics data */
1088  SCIP_PROB* origprob, /**< original problem */
1089  SCIP_PROB* transprob, /**< transformed problem after presolve */
1090  SCIP_SOL* sol, /**< primal CIP solution */
1091  int* insertpos, /**< pointer to store the insert position of that solution */
1092  SCIP_Bool* replace /**< pointer to store whether the solution at insertpos should be replaced
1093  * (e.g., because it lives in the original space) */
1094  )
1095 {
1096  SCIP_Real obj;
1097 
1098  obj = SCIPsolGetObj(sol, set, transprob, origprob);
1099 
1100  /* check if we are willing to check worse solutions; a solution is better if the objective is smaller than the
1101  * current cutoff bound; solutions with infinite objective value are never accepted
1102  */
1103  if( (!set->misc_improvingsols || obj < primal->cutoffbound) && !SCIPsetIsInfinity(set, obj) )
1104  {
1105  /* find insert position for the solution */
1106  (*insertpos) = primalSearchSolPos(primal, set, transprob, origprob, sol);
1107  (*replace) = FALSE;
1108 
1109  /* the solution should be added, if the insertpos is smaller than the maximum number of solutions to be stored
1110  * and it does not already exist or it does exist, but the existing solution should be replaced by the new one
1111  */
1112  if( (*insertpos) < set->limit_maxsol &&
1113  (!primalExistsSol(primal, set, stat, origprob, transprob, sol, insertpos, replace) || (*replace)) )
1114  return TRUE;
1115  }
1116 
1117  return FALSE;
1118 }
1119 
1120 /** check if we are willing to store the solution candidate for later checking */
1121 static
1123  SCIP_PRIMAL* primal, /**< primal data */
1124  SCIP_SET* set, /**< global SCIP settings */
1125  SCIP_STAT* stat, /**< problem statistics data */
1126  SCIP_PROB* origprob, /**< original problem */
1127  SCIP_SOL* sol, /**< primal CIP solution */
1128  int* insertpos /**< pointer to store the insert position of that solution */
1129  )
1130 {
1131  assert(SCIPsolIsOriginal(sol));
1132 
1133  /* find insert position for the solution */
1134  (*insertpos) = primalSearchOrigSolPos(primal, sol);
1135 
1136  if( !set->reopt_enable && (*insertpos) < set->limit_maxorigsol && !primalExistsOrigSol(primal, set, stat, origprob, sol, *insertpos) )
1137  return TRUE;
1138 
1139  return FALSE;
1140 }
1141 
1142 /** adds primal solution to solution storage by copying it */
1144  SCIP_PRIMAL* primal, /**< primal data */
1145  BMS_BLKMEM* blkmem, /**< block memory */
1146  SCIP_SET* set, /**< global SCIP settings */
1147  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1148  SCIP_STAT* stat, /**< problem statistics data */
1149  SCIP_PROB* origprob, /**< original problem */
1150  SCIP_PROB* transprob, /**< transformed problem after presolve */
1151  SCIP_TREE* tree, /**< branch and bound tree */
1152  SCIP_REOPT* reopt, /**< reoptimization data structure */
1153  SCIP_LP* lp, /**< current LP data */
1154  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1155  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1156  SCIP_SOL* sol, /**< primal CIP solution */
1157  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1158  )
1159 {
1160  SCIP_Bool replace;
1161  int insertpos;
1162 
1163  assert(primal != NULL);
1164  assert(blkmem != NULL);
1165  assert(set != NULL);
1166  assert(messagehdlr != NULL);
1167  assert(stat != NULL);
1168  assert(origprob != NULL);
1169  assert(transprob != NULL);
1170  assert(tree != NULL);
1171  assert(lp != NULL);
1172  assert(eventqueue != NULL);
1173  assert(eventfilter != NULL);
1174  assert(sol != NULL);
1175  assert(stored != NULL);
1176 
1177  insertpos = -1;
1178 
1179  assert(!SCIPsolIsPartial(sol));
1180 
1181  if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1182  {
1183  SCIP_SOL* solcopy;
1184 #ifdef SCIP_MORE_DEBUG
1185  int i;
1186 #endif
1187 
1188  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1189 
1190  /* create a copy of the solution */
1191  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1192 
1193  /* insert copied solution into solution storage */
1194  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1195  tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1196 #ifdef SCIP_MORE_DEBUG
1197  for( i = 0; i < primal->nsols - 1; ++i )
1198  {
1199  assert(SCIPsetIsLE(set, SCIPsolGetObj(primal->sols[i], set, transprob, origprob), SCIPsolGetObj(primal->sols[i+1], set, transprob, origprob)));
1200  }
1201 #endif
1202  *stored = TRUE;
1203  }
1204  else
1205  *stored = FALSE;
1206 
1207  return SCIP_OKAY;
1208 }
1209 
1210 /** adds primal solution to solution storage, frees the solution afterwards */
1212  SCIP_PRIMAL* primal, /**< primal data */
1213  BMS_BLKMEM* blkmem, /**< block memory */
1214  SCIP_SET* set, /**< global SCIP settings */
1215  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1216  SCIP_STAT* stat, /**< problem statistics data */
1217  SCIP_PROB* origprob, /**< original problem */
1218  SCIP_PROB* transprob, /**< transformed problem after presolve */
1219  SCIP_TREE* tree, /**< branch and bound tree */
1220  SCIP_REOPT* reopt, /**< reoptimization data structure */
1221  SCIP_LP* lp, /**< current LP data */
1222  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1223  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1224  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1225  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1226  )
1227 {
1228  SCIP_Bool replace;
1229  int insertpos;
1230 
1231  assert(primal != NULL);
1232  assert(transprob != NULL);
1233  assert(origprob != NULL);
1234  assert(sol != NULL);
1235  assert(*sol != NULL);
1236  assert(stored != NULL);
1237 
1238  insertpos = -1;
1239 
1240  if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1241  {
1242  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1243 
1244  /* insert solution into solution storage */
1245  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1246  tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1247 
1248  /* clear the pointer, such that the user cannot access the solution anymore */
1249  *sol = NULL;
1250 
1251  *stored = TRUE;
1252  }
1253  else
1254  {
1255  /* the solution is too bad -> free it immediately */
1256  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1257 
1258  *stored = FALSE;
1259  }
1260  assert(*sol == NULL);
1261 
1262  return SCIP_OKAY;
1263 }
1264 
1265 /** adds primal solution to solution candidate storage of original problem space */
1267  SCIP_PRIMAL* primal, /**< primal data */
1268  BMS_BLKMEM* blkmem, /**< block memory */
1269  SCIP_SET* set, /**< global SCIP settings */
1270  SCIP_STAT* stat, /**< problem statistics data */
1271  SCIP_PROB* prob, /**< original problem data */
1272  SCIP_SOL* sol, /**< primal CIP solution; is cleared in function call */
1273  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1274  )
1275 {
1276  int insertpos;
1277 
1278  assert(primal != NULL);
1279  assert(blkmem != NULL);
1280  assert(set != NULL);
1281  assert(stat != NULL);
1282  assert(sol != NULL);
1283  assert(SCIPsolIsOriginal(sol));
1284  assert(stored != NULL);
1285 
1286  insertpos = -1;
1287 
1288  if( SCIPsolIsPartial(sol) )
1289  {
1290  SCIP_SOL* solcopy;
1291 
1292  /* create a copy of the solution */
1293  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1294 
1295  SCIP_CALL( primalAddOrigPartialSol(primal, blkmem, set, prob, solcopy) );
1296 
1297  *stored = TRUE;
1298  }
1299  else if( origsolOfInterest(primal, set, stat, prob, sol, &insertpos) )
1300  {
1301  SCIP_SOL* solcopy;
1302 
1303  assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1304  assert(!set->reopt_enable);
1305 
1306  /* create a copy of the solution */
1307  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1308 
1309  /* insert solution into solution storage */
1310  SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, solcopy, insertpos) );
1311 
1312  *stored = TRUE;
1313  }
1314  else
1315  *stored = FALSE;
1316 
1317  return SCIP_OKAY;
1318 }
1319 
1320 /** adds primal solution to solution candidate storage of original problem space, frees the solution afterwards */
1322  SCIP_PRIMAL* primal, /**< primal data */
1323  BMS_BLKMEM* blkmem, /**< block memory */
1324  SCIP_SET* set, /**< global SCIP settings */
1325  SCIP_STAT* stat, /**< problem statistics data */
1326  SCIP_PROB* prob, /**< original problem data */
1327  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1328  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1329  )
1330 {
1331  int insertpos;
1332 
1333  assert(primal != NULL);
1334  assert(sol != NULL);
1335  assert(*sol != NULL);
1336  assert(SCIPsolIsOriginal(*sol));
1337  assert(stored != NULL);
1338 
1339  insertpos = -1;
1340 
1341  if( SCIPsolIsPartial(*sol) )
1342  {
1343  /* insert solution into solution storage */
1344  SCIP_CALL( primalAddOrigPartialSol(primal, blkmem, set, prob, *sol) );
1345 
1346  /* clear the pointer, such that the user cannot access the solution anymore */
1347  *sol = NULL;
1348 
1349  *stored = TRUE;
1350  }
1351  else if( origsolOfInterest(primal, set, stat, prob, *sol, &insertpos) )
1352  {
1353  assert(insertpos >= 0 && insertpos < set->limit_maxorigsol);
1354  assert(!set->reopt_enable);
1355 
1356  /* insert solution into solution storage */
1357  SCIP_CALL( primalAddOrigSol(primal, blkmem, set, prob, *sol, insertpos) );
1358 
1359  /* clear the pointer, such that the user cannot access the solution anymore */
1360  *sol = NULL;
1361 
1362  *stored = TRUE;
1363  }
1364  else
1365  {
1366  /* the solution is too bad -> free it immediately */
1367  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1368 
1369  *stored = FALSE;
1370  }
1371  assert(*sol == NULL);
1372 
1373  return SCIP_OKAY;
1374 }
1375 
1376 /** links temporary solution of primal data to current solution */
1377 static
1379  SCIP_PRIMAL* primal, /**< primal data */
1380  BMS_BLKMEM* blkmem, /**< block memory */
1381  SCIP_SET* set, /**< global SCIP settings */
1382  SCIP_STAT* stat, /**< problem statistics data */
1383  SCIP_PROB* prob, /**< transformed problem data */
1384  SCIP_TREE* tree, /**< branch and bound tree */
1385  SCIP_LP* lp, /**< current LP data */
1386  SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */
1387  )
1388 {
1389  assert(primal != NULL);
1390 
1391  if( primal->currentsol == NULL )
1392  {
1393  SCIP_CALL( SCIPsolCreateCurrentSol(&primal->currentsol, blkmem, set, stat, prob, primal, tree, lp, heur) );
1394  }
1395  else
1396  {
1397  SCIP_CALL( SCIPsolLinkCurrentSol(primal->currentsol, set, stat, prob, tree, lp) );
1398  SCIPsolSetHeur(primal->currentsol, heur);
1399  }
1400 
1401  return SCIP_OKAY;
1402 }
1403 
1404 /** adds current LP/pseudo solution to solution storage */
1406  SCIP_PRIMAL* primal, /**< primal data */
1407  BMS_BLKMEM* blkmem, /**< block memory */
1408  SCIP_SET* set, /**< global SCIP settings */
1409  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1410  SCIP_STAT* stat, /**< problem statistics data */
1411  SCIP_PROB* origprob, /**< original problem */
1412  SCIP_PROB* transprob, /**< transformed problem after presolve */
1413  SCIP_TREE* tree, /**< branch and bound tree */
1414  SCIP_REOPT* reopt, /**< reoptimization data structure */
1415  SCIP_LP* lp, /**< current LP data */
1416  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1417  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1418  SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1419  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1420  )
1421 {
1422  assert(primal != NULL);
1423 
1424  /* link temporary solution to current solution */
1425  SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1426 
1427  /* add solution to solution storage */
1428  SCIP_CALL( SCIPprimalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1429  tree, reopt, lp, eventqueue, eventfilter, primal->currentsol, stored) );
1430 
1431  return SCIP_OKAY;
1432 }
1433 
1434 /** checks primal solution; if feasible, adds it to storage by copying it */
1436  SCIP_PRIMAL* primal, /**< primal data */
1437  BMS_BLKMEM* blkmem, /**< block memory */
1438  SCIP_SET* set, /**< global SCIP settings */
1439  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1440  SCIP_STAT* stat, /**< problem statistics data */
1441  SCIP_PROB* origprob, /**< original problem */
1442  SCIP_PROB* transprob, /**< transformed problem after presolve */
1443  SCIP_TREE* tree, /**< branch and bound tree */
1444  SCIP_REOPT* reopt, /**< reoptimization data structure */
1445  SCIP_LP* lp, /**< current LP data */
1446  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1447  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1448  SCIP_SOL* sol, /**< primal CIP solution */
1449  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1450  SCIP_Bool completely, /**< Should all violations be checked? */
1451  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1452  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1453  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1454  SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */
1455  )
1456 {
1457  SCIP_Bool feasible;
1458  SCIP_Bool replace;
1459  int insertpos;
1460 
1461  assert(primal != NULL);
1462  assert(set != NULL);
1463  assert(transprob != NULL);
1464  assert(origprob != NULL);
1465  assert(tree != NULL);
1466  assert(sol != NULL);
1467  assert(stored != NULL);
1468 
1469  /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1470  checklprows = checklprows || set->misc_exactsolve;
1471 
1472  insertpos = -1;
1473 
1474  if( solOfInterest(primal, set, stat, origprob, transprob, sol, &insertpos, &replace) )
1475  {
1476  /* check solution for feasibility */
1477  SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1478  checkintegrality, checklprows, &feasible) );
1479  }
1480  else
1481  feasible = FALSE;
1482 
1483  if( feasible )
1484  {
1485  SCIP_SOL* solcopy;
1486 
1487  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1488 
1489  /* create a copy of the solution */
1490  SCIP_CALL( SCIPsolCopy(&solcopy, blkmem, set, stat, primal, sol) );
1491 
1492  /* insert copied solution into solution storage */
1493  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1494  tree, reopt, lp, eventqueue, eventfilter, &solcopy, insertpos, replace) );
1495 
1496  *stored = TRUE;
1497  }
1498  else
1499  *stored = FALSE;
1500 
1501  return SCIP_OKAY;
1502 }
1503 
1504 /** checks primal solution; if feasible, adds it to storage; solution is freed afterwards */
1506  SCIP_PRIMAL* primal, /**< primal data */
1507  BMS_BLKMEM* blkmem, /**< block memory */
1508  SCIP_SET* set, /**< global SCIP settings */
1509  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1510  SCIP_STAT* stat, /**< problem statistics data */
1511  SCIP_PROB* origprob, /**< original problem */
1512  SCIP_PROB* transprob, /**< transformed problem after presolve */
1513  SCIP_TREE* tree, /**< branch and bound tree */
1514  SCIP_REOPT* reopt, /**< reoptimization data structure */
1515  SCIP_LP* lp, /**< current LP data */
1516  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1517  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1518  SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */
1519  SCIP_Bool printreason, /**< Should all the reasons of violations be printed? */
1520  SCIP_Bool completely, /**< Should all violations be checked? */
1521  SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */
1522  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1523  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1524  SCIP_Bool* stored /**< stores whether solution was feasible and good enough to keep */
1525  )
1526 {
1527  SCIP_Bool feasible;
1528  SCIP_Bool replace;
1529  int insertpos;
1530 
1531  assert(primal != NULL);
1532  assert(transprob != NULL);
1533  assert(origprob != NULL);
1534  assert(tree != NULL);
1535  assert(sol != NULL);
1536  assert(*sol != NULL);
1537  assert(stored != NULL);
1538 
1539  *stored = FALSE;
1540 
1541  /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */
1542  checklprows = checklprows || set->misc_exactsolve;
1543 
1544  insertpos = -1;
1545 
1546  if( solOfInterest(primal, set, stat, origprob, transprob, *sol, &insertpos, &replace) )
1547  {
1548  /* check solution for feasibility */
1549  SCIP_CALL( SCIPsolCheck(*sol, set, messagehdlr, blkmem, stat, transprob, printreason, completely, checkbounds,
1550  checkintegrality, checklprows, &feasible) );
1551  }
1552  else
1553  feasible = FALSE;
1554 
1555  if( feasible )
1556  {
1557  assert(insertpos >= 0 && insertpos < set->limit_maxsol);
1558 
1559  /* insert solution into solution storage */
1560  SCIP_CALL( primalAddSol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1561  tree, reopt, lp, eventqueue, eventfilter, sol, insertpos, replace) );
1562 
1563  /* clear the pointer, such that the user cannot access the solution anymore */
1564  *sol = NULL;
1565  *stored = TRUE;
1566  }
1567  else
1568  {
1569  /* the solution is too bad or infeasible -> free it immediately */
1570  SCIP_CALL( SCIPsolFree(sol, blkmem, primal) );
1571  *stored = FALSE;
1572  }
1573  assert(*sol == NULL);
1574 
1575  return SCIP_OKAY;
1576 }
1577 
1578 /** checks current LP/pseudo solution; if feasible, adds it to storage */
1580  SCIP_PRIMAL* primal, /**< primal data */
1581  BMS_BLKMEM* blkmem, /**< block memory */
1582  SCIP_SET* set, /**< global SCIP settings */
1583  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1584  SCIP_STAT* stat, /**< problem statistics data */
1585  SCIP_PROB* origprob, /**< original problem */
1586  SCIP_PROB* transprob, /**< transformed problem after presolve */
1587  SCIP_TREE* tree, /**< branch and bound tree */
1588  SCIP_REOPT* reopt, /**< reoptimization data structure */
1589  SCIP_LP* lp, /**< current LP data */
1590  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1591  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1592  SCIP_HEUR* heur, /**< heuristic that found the solution (or NULL if it's from the tree) */
1593  SCIP_Bool printreason, /**< Should all reasons of violations be printed? */
1594  SCIP_Bool completely, /**< Should all violations be checked? */
1595  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
1596  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
1597  SCIP_Bool* stored /**< stores whether given solution was good enough to keep */
1598  )
1599 {
1600  assert(primal != NULL);
1601 
1602  /* link temporary solution to current solution */
1603  SCIP_CALL( primalLinkCurrentSol(primal, blkmem, set, stat, transprob, tree, lp, heur) );
1604 
1605  /* add solution to solution storage */
1606  SCIP_CALL( SCIPprimalTrySol(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1607  tree, reopt, lp, eventqueue, eventfilter, primal->currentsol,
1608  printreason, completely, FALSE, checkintegrality, checklprows, stored) );
1609 
1610  return SCIP_OKAY;
1611 }
1612 
1613 /** inserts solution into the global array of all existing primal solutions */
1615  SCIP_PRIMAL* primal, /**< primal data */
1616  SCIP_SET* set, /**< global SCIP settings */
1617  SCIP_SOL* sol /**< primal CIP solution */
1618  )
1619 {
1620  assert(primal != NULL);
1621  assert(sol != NULL);
1622  assert(SCIPsolGetPrimalIndex(sol) == -1);
1623 
1624  /* allocate memory for solution storage */
1625  SCIP_CALL( ensureExistingsolsSize(primal, set, primal->nexistingsols+1) );
1626 
1627  /* append solution */
1628  SCIPsolSetPrimalIndex(sol, primal->nexistingsols);
1629  primal->existingsols[primal->nexistingsols] = sol;
1630  primal->nexistingsols++;
1631 
1632  return SCIP_OKAY;
1633 }
1634 
1635 /** removes solution from the global array of all existing primal solutions */
1637  SCIP_PRIMAL* primal, /**< primal data */
1638  SCIP_SOL* sol /**< primal CIP solution */
1639  )
1640 {
1641  int idx;
1642 
1643  assert(primal != NULL);
1644  assert(sol != NULL);
1645 
1646 #ifndef NDEBUG
1647  for( idx = 0; idx < primal->nexistingsols; ++idx )
1648  {
1649  assert(idx == SCIPsolGetPrimalIndex(primal->existingsols[idx]));
1650  }
1651 #endif
1652 
1653  /* remove solution */
1654  idx = SCIPsolGetPrimalIndex(sol);
1655  assert(0 <= idx && idx < primal->nexistingsols);
1656  assert(sol == primal->existingsols[idx]);
1657  if( idx < primal->nexistingsols-1 )
1658  {
1659  primal->existingsols[idx] = primal->existingsols[primal->nexistingsols-1];
1660  SCIPsolSetPrimalIndex(primal->existingsols[idx], idx);
1661  }
1662  primal->nexistingsols--;
1663 }
1664 
1665 /** updates all existing primal solutions after a change in a variable's objective value */
1667  SCIP_PRIMAL* primal, /**< primal data */
1668  SCIP_VAR* var, /**< problem variable */
1669  SCIP_Real oldobj, /**< old objective value */
1670  SCIP_Real newobj /**< new objective value */
1671  )
1672 {
1673  int i;
1674 
1675  assert(primal != NULL);
1676 
1677  for( i = 0; i < primal->nexistingsols; ++i )
1678  {
1679  if( !SCIPsolIsOriginal(primal->existingsols[i]) )
1680  SCIPsolUpdateVarObj(primal->existingsols[i], var, oldobj, newobj);
1681  }
1682 }
1683 
1684 /** retransforms all existing solutions to original problem space */
1686  SCIP_PRIMAL* primal, /**< primal data */
1687  SCIP_SET* set, /**< global SCIP settings */
1688  SCIP_STAT* stat, /**< problem statistics data */
1689  SCIP_PROB* origprob, /**< original problem */
1690  SCIP_PROB* transprob /**< transformed problem */
1691  )
1692 {
1693  SCIP_Bool hasinfval;
1694  int i;
1695 
1696  assert(primal != NULL);
1697 
1698  for( i = 0; i < primal->nsols; ++i )
1699  {
1700  if( SCIPsolGetOrigin(primal->sols[i]) == SCIP_SOLORIGIN_ZERO )
1701  {
1702  SCIP_CALL( SCIPsolRetransform(primal->sols[i], set, stat, origprob, transprob, &hasinfval) );
1703  }
1704  }
1705 
1706  return SCIP_OKAY;
1707 }
1708 
1709 /** tries to transform original solution to the transformed problem space */
1711  SCIP_PRIMAL* primal, /**< primal data */
1712  SCIP_SOL* sol, /**< primal solution */
1713  BMS_BLKMEM* blkmem, /**< block memory */
1714  SCIP_SET* set, /**< global SCIP settings */
1715  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
1716  SCIP_STAT* stat, /**< problem statistics data */
1717  SCIP_PROB* origprob, /**< original problem */
1718  SCIP_PROB* transprob, /**< transformed problem after presolve */
1719  SCIP_TREE* tree, /**< branch and bound tree */
1720  SCIP_REOPT* reopt, /**< reoptimization data structure */
1721  SCIP_LP* lp, /**< current LP data */
1722  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1723  SCIP_EVENTFILTER* eventfilter, /**< event filter for global (not variable dependent) events */
1724  SCIP_Real* solvals, /**< array for internal use to store solution values, or NULL;
1725  * if the method is called multiple times in a row, an array with size >=
1726  * number of active variables should be given for performance reasons */
1727  SCIP_Bool* solvalset, /**< array for internal use to store which solution values were set, or NULL;
1728  * if the method is called multiple times in a row, an array with size >=
1729  * number of active variables should be given for performance reasons */
1730  int solvalssize, /**< size of solvals and solvalset arrays, should be >= number of active
1731  * variables */
1732  SCIP_Bool* added /**< pointer to store whether the solution was added */
1733  )
1734 {
1735  SCIP_VAR** origvars;
1736  SCIP_VAR** transvars;
1737  SCIP_VAR* var;
1738  SCIP_Real* localsolvals;
1739  SCIP_Bool* localsolvalset;
1740  SCIP_Real solval;
1741  SCIP_Real scalar;
1742  SCIP_Real constant;
1743  SCIP_Bool localarrays;
1744  SCIP_Bool feasible;
1745  int norigvars;
1746  int ntransvars;
1747  int nvarsset;
1748  int v;
1749 
1750  assert(origprob != NULL);
1751  assert(transprob != NULL);
1752  assert(SCIPsolIsOriginal(sol));
1753  assert(solvalssize == 0 || solvals != NULL);
1754  assert(solvalssize == 0 || solvalset != NULL);
1755 
1756  origvars = origprob->vars;
1757  norigvars = origprob->nvars;
1758  transvars = transprob->vars;
1759  ntransvars = transprob->nvars;
1760  assert(solvalssize == 0 || solvalssize >= ntransvars);
1761 
1762  SCIPsetDebugMsg(set, "try to transfer original solution %p with objective %g into the transformed problem space\n",
1763  (void*)sol, SCIPsolGetOrigObj(sol));
1764 
1765  /* if no solvals and solvalset arrays are given, allocate local ones, otherwise use the given ones */
1766  localarrays = (solvalssize == 0);
1767  if( localarrays )
1768  {
1769  SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvals, ntransvars) );
1770  SCIP_CALL( SCIPsetAllocBufferArray(set, &localsolvalset, ntransvars) );
1771  }
1772  else
1773  {
1774  localsolvals = solvals;
1775  localsolvalset = solvalset;
1776  }
1777 
1778  BMSclearMemoryArray(localsolvalset, ntransvars);
1779  feasible = TRUE;
1780  (*added) = FALSE;
1781  nvarsset = 0;
1782 
1783  /* for each original variable, get the corresponding active, fixed or multi-aggregated variable;
1784  * if it resolves to an active variable, we set its solution value or check whether an already stored solution value
1785  * is consistent; if it resolves to a fixed variable, we check that the fixing matches the original solution value;
1786  * multi-aggregated variables are skipped, because their value is defined by setting solution values for the active
1787  * variables, anyway
1788  */
1789  for( v = 0; v < norigvars && feasible; ++v )
1790  {
1791  var = origvars[v];
1792 
1793  solval = SCIPsolGetVal(sol, set, stat, var);
1794 
1795  /* get corresponding active, fixed, or multi-aggregated variable */
1796  scalar = 1.0;
1797  constant = 0.0;
1798  SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
1801 
1802  /* check whether the fixing corresponds to the solution value of the original variable */
1803  if( scalar == 0.0 )
1804  {
1805  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED ||
1806  (SCIPsetIsInfinity(set, constant) || SCIPsetIsInfinity(set, -constant)));
1807 
1808  if( !SCIPsetIsEQ(set, solval, constant) )
1809  {
1810  SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to fixed variable <%s> (original solval=%g)\n",
1811  SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), constant);
1812  feasible = FALSE;
1813  }
1814  }
1815  else if( SCIPvarIsActive(var) )
1816  {
1817  /* if we already assigned a solution value to the transformed variable, check that it corresponds to the
1818  * value obtained from the currently regarded original variable
1819  */
1820  if( localsolvalset[SCIPvarGetProbindex(var)] )
1821  {
1822  if( !SCIPsetIsEQ(set, solval, scalar * localsolvals[SCIPvarGetProbindex(var)] + constant) )
1823  {
1824  SCIPsetDebugMsg(set, "original variable <%s> (solval=%g) resolves to active variable <%s> with assigned solval %g (original solval=%g)\n",
1825  SCIPvarGetName(origvars[v]), solval, SCIPvarGetName(var), localsolvals[SCIPvarGetProbindex(var)],
1826  scalar * localsolvals[SCIPvarGetProbindex(var)] + constant);
1827  feasible = FALSE;
1828  }
1829  }
1830  /* assign solution value to the transformed variable */
1831  else
1832  {
1833  assert(scalar != 0.0);
1834 
1835  localsolvals[SCIPvarGetProbindex(var)] = (solval - constant) / scalar;
1836  localsolvalset[SCIPvarGetProbindex(var)] = TRUE;
1837  ++nvarsset;
1838  }
1839  }
1840 #ifndef NDEBUG
1841  /* we do not have to handle multi-aggregated variables here, since by assigning values to all active variabes,
1842  * we implicitly assign values to the multi-aggregated variables, too
1843  */
1844  else
1845  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR);
1846 #endif
1847  }
1848 
1849  /* if the solution values of fixed and active variables lead to no contradiction, construct solution and try it */
1850  if( feasible )
1851  {
1852  SCIP_SOL* transsol;
1853 
1854  SCIP_CALL( SCIPsolCreate(&transsol, blkmem, set, stat, primal, tree, SCIPsolGetHeur(sol)) );
1855 
1856  /* set solution values for variables to which we assigned a value */
1857  for( v = 0; v < ntransvars; ++v )
1858  {
1859  if( localsolvalset[v] )
1860  {
1861  SCIP_CALL( SCIPsolSetVal(transsol, set, stat, tree, transvars[v], localsolvals[v]) );
1862  }
1863  }
1864 
1865  SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob,
1866  tree, reopt, lp, eventqueue, eventfilter, &transsol, FALSE, FALSE, TRUE, TRUE, TRUE, added) );
1867 
1868  SCIPsetDebugMsg(set, "solution transferred, %d/%d active variables set (stored=%u)\n", nvarsset, ntransvars, *added);
1869  }
1870  else
1871  (*added) = FALSE;
1872 
1873  /* free local arrays, if needed */
1874  if( localarrays )
1875  {
1876  SCIPsetFreeBufferArray(set, &localsolvalset);
1877  SCIPsetFreeBufferArray(set, &localsolvals);
1878  }
1879 
1880  return SCIP_OKAY;
1881 }
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:1378
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:5517
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:5575
internal methods for storing primal CIP solutions
void SCIPprimalSolFreed(SCIP_PRIMAL *primal, SCIP_SOL *sol)
Definition: primal.c:1636
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:107
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:781
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:248
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:1435
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5379
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:1266
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:2036
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1834
int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
Definition: tree.c:8132
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16862
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:5492
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5091
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:104
SCIP_VISUAL * visual
Definition: struct_stat.h:163
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:5611
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:1405
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:2216
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5557
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:1505
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:915
SCIP_Longint bestsolnode
Definition: struct_stat.h:102
SCIP_Bool SCIPtreeInRepropagation(SCIP_TREE *tree)
Definition: tree.c:8105
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:164
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:16555
SCIP_Real SCIPsetFeasCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6093
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:950
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2382
#define REALABS(x)
Definition: def.h:169
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:2192
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:316
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6003
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5539
SCIP_RETCODE SCIPprimalRetransformSolutions(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob)
Definition: primal.c:1685
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5959
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:1614
#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:1122
void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: primal.c:1666
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:833
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:1444
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:1084
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:1321
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:1211
#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:9882
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:8115
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:5593
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:1143
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16674
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:145
internal methods for problem statistics
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Real firstprimaltime
Definition: struct_stat.h:120
#define MIN(x, y)
Definition: memory.c:75
SCIP_Real firstprimalbound
Definition: struct_stat.h:119
#define BMSallocMemory(ptr)
Definition: memory.h:78
#define SCIP_INVALID
Definition: def.h:165
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:86
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:1710
SCIP_Real SCIPsetEpsilon(SCIP_SET *set)
Definition: set.c:5401
SCIP_STAGE SCIPsetGetStage(SCIP_SET *set)
Definition: set.c:2664
SCIP_Real SCIPprobExternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
Definition: prob.c:2014
static int primalSearchSolPos(SCIP_PRIMAL *primal, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SOL *sol)
Definition: primal.c:865
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:5023
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:89
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:1032
int SCIPsolGetRunnum(SCIP_SOL *sol)
Definition: sol.c:2352
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
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:249
#define SCIP_ALLOC(x)
Definition: def.h:327
int existingsolssize
Definition: struct_primal.h:58
void SCIPvisualUpperbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real upperbound)
Definition: visual.c:778
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:16842
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:1579
SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
Definition: sol.c:739
internal methods for displaying runtime statistics