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