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