Scippy

SCIP

Solving Constraint Integer Programs

heur_shifting.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-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file heur_shifting.c
17  * @brief LP rounding heuristic that tries to recover from intermediate infeasibilities and shifts continuous variables
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 #include <string.h>
25 
26 #include "scip/heur_shifting.h"
27 
28 
29 #define HEUR_NAME "shifting"
30 #define HEUR_DESC "LP rounding heuristic with infeasibility recovering also using continuous variables"
31 #define HEUR_DISPCHAR 's'
32 #define HEUR_PRIORITY -5000
33 #define HEUR_FREQ 10
34 #define HEUR_FREQOFS 0
35 #define HEUR_MAXDEPTH -1
36 #define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP
37 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
38 
39 #define MAXSHIFTINGS 50 /**< maximal number of non improving shiftings */
40 #define WEIGHTFACTOR 1.1
41 
42 
43 /* locally defined heuristic data */
44 struct SCIP_HeurData
45 {
46  SCIP_SOL* sol; /**< working solution */
47  SCIP_Longint lastlp; /**< last LP number where the heuristic was applied */
48  unsigned int randseed; /**< seed value for random number generator */
49 };
50 
51 
52 /*
53  * local methods
54  */
55 
56 /** update row violation arrays after a row's activity value changed */
57 static
59  SCIP* scip, /**< SCIP data structure */
60  SCIP_ROW* row, /**< LP row */
61  SCIP_ROW** violrows, /**< array with currently violated rows */
62  int* violrowpos, /**< position of LP rows in violrows array */
63  int* nviolrows, /**< pointer to the number of currently violated rows */
64  int* nviolfracrows, /**< pointer to the number of violated rows with fractional candidates */
65  int* nfracsinrow, /**< array with number of fractional variables for every row */
66  SCIP_Real oldactivity, /**< old activity value of LP row */
67  SCIP_Real newactivity /**< new activity value of LP row */
68  )
69 {
70  SCIP_Real lhs;
71  SCIP_Real rhs;
72  SCIP_Bool oldviol;
73  SCIP_Bool newviol;
74 
75  assert(violrows != NULL);
76  assert(violrowpos != NULL);
77  assert(nviolrows != NULL);
78 
79  lhs = SCIProwGetLhs(row);
80  rhs = SCIProwGetRhs(row);
81  oldviol = (SCIPisFeasLT(scip, oldactivity, lhs) || SCIPisFeasGT(scip, oldactivity, rhs));
82  newviol = (SCIPisFeasLT(scip, newactivity, lhs) || SCIPisFeasGT(scip, newactivity, rhs));
83  if( oldviol != newviol )
84  {
85  int rowpos;
86  int violpos;
87 
88  rowpos = SCIProwGetLPPos(row);
89  assert(rowpos >= 0);
90 
91  if( oldviol )
92  {
93  /* the row violation was repaired: remove row from violrows array, decrease violation count */
94  violpos = violrowpos[rowpos];
95  assert(0 <= violpos && violpos < *nviolrows);
96  assert(violrows[violpos] == row);
97  violrowpos[rowpos] = -1;
98 
99  /* first, move the row to the end of the subset of violated rows with fractional variables */
100  if( nfracsinrow[rowpos] > 0 )
101  {
102  assert(violpos < *nviolfracrows);
103 
104  /* replace with last violated row containing fractional variables */
105  if( violpos != *nviolfracrows - 1 )
106  {
107  violrows[violpos] = violrows[*nviolfracrows - 1];
108  violrowpos[SCIProwGetLPPos(violrows[violpos])] = violpos;
109  violpos = *nviolfracrows - 1;
110  }
111  (*nviolfracrows)--;
112  }
113 
114  assert(violpos >= *nviolfracrows);
115 
116  /* swap row at the end of the violated array to the position of this row and decrease the counter */
117  if( violpos != *nviolrows - 1 )
118  {
119  violrows[violpos] = violrows[*nviolrows - 1];
120  violrowpos[SCIProwGetLPPos(violrows[violpos])] = violpos;
121  }
122  (*nviolrows)--;
123  }
124  else
125  {
126  /* the row is now violated: add row to violrows array, increase violation count */
127  assert(violrowpos[rowpos] == -1);
128  violrows[*nviolrows] = row;
129  violrowpos[rowpos] = *nviolrows;
130  (*nviolrows)++;
131 
132  /* if the row contains fractional variables, swap with the last violated row that has no fractional variables
133  * at position *nviolfracrows
134  */
135  if( nfracsinrow[rowpos] > 0 )
136  {
137  if( *nviolfracrows < *nviolrows - 1 )
138  {
139  assert(nfracsinrow[SCIProwGetLPPos(violrows[*nviolfracrows])] == 0);
140 
141  violrows[*nviolrows - 1] = violrows[*nviolfracrows];
142  violrowpos[SCIProwGetLPPos(violrows[*nviolrows - 1])] = *nviolrows - 1;
143 
144  violrows[*nviolfracrows] = row;
145  violrowpos[rowpos] = *nviolfracrows;
146  }
147  (*nviolfracrows)++;
148  }
149  }
150  }
151 }
152 
153 /** update row activities after a variable's solution value changed */
154 static
156  SCIP* scip, /**< SCIP data structure */
157  SCIP_Real* activities, /**< LP row activities */
158  SCIP_ROW** violrows, /**< array with currently violated rows */
159  int* violrowpos, /**< position of LP rows in violrows array */
160  int* nviolrows, /**< pointer to the number of currently violated rows */
161  int* nviolfracrows, /**< pointer to the number of violated rows with fractional candidates */
162  int* nfracsinrow, /**< array with number of fractional variables for every row */
163  int nlprows, /**< number of rows in current LP */
164  SCIP_VAR* var, /**< variable that has been changed */
165  SCIP_Real oldsolval, /**< old solution value of variable */
166  SCIP_Real newsolval /**< new solution value of variable */
167  )
168 {
169  SCIP_COL* col;
170  SCIP_ROW** colrows;
171  SCIP_Real* colvals;
172  SCIP_Real delta;
173  int ncolrows;
174  int r;
175 
176  assert(activities != NULL);
177  assert(nviolrows != NULL);
178  assert(0 <= *nviolrows && *nviolrows <= nlprows);
179 
180  delta = newsolval - oldsolval;
181  col = SCIPvarGetCol(var);
182  colrows = SCIPcolGetRows(col);
183  colvals = SCIPcolGetVals(col);
184  ncolrows = SCIPcolGetNLPNonz(col);
185  assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
186 
187  for( r = 0; r < ncolrows; ++r )
188  {
189  SCIP_ROW* row;
190  int rowpos;
191 
192  row = colrows[r];
193  rowpos = SCIProwGetLPPos(row);
194  assert(-1 <= rowpos && rowpos < nlprows);
195 
196  if( rowpos >= 0 && !SCIProwIsLocal(row) )
197  {
198  SCIP_Real oldactivity;
199  SCIP_Real newactivity;
200 
201  assert(SCIProwIsInLP(row));
202 
203  /* update row activity */
204  oldactivity = activities[rowpos];
205  if( !SCIPisInfinity(scip, -oldactivity) && !SCIPisInfinity(scip, oldactivity) )
206  {
207  newactivity = oldactivity + delta * colvals[r];
208  if( SCIPisInfinity(scip, newactivity) )
209  newactivity = SCIPinfinity(scip);
210  else if( SCIPisInfinity(scip, -newactivity) )
211  newactivity = -SCIPinfinity(scip);
212  activities[rowpos] = newactivity;
213 
214  /* update row violation arrays */
215  updateViolations(scip, row, violrows, violrowpos, nviolrows, nviolfracrows, nfracsinrow, oldactivity, newactivity);
216  }
217  }
218  }
219 
220  return SCIP_OKAY;
221 }
222 
223 /** returns a variable, that pushes activity of the row in the given direction with minimal negative impact on other rows;
224  * if variables have equal impact, chooses the one with best objective value improvement in corresponding direction;
225  * prefer fractional integers over other variables in order to become integral during the process;
226  * shifting in a direction is forbidden, if this forces the objective value over the upper bound, or if the variable
227  * was already shifted in the opposite direction
228  */
229 static
231  SCIP* scip, /**< SCIP data structure */
232  SCIP_SOL* sol, /**< primal solution */
233  SCIP_ROW* row, /**< LP row */
234  SCIP_Real rowactivity, /**< activity of LP row */
235  int direction, /**< should the activity be increased (+1) or decreased (-1)? */
236  SCIP_Real* nincreases, /**< array with weighted number of increasings per variables */
237  SCIP_Real* ndecreases, /**< array with weighted number of decreasings per variables */
238  SCIP_Real increaseweight, /**< current weight of increase/decrease updates */
239  SCIP_VAR** shiftvar, /**< pointer to store the shifting variable, returns NULL if impossible */
240  SCIP_Real* oldsolval, /**< pointer to store old solution value of shifting variable */
241  SCIP_Real* newsolval /**< pointer to store new (shifted) solution value of shifting variable */
242  )
243 {
244  SCIP_COL** rowcols;
245  SCIP_Real* rowvals;
246  int nrowcols;
247  SCIP_Real activitydelta;
248  SCIP_Real bestshiftscore;
249  SCIP_Real bestdeltaobj;
250  int c;
251 
252  assert(direction == +1 || direction == -1);
253  assert(nincreases != NULL);
254  assert(ndecreases != NULL);
255  assert(shiftvar != NULL);
256  assert(oldsolval != NULL);
257  assert(newsolval != NULL);
258 
259  /* get row entries */
260  rowcols = SCIProwGetCols(row);
261  rowvals = SCIProwGetVals(row);
262  nrowcols = SCIProwGetNLPNonz(row);
263 
264  /* calculate how much the activity must be shifted in order to become feasible */
265  activitydelta = (direction == +1 ? SCIProwGetLhs(row) - rowactivity : SCIProwGetRhs(row) - rowactivity);
266  assert((direction == +1 && SCIPisPositive(scip, activitydelta))
267  || (direction == -1 && SCIPisNegative(scip, activitydelta)));
268 
269  /* select shifting variable */
270  bestshiftscore = SCIP_REAL_MAX;
271  bestdeltaobj = SCIPinfinity(scip);
272  *shiftvar = NULL;
273  *newsolval = 0.0;
274  *oldsolval = 0.0;
275  for( c = 0; c < nrowcols; ++c )
276  {
277  SCIP_COL* col;
278  SCIP_VAR* var;
279  SCIP_Real val;
280  SCIP_Real solval;
281  SCIP_Real shiftval;
282  SCIP_Real shiftscore;
283  SCIP_Bool isinteger;
284  SCIP_Bool isfrac;
285  SCIP_Bool increase;
286 
287  col = rowcols[c];
288  var = SCIPcolGetVar(col);
289  val = rowvals[c];
290  assert(!SCIPisZero(scip, val));
291  solval = SCIPgetSolVal(scip, sol, var);
292 
294  isfrac = (isinteger && !SCIPisFeasIntegral(scip, solval));
295  increase = (direction * val > 0.0);
296 
297  /* calculate the score of the shifting (prefer smaller values) */
298  if( isfrac )
299  shiftscore = increase ? -1.0 / (SCIPvarGetNLocksUp(var) + 1.0) :
300  -1.0 / (SCIPvarGetNLocksDown(var) + 1.0);
301  else
302  {
303  int probindex;
304  probindex = SCIPvarGetProbindex(var);
305 
306  if( increase )
307  shiftscore = ndecreases[probindex]/increaseweight;
308  else
309  shiftscore = nincreases[probindex]/increaseweight;
310  if( isinteger )
311  shiftscore += 1.0;
312  }
313 
314  if( shiftscore <= bestshiftscore )
315  {
316  SCIP_Real deltaobj;
317 
318  if( !increase )
319  {
320  /* shifting down */
321  assert(direction * val < 0.0);
322  if( isfrac )
323  shiftval = SCIPfeasFloor(scip, solval);
324  else
325  {
326  SCIP_Real lb;
327 
328  assert(activitydelta/val < 0.0);
329  shiftval = solval + activitydelta/val;
330  assert(shiftval <= solval); /* may be equal due to numerical digit erasement in the subtraction */
331  if( SCIPvarIsIntegral(var) )
332  shiftval = SCIPfeasFloor(scip, shiftval);
333  lb = SCIPvarGetLbGlobal(var);
334  shiftval = MAX(shiftval, lb);
335  }
336  }
337  else
338  {
339  /* shifting up */
340  assert(direction * val > 0.0);
341  if( isfrac )
342  shiftval = SCIPfeasCeil(scip, solval);
343  else
344  {
345  SCIP_Real ub;
346 
347  assert(activitydelta/val > 0.0);
348  shiftval = solval + activitydelta/val;
349  assert(shiftval >= solval); /* may be equal due to numerical digit erasement in the subtraction */
350  if( SCIPvarIsIntegral(var) )
351  shiftval = SCIPfeasCeil(scip, shiftval);
352  ub = SCIPvarGetUbGlobal(var);
353  shiftval = MIN(shiftval, ub);
354  }
355  }
356 
357  if( SCIPisEQ(scip, shiftval, solval) )
358  continue;
359 
360  deltaobj = SCIPvarGetObj(var) * (shiftval - solval);
361  if( shiftscore < bestshiftscore || deltaobj < bestdeltaobj )
362  {
363  bestshiftscore = shiftscore;
364  bestdeltaobj = deltaobj;
365  *shiftvar = var;
366  *oldsolval = solval;
367  *newsolval = shiftval;
368  }
369  }
370  }
371 
372  return SCIP_OKAY;
373 }
374 
375 /** returns a fractional variable, that has most impact on rows in opposite direction, i.e. that is most crucial to
376  * fix in the other direction;
377  * if variables have equal impact, chooses the one with best objective value improvement in corresponding direction;
378  * shifting in a direction is forbidden, if this forces the objective value over the upper bound
379  */
380 static
382  SCIP* scip, /**< SCIP data structure */
383  SCIP_SOL* sol, /**< primal solution */
384  SCIP_Real minobj, /**< minimal objective value possible after shifting remaining fractional vars */
385  SCIP_VAR** lpcands, /**< fractional variables in LP */
386  int nlpcands, /**< number of fractional variables in LP */
387  SCIP_VAR** shiftvar, /**< pointer to store the shifting variable, returns NULL if impossible */
388  SCIP_Real* oldsolval, /**< old (fractional) solution value of shifting variable */
389  SCIP_Real* newsolval /**< new (shifted) solution value of shifting variable */
390  )
391 {
392  SCIP_VAR* var;
393  SCIP_Real solval;
394  SCIP_Real shiftval;
395  SCIP_Real obj;
396  SCIP_Real deltaobj;
397  SCIP_Real bestdeltaobj;
398  int maxnlocks;
399  int nlocks;
400  int v;
401 
402  assert(shiftvar != NULL);
403  assert(oldsolval != NULL);
404  assert(newsolval != NULL);
405 
406  /* select shifting variable */
407  maxnlocks = -1;
408  bestdeltaobj = SCIPinfinity(scip);
409  *shiftvar = NULL;
410  for( v = 0; v < nlpcands; ++v )
411  {
412  var = lpcands[v];
414 
415  solval = SCIPgetSolVal(scip, sol, var);
416  if( !SCIPisFeasIntegral(scip, solval) )
417  {
418  obj = SCIPvarGetObj(var);
419 
420  /* shifting down */
421  nlocks = SCIPvarGetNLocksUp(var);
422  if( nlocks >= maxnlocks )
423  {
424  shiftval = SCIPfeasFloor(scip, solval);
425  deltaobj = obj * (shiftval - solval);
426  if( (nlocks > maxnlocks || deltaobj < bestdeltaobj) && minobj - obj < SCIPgetCutoffbound(scip) )
427  {
428  maxnlocks = nlocks;
429  bestdeltaobj = deltaobj;
430  *shiftvar = var;
431  *oldsolval = solval;
432  *newsolval = shiftval;
433  }
434  }
435 
436  /* shifting up */
437  nlocks = SCIPvarGetNLocksDown(var);
438  if( nlocks >= maxnlocks )
439  {
440  shiftval = SCIPfeasCeil(scip, solval);
441  deltaobj = obj * (shiftval - solval);
442  if( (nlocks > maxnlocks || deltaobj < bestdeltaobj) && minobj + obj < SCIPgetCutoffbound(scip) )
443  {
444  maxnlocks = nlocks;
445  bestdeltaobj = deltaobj;
446  *shiftvar = var;
447  *oldsolval = solval;
448  *newsolval = shiftval;
449  }
450  }
451  }
452  }
453 
454  return SCIP_OKAY;
455 }
456 
457 /** adds a given value to the fractionality counters of the rows in which the given variable appears */
458 static
460  int* nfracsinrow, /**< array to store number of fractional variables per row */
461  SCIP_ROW** violrows, /**< array with currently violated rows */
462  int* violrowpos, /**< position of LP rows in violrows array */
463  int* nviolfracrows, /**< pointer to store the number of violated rows with fractional variables */
464  int nviolrows, /**< the number of currently violated rows (stays unchanged in this method) */
465  int nlprows, /**< number of rows in LP */
466  SCIP_VAR* var, /**< variable for which the counting should be updated */
467  int incval /**< value that should be added to the corresponding array entries */
468  )
469 {
470  SCIP_COL* col;
471  SCIP_ROW** rows;
472  int nrows;
473  int r;
474 
475  assert(incval != 0);
476  assert(nviolrows >= *nviolfracrows);
477  col = SCIPvarGetCol(var);
478  rows = SCIPcolGetRows(col);
479  nrows = SCIPcolGetNLPNonz(col);
480  for( r = 0; r < nrows; ++r )
481  {
482  int rowidx;
483  int theviolrowpos;
484  rowidx = SCIProwGetLPPos(rows[r]);
485  assert(0 <= rowidx && rowidx < nlprows);
486  nfracsinrow[rowidx] += incval;
487  assert(nfracsinrow[rowidx] >= 0);
488  theviolrowpos = violrowpos[rowidx];
489 
490  if( SCIProwIsLocal(rows[r]) )
491  continue;
492 
493  /* swap positions in violrows array if fractionality has changed to 0 */
494  if( theviolrowpos >= 0 )
495  {
496  /* first case: the number of fractional variables has become zero: swap row in violrows array to the
497  * second part, containing only violated rows without fractional variables
498  */
499  if( nfracsinrow[rowidx] == 0 )
500  {
501  assert(theviolrowpos <= *nviolfracrows - 1);
502 
503  /* nothing to do if row is already at the end of the first part, otherwise, swap it to the last position
504  * and decrease the counter */
505  if( theviolrowpos < *nviolfracrows - 1 )
506  {
507  violrows[theviolrowpos] = violrows[*nviolfracrows - 1];
508  violrows[*nviolfracrows - 1] = rows[r];
509 
510 
511  violrowpos[SCIProwGetLPPos(violrows[theviolrowpos])] = theviolrowpos;
512  violrowpos[rowidx] = *nviolfracrows - 1;
513  }
514  (*nviolfracrows)--;
515  }
516  /* second interesting case: the number of fractional variables was zero before, swap it with the first
517  * violated row without fractional variables
518  */
519  else if( nfracsinrow[rowidx] == incval )
520  {
521  assert(theviolrowpos >= *nviolfracrows);
522 
523  /* nothing to do if the row is exactly located at index *nviolfracrows */
524  if( theviolrowpos > *nviolfracrows )
525  {
526  violrows[theviolrowpos] = violrows[*nviolfracrows];
527  violrows[*nviolfracrows] = rows[r];
528 
529 
530  violrowpos[SCIProwGetLPPos(violrows[theviolrowpos])] = theviolrowpos;
531  violrowpos[rowidx] = *nviolfracrows;
532  }
533  (*nviolfracrows)++;
534  }
535  }
536  }
537 }
538 
539 
540 /*
541  * Callback methods
542  */
543 
544 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
545 static
546 SCIP_DECL_HEURCOPY(heurCopyShifting)
547 { /*lint --e{715}*/
548  assert(scip != NULL);
549  assert(heur != NULL);
550  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
551 
552  /* call inclusion method of primal heuristic */
554 
555  return SCIP_OKAY;
556 }
557 
558 
559 /** initialization method of primal heuristic (called after problem was transformed) */
560 static
561 SCIP_DECL_HEURINIT(heurInitShifting) /*lint --e{715}*/
562 { /*lint --e{715}*/
563  SCIP_HEURDATA* heurdata;
564 
565  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
566  assert(SCIPheurGetData(heur) == NULL);
567 
568  /* create heuristic data */
569  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
570  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
571  heurdata->lastlp = -1;
572  heurdata->randseed = 0;
573  SCIPheurSetData(heur, heurdata);
574 
575  return SCIP_OKAY;
576 }
577 
578 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
579 static
580 SCIP_DECL_HEUREXIT(heurExitShifting) /*lint --e{715}*/
581 { /*lint --e{715}*/
582  SCIP_HEURDATA* heurdata;
583 
584  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
585 
586  /* free heuristic data */
587  heurdata = SCIPheurGetData(heur);
588  assert(heurdata != NULL);
589  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
590  SCIPfreeMemory(scip, &heurdata);
591  SCIPheurSetData(heur, NULL);
592 
593  return SCIP_OKAY;
594 }
595 
596 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
597 static
598 SCIP_DECL_HEURINITSOL(heurInitsolShifting)
599 {
600  SCIP_HEURDATA* heurdata;
601 
602  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
603 
604  heurdata = SCIPheurGetData(heur);
605  assert(heurdata != NULL);
606  heurdata->lastlp = -1;
607 
608  return SCIP_OKAY;
609 }
610 
611 
612 /** execution method of primal heuristic */
613 static
614 SCIP_DECL_HEUREXEC(heurExecShifting) /*lint --e{715}*/
615 { /*lint --e{715}*/
616  SCIP_HEURDATA* heurdata;
617  SCIP_SOL* sol;
618  SCIP_VAR** lpcands;
619  SCIP_Real* lpcandssol;
620  SCIP_ROW** lprows;
621  SCIP_Real* activities;
622  SCIP_ROW** violrows;
623  SCIP_Real* nincreases;
624  SCIP_Real* ndecreases;
625  int* violrowpos;
626  int* nfracsinrow;
627  SCIP_Real increaseweight;
628  SCIP_Real obj;
629  SCIP_Real bestshiftval;
630  SCIP_Real minobj;
631  int nlpcands;
632  int nlprows;
633  int nvars;
634  int nfrac;
635  int nviolrows;
636  int nviolfracrows;
637  int nprevviolrows;
638  int minnviolrows;
639  int nnonimprovingshifts;
640  int c;
641  int r;
642  SCIP_Longint nlps;
643  SCIP_Longint ncalls;
644  SCIP_Longint nsolsfound;
645  SCIP_Longint nnodes;
646 
647  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
648  assert(scip != NULL);
649  assert(result != NULL);
650  assert(SCIPhasCurrentNodeLP(scip));
651 
652  *result = SCIP_DIDNOTRUN;
653 
654  /* only call heuristic, if an optimal LP solution is at hand */
656  return SCIP_OKAY;
657 
658  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
659  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
660  return SCIP_OKAY;
661 
662  /* get heuristic data */
663  heurdata = SCIPheurGetData(heur);
664  assert(heurdata != NULL);
665 
666  /* don't call heuristic, if we have already processed the current LP solution */
667  nlps = SCIPgetNLPs(scip);
668  if( nlps == heurdata->lastlp )
669  return SCIP_OKAY;
670  heurdata->lastlp = nlps;
671 
672  /* don't call heuristic, if it was not successful enough in the past */
673  ncalls = SCIPheurGetNCalls(heur);
674  nsolsfound = 10*SCIPheurGetNBestSolsFound(heur) + SCIPheurGetNSolsFound(heur);
675  nnodes = SCIPgetNNodes(scip);
676  if( nnodes % ((ncalls/100)/(nsolsfound+1)+1) != 0 )
677  return SCIP_OKAY;
678 
679  /* get fractional variables, that should be integral */
680  /* todo check if heuristic should include implicit integer variables for its calculations */
681  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, NULL) );
682  nfrac = nlpcands;
683 
684  /* only call heuristic, if LP solution is fractional */
685  if( nfrac == 0 )
686  return SCIP_OKAY;
687 
688  *result = SCIP_DIDNOTFIND;
689 
690  /* get LP rows */
691  SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
692 
693  SCIPdebugMessage("executing shifting heuristic: %d LP rows, %d fractionals\n", nlprows, nfrac);
694 
695  /* get memory for activities, violated rows, and row violation positions */
696  nvars = SCIPgetNVars(scip);
697  SCIP_CALL( SCIPallocBufferArray(scip, &activities, nlprows) );
698  SCIP_CALL( SCIPallocBufferArray(scip, &violrows, nlprows) );
699  SCIP_CALL( SCIPallocBufferArray(scip, &violrowpos, nlprows) );
700  SCIP_CALL( SCIPallocBufferArray(scip, &nfracsinrow, nlprows) );
701  SCIP_CALL( SCIPallocBufferArray(scip, &nincreases, nvars) );
702  SCIP_CALL( SCIPallocBufferArray(scip, &ndecreases, nvars) );
703  BMSclearMemoryArray(nfracsinrow, nlprows);
704  BMSclearMemoryArray(nincreases, nvars);
705  BMSclearMemoryArray(ndecreases, nvars);
706 
707  /* get the activities for all globally valid rows;
708  * the rows should be feasible, but due to numerical inaccuracies in the LP solver, they can be violated
709  */
710  nviolrows = 0;
711  for( r = 0; r < nlprows; ++r )
712  {
713  SCIP_ROW* row;
714 
715  row = lprows[r];
716  assert(SCIProwGetLPPos(row) == r);
717 
718  if( !SCIProwIsLocal(row) )
719  {
720  activities[r] = SCIPgetRowActivity(scip, row);
721  if( SCIPisFeasLT(scip, activities[r], SCIProwGetLhs(row))
722  || SCIPisFeasGT(scip, activities[r], SCIProwGetRhs(row)) )
723  {
724  violrows[nviolrows] = row;
725  violrowpos[r] = nviolrows;
726  nviolrows++;
727  }
728  else
729  violrowpos[r] = -1;
730  }
731  }
732 
733  nviolfracrows = 0;
734  /* calc the current number of fractional variables in rows */
735  for( c = 0; c < nlpcands; ++c )
736  addFracCounter(nfracsinrow, violrows, violrowpos, &nviolfracrows, nviolrows, nlprows, lpcands[c], +1);
737 
738  /* get the working solution from heuristic's local data */
739  sol = heurdata->sol;
740  assert(sol != NULL);
741 
742  /* copy the current LP solution to the working solution */
743  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
744 
745  /* calculate the minimal objective value possible after rounding fractional variables */
746  minobj = SCIPgetSolTransObj(scip, sol);
747  assert(minobj < SCIPgetCutoffbound(scip));
748  for( c = 0; c < nlpcands; ++c )
749  {
750  obj = SCIPvarGetObj(lpcands[c]);
751  bestshiftval = obj > 0.0 ? SCIPfeasFloor(scip, lpcandssol[c]) : SCIPfeasCeil(scip, lpcandssol[c]);
752  minobj += obj * (bestshiftval - lpcandssol[c]);
753  }
754 
755  /* try to shift remaining variables in order to become/stay feasible */
756  nnonimprovingshifts = 0;
757  minnviolrows = INT_MAX;
758  increaseweight = 1.0;
759  while( (nfrac > 0 || nviolrows > 0) && nnonimprovingshifts < MAXSHIFTINGS )
760  {
761  SCIP_VAR* shiftvar;
762  SCIP_Real oldsolval;
763  SCIP_Real newsolval;
764  SCIP_Bool oldsolvalisfrac;
765  int probindex;
766 
767  SCIPdebugMessage("shifting heuristic: nfrac=%d, nviolrows=%d, obj=%g (best possible obj: %g), cutoff=%g\n",
768  nfrac, nviolrows, SCIPgetSolOrigObj(scip, sol), SCIPretransformObj(scip, minobj),
770 
771  nprevviolrows = nviolrows;
772 
773  /* choose next variable to process:
774  * - if a violated row exists, shift a variable decreasing the violation, that has least impact on other rows
775  * - otherwise, shift a variable, that has strongest devastating impact on rows in opposite direction
776  */
777  shiftvar = NULL;
778  oldsolval = 0.0;
779  newsolval = 0.0;
780  if( nviolrows > 0 && (nfrac == 0 || nnonimprovingshifts < MAXSHIFTINGS-1) )
781  {
782  SCIP_ROW* row;
783  int rowidx;
784  int rowpos;
785  int direction;
786 
787  rowidx = -1;
788 
789  /* violated rows containing fractional variables are preferred; if such a row exists, choose the last one from the list
790  * (at position nviolfracrows - 1) because removing this row will cause one swapping operation less than other rows
791  */
792  if( nfrac > 0 )
793  {
794  if( nviolfracrows == 0 )
795  rowidx = -1;
796  else
797  rowidx = nviolfracrows - 1;
798  }
799 
800  /* there is no violated row containing a fractional variable, select a violated row uniformly at random */
801  if( rowidx == -1 )
802  rowidx = SCIPgetRandomInt(0, nviolrows-1, &heurdata->randseed);
803 
804  assert(0 <= rowidx && rowidx < nviolrows);
805  row = violrows[rowidx];
806  rowpos = SCIProwGetLPPos(row);
807  assert(0 <= rowpos && rowpos < nlprows);
808  assert(violrowpos[rowpos] == rowidx);
809  assert(nfracsinrow[rowpos] == 0 || rowidx == nviolfracrows - 1);
810 
811  SCIPdebugMessage("shifting heuristic: try to fix violated row <%s>: %g <= %g <= %g\n",
812  SCIProwGetName(row), SCIProwGetLhs(row), activities[rowpos], SCIProwGetRhs(row));
813  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, row, NULL) ) );
814 
815  /* get direction in which activity must be shifted */
816  assert(SCIPisFeasLT(scip, activities[rowpos], SCIProwGetLhs(row))
817  || SCIPisFeasGT(scip, activities[rowpos], SCIProwGetRhs(row)));
818  direction = SCIPisFeasLT(scip, activities[rowpos], SCIProwGetLhs(row)) ? +1 : -1;
819 
820  /* search a variable that can shift the activity in the necessary direction */
821  SCIP_CALL( selectShifting(scip, sol, row, activities[rowpos], direction,
822  nincreases, ndecreases, increaseweight, &shiftvar, &oldsolval, &newsolval) );
823  }
824 
825  if( shiftvar == NULL && nfrac > 0 )
826  {
827  SCIPdebugMessage("shifting heuristic: search rounding variable and try to stay feasible\n");
828  SCIP_CALL( selectEssentialRounding(scip, sol, minobj, lpcands, nlpcands, &shiftvar, &oldsolval, &newsolval) );
829  }
830 
831  /* check, whether shifting was possible */
832  if( shiftvar == NULL || SCIPisEQ(scip, oldsolval, newsolval) )
833  {
834  SCIPdebugMessage("shifting heuristic: -> didn't find a shifting variable\n");
835  break;
836  }
837 
838  SCIPdebugMessage("shifting heuristic: -> shift var <%s>[%g,%g], type=%d, oldval=%g, newval=%g, obj=%g\n",
839  SCIPvarGetName(shiftvar), SCIPvarGetLbGlobal(shiftvar), SCIPvarGetUbGlobal(shiftvar), SCIPvarGetType(shiftvar),
840  oldsolval, newsolval, SCIPvarGetObj(shiftvar));
841 
842  /* update row activities of globally valid rows */
843  SCIP_CALL( updateActivities(scip, activities, violrows, violrowpos, &nviolrows, &nviolfracrows, nfracsinrow, nlprows,
844  shiftvar, oldsolval, newsolval) );
845  if( nviolrows >= nprevviolrows )
846  nnonimprovingshifts++;
847  else if( nviolrows < minnviolrows )
848  {
849  minnviolrows = nviolrows;
850  nnonimprovingshifts = 0;
851  }
852 
853  /* store new solution value and decrease fractionality counter */
854  SCIP_CALL( SCIPsetSolVal(scip, sol, shiftvar, newsolval) );
855 
856  /* update fractionality counter and minimal objective value possible after shifting remaining variables */
857  oldsolvalisfrac = !SCIPisFeasIntegral(scip, oldsolval)
858  && (SCIPvarGetType(shiftvar) == SCIP_VARTYPE_BINARY || SCIPvarGetType(shiftvar) == SCIP_VARTYPE_INTEGER);
859  obj = SCIPvarGetObj(shiftvar);
860  if( (SCIPvarGetType(shiftvar) == SCIP_VARTYPE_BINARY || SCIPvarGetType(shiftvar) == SCIP_VARTYPE_INTEGER)
861  && oldsolvalisfrac )
862  {
863  assert(SCIPisFeasIntegral(scip, newsolval));
864  nfrac--;
865  nnonimprovingshifts = 0;
866  minnviolrows = INT_MAX;
867  addFracCounter(nfracsinrow, violrows, violrowpos, &nviolfracrows, nviolrows, nlprows, shiftvar, -1);
868 
869  /* the rounding was already calculated into the minobj -> update only if rounding in "wrong" direction */
870  if( obj > 0.0 && newsolval > oldsolval )
871  minobj += obj;
872  else if( obj < 0.0 && newsolval < oldsolval )
873  minobj -= obj;
874  }
875  else
876  {
877  /* update minimal possible objective value */
878  minobj += obj * (newsolval - oldsolval);
879  }
880 
881  /* update increase/decrease arrays */
882  if( !oldsolvalisfrac )
883  {
884  probindex = SCIPvarGetProbindex(shiftvar);
885  assert(0 <= probindex && probindex < nvars);
886  increaseweight *= WEIGHTFACTOR;
887  if( newsolval < oldsolval )
888  ndecreases[probindex] += increaseweight;
889  else
890  nincreases[probindex] += increaseweight;
891  if( increaseweight >= 1e+09 )
892  {
893  int i;
894 
895  for( i = 0; i < nvars; ++i )
896  {
897  nincreases[i] /= increaseweight;
898  ndecreases[i] /= increaseweight;
899  }
900  increaseweight = 1.0;
901  }
902  }
903 
904  SCIPdebugMessage("shifting heuristic: -> nfrac=%d, nviolrows=%d, obj=%g (best possible obj: %g)\n",
905  nfrac, nviolrows, SCIPgetSolOrigObj(scip, sol), SCIPretransformObj(scip, minobj));
906  }
907 
908  /* check, if the new solution is feasible */
909  if( nfrac == 0 && nviolrows == 0 )
910  {
911  SCIP_Bool stored;
912 
913  /* check solution for feasibility, and add it to solution store if possible
914  * neither integrality nor feasibility of LP rows has to be checked, because this is already
915  * done in the shifting heuristic itself; however, we better check feasibility of LP rows,
916  * because of numerical problems with activity updating
917  */
918  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, TRUE, &stored) );
919 
920  if( stored )
921  {
922  SCIPdebugMessage("found feasible shifted solution:\n");
923  SCIPdebug( SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) ) );
924  *result = SCIP_FOUNDSOL;
925  }
926  }
927 
928  /* free memory buffers */
929  SCIPfreeBufferArray(scip, &ndecreases);
930  SCIPfreeBufferArray(scip, &nincreases);
931  SCIPfreeBufferArray(scip, &nfracsinrow);
932  SCIPfreeBufferArray(scip, &violrowpos);
933  SCIPfreeBufferArray(scip, &violrows);
934  SCIPfreeBufferArray(scip, &activities);
935 
936  return SCIP_OKAY;
937 }
938 
939 
940 /*
941  * heuristic specific interface methods
942  */
943 
944 /** creates the shifting heuristic with infeasibility recovering and includes it in SCIP */
946  SCIP* scip /**< SCIP data structure */
947  )
948 {
949  SCIP_HEUR* heur;
950 
951  /* include primal heuristic */
952  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
954  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecShifting, NULL) );
955 
956  assert(heur != NULL);
957 
958  /* set non-NULL pointers to callback methods */
959  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyShifting) );
960  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitShifting) );
961  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitShifting) );
962  SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolShifting) );
963 
964  return SCIP_OKAY;
965 }
966 
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip.c:7330
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41180
static SCIP_DECL_HEUREXEC(heurExecShifting)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:32735
static void addFracCounter(int *nfracsinrow, SCIP_ROW **violrows, int *violrowpos, int *nviolfracrows, int nviolrows, int nlprows, SCIP_VAR *var, int incval)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41293
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10735
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16341
static SCIP_RETCODE selectEssentialRounding(SCIP *scip, SCIP_SOL *sol, SCIP_Real minobj, SCIP_VAR **lpcands, int nlpcands, SCIP_VAR **shiftvar, SCIP_Real *oldsolval, SCIP_Real *newsolval)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41256
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1273
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:7266
LP rounding heuristic that tries to recover from intermediate infeasibilities and shifts continuous v...
SCIP_Longint SCIPheurGetNSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1283
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41528
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:41640
#define HEUR_FREQ
Definition: heur_shifting.c:33
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:18914
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:18860
#define HEUR_FREQOFS
Definition: heur_shifting.c:34
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16965
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:34453
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, unsigned int timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip.c:7221
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:18849
static SCIP_DECL_HEURINITSOL(heurInitsolShifting)
#define FALSE
Definition: def.h:53
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34723
static void updateViolations(SCIP *scip, SCIP_ROW *row, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, SCIP_Real oldactivity, SCIP_Real newactivity)
Definition: heur_shifting.c:58
#define TRUE
Definition: def.h:52
#define SCIPdebug(x)
Definition: pub_message.h:74
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:41616
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38147
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26426
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34593
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20414
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16803
#define HEUR_DISPCHAR
Definition: heur_shifting.c:31
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26469
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:41652
SCIP_RETCODE SCIPincludeHeurShifting(SCIP *scip)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34676
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16532
#define HEUR_USESSUBSCIP
Definition: heur_shifting.c:37
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:18783
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41317
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20355
#define HEUR_PRIORITY
Definition: heur_shifting.c:32
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20426
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:18924
static SCIP_RETCODE updateActivities(SCIP *scip, SCIP_Real *activities, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, int nlprows, SCIP_VAR *var, SCIP_Real oldsolval, SCIP_Real newsolval)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:33612
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:19125
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:19023
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16669
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition: scip.c:26737
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3204
#define WEIGHTFACTOR
Definition: heur_shifting.c:40
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41245
#define SCIP_CALL(x)
Definition: def.h:263
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26341
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:18772
SCIP_Longint SCIPgetNLPs(SCIP *scip)
Definition: scip.c:37045
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:18973
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41554
#define HEUR_MAXDEPTH
Definition: heur_shifting.c:35
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
#define SCIP_Bool
Definition: def.h:50
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:34808
static SCIP_DECL_HEURINIT(heurInitShifting)
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34258
#define HEUR_NAME
Definition: heur_shifting.c:29
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7314
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41232
int SCIPgetRandomInt(int minrandval, int maxrandval, unsigned int *seedp)
Definition: misc.c:7695
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7298
#define SCIP_REAL_MAX
Definition: def.h:125
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16506
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1293
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20371
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16955
static SCIP_DECL_HEURCOPY(heurCopyShifting)
#define MAXSHIFTINGS
Definition: heur_shifting.c:39
static SCIP_RETCODE selectShifting(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *row, SCIP_Real rowactivity, int direction, SCIP_Real *nincreases, SCIP_Real *ndecreases, SCIP_Real increaseweight, SCIP_VAR **shiftvar, SCIP_Real *oldsolval, SCIP_Real *newsolval)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:18870
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16648
#define SCIP_Real
Definition: def.h:124
#define MIN(x, y)
Definition: memory.c:63
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip.c:28321
#define SCIP_Longint
Definition: def.h:109
#define HEUR_DESC
Definition: heur_shifting.c:30
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:19103
SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:28232
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1058
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:18684
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41305
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:18793
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3149
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:35827
static SCIP_DECL_HEUREXIT(heurExitShifting)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:36982
#define HEUR_TIMING
Definition: heur_shifting.c:36
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:35007
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:34217