Scippy

SCIP

Solving Constraint Integer Programs

heur_octane.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-2016 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_octane.c
17  * @brief octane primal heuristic based on Balas, Ceria, Dawande, Margot, and Pataki
18  * @author Timo Berthold
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 #include <math.h>
26 #include "scip/heur_octane.h"
27 
28 #define HEUR_NAME "octane"
29 #define HEUR_DESC "octane primal heuristic for pure {0;1}-problems based on Balas et al."
30 #define HEUR_DISPCHAR 'O'
31 #define HEUR_PRIORITY -1008000
32 #define HEUR_FREQ -1
33 #define HEUR_FREQOFS 0
34 #define HEUR_MAXDEPTH -1
35 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
36 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
37 
38 #define DEFAULT_FMAX 100 /**< {0,1}-points to be checked */
39 #define DEFAULT_FFIRST 10 /**< {0,1}-points to be generated at first */
40 #define DEFAULT_USEFRACSPACE TRUE /**< use heuristic for the space of fractional variables or for whole space? */
41 
42 /** primal heuristic data */
43 struct SCIP_HeurData
44 {
45  SCIP_SOL* sol; /**< working solution */
46  int f_max; /**< {0,1}-points to be checked */
47  int f_first; /**< {0,1}-points to be generated at first in order to check whether restart is necessary */
48  int lastrule; /**< last ray selection rule that was performed */
49  SCIP_Bool usefracspace; /**< use heuristic for the space of fractional variables or for the whole space? */
50  SCIP_Bool useobjray; /**< should the inner normal of the objective be used as one ray direction? */
51  SCIP_Bool useavgray; /**< should the average ray of the basic cone be used as one ray direction? */
52  SCIP_Bool usediffray; /**< should difference between root sol and current LP sol be used as one ray direction? */
53  SCIP_Bool useavgwgtray; /**< should the weighted average ray of the basic cone be used as one ray direction? */
54  SCIP_Bool useavgnbray; /**< should the average ray of the nonbasic cone be used as one ray direction? */
55  int nsuccess; /**< number of runs that produced at least one feasible solution */
56 };
57 
58 /*
59  * Local methods
60  */
61 
62 
63 /** tries to insert the facet obtained from facet i flipped in component j into the list of the fmax nearest facets */
64 static
66  SCIP* scip, /**< SCIP data structure */
67  SCIP_Bool** facets, /**< facets got so far */
68  SCIP_Real* lambda, /**< distances of the facets */
69  int i, /**< current facet */
70  int j, /**< component to flip */
71  int f_max, /**< maximal number of facets to create */
72  int nsubspacevars, /**< dimension of the fractional space */
73  SCIP_Real lam, /**< distance of the current facet */
74  int* nfacets /**< number of facets */
75  )
76 {
77  SCIP_Bool* lastfacet;
78  int k;
79 
80  assert(scip != NULL);
81  assert(facets != NULL);
82  assert(lambda != NULL);
83  assert(nfacets != NULL);
84 
85  if( SCIPisFeasLE(scip, lam, 0.0) || SCIPisFeasGE(scip, lam, lambda[f_max-1]) )
86  return;
87 
88  lastfacet = facets[f_max];
89 
90  /* shifting lam through lambda, lambda keeps increasingly sorted */
91  for( k = f_max; k > 0 && SCIPisFeasGT(scip, lambda[k-1], lam); --k )
92  {
93  lambda[k] = lambda[k-1];
94  facets[k] = facets[k-1];
95  }
96  assert(i < k && k < f_max );
97 
98  /* inserting new facet into list, new facet is facet at position i flipped in coordinate j, new distance lam */
99  facets[k] = lastfacet;
100  lambda[k] = lam;
101 
102  /*lint --e{866}*/
103  BMScopyMemoryArray(facets[k], facets[i], nsubspacevars);
104  facets[k][j] = !facets[k][j];
105  (*nfacets)++;
106 }
107 
108 /** constructs a solution from a given facet paying attention to the transformations made at the beginning of OCTANE */
109 static
111  SCIP* scip, /**< SCIP data structure */
112  SCIP_Bool* facet, /**< current facet */
113  SCIP_SOL* sol, /**< solution to create */
114  SCIP_Bool* sign, /**< marker for retransformation */
115  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
116  int nsubspacevars /**< dimension of fractional space */
117  )
118 {
119  int v;
120 
121  assert(scip != NULL);
122  assert(facet != NULL);
123  assert(sol != NULL);
124  assert(sign != NULL);
125  assert(subspacevars != NULL);
126 
127  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
128  for( v = nsubspacevars - 1; v >= 0; --v )
129  {
130  /* after permutation, a variable should be set to 1, iff there was no reflection in this coordinate and the hit
131  * facet has coordinate + or there was a reflection and the facet has coordinate - */
132  if( facet[v] == sign[v] )
133  {
134  SCIP_CALL( SCIPsetSolVal(scip, sol, subspacevars[v], 1.0) );
135  }
136  else
137  {
138  SCIP_CALL( SCIPsetSolVal(scip, sol, subspacevars[v], 0.0) );
139  }
140  }
141 
142  return SCIP_OKAY;
143 }
144 
145 /** generates the direction of the shooting ray as the inner normal of the objective function */
146 static
148  SCIP* scip, /**< SCIP data structure */
149  SCIP_Real* raydirection, /**< shooting ray */
150  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
151  int nsubspacevars /**< dimension of fractional space */
152  )
153 {
154  int v;
155 
156  assert(scip != NULL);
157  assert(raydirection != NULL);
158  assert(subspacevars != NULL);
159 
160  for( v = nsubspacevars - 1; v >= 0; --v )
161  raydirection[v] = SCIPvarGetObj(subspacevars[v]);
162  return SCIP_OKAY;
163 }
164 
165 /** generates the direction of the shooting ray as the difference between the root and the current LP solution */
166 static
168  SCIP* scip, /**< SCIP data structure */
169  SCIP_Real* raydirection, /**< shooting ray */
170  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
171  int nsubspacevars /**< dimension of fractional space */
172  )
173 {
174  int v;
175 
176  assert(scip != NULL);
177  assert(raydirection != NULL);
178  assert(subspacevars != NULL);
179 
180  for( v = nsubspacevars - 1; v >= 0; --v )
181  raydirection[v] = SCIPvarGetLPSol(subspacevars[v]) - SCIPvarGetRootSol(subspacevars[v]);
182 
183  return SCIP_OKAY;
184 }
185 
186 
187 /** generates the direction of the shooting ray as the average of the extreme rays of the basic cone */
188 static
190  SCIP* scip, /**< SCIP data structure */
191  SCIP_Real* raydirection, /**< shooting ray */
192  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
193  int nsubspacevars, /**< dimension of fractional space */
194  SCIP_Bool weighted /**< should the rays be weighted? */
195  )
196 {
197  SCIP_ROW** rows;
198  SCIP_Real** tableaurows;
199  SCIP_Real* rownorm;
200  SCIP_Real rowweight;
201  int** tableaurowinds; /* indices of non-zero entries */
202  int* ntableaurowinds; /* number of non-zero entries */
203  SCIP_Bool* usedrowids = NULL; /* visited row indices */
204  int* rowids; /* row indices */
205  int nrowids = 0; /* number of row indices */
206  int tableaurowind;
207  int nrows;
208  int i;
209  int j;
210  int sparse = -1; /* used to check that either all information is sparse or not sparse */
211 
212  assert(scip != NULL);
213  assert(raydirection != NULL);
214  assert(subspacevars != NULL);
215  assert(nsubspacevars > 0);
216 
217  /* get data */
218  SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
219  assert(nrows > 0);
220  assert(rows != NULL);
221 
222  /* allocate memory */
223  SCIP_CALL( SCIPallocBufferArray(scip, &tableaurows, nsubspacevars) );
224  SCIP_CALL( SCIPallocBufferArray(scip, &tableaurowinds, nsubspacevars) );
225  SCIP_CALL( SCIPallocBufferArray(scip, &ntableaurowinds, nsubspacevars) );
226  for( j = nsubspacevars - 1; j >= 0; --j )
227  {
228  /*lint --e{866}*/
229  SCIP_CALL( SCIPallocBufferArray(scip, &tableaurows[j], nrows) );
230  SCIP_CALL( SCIPallocBufferArray(scip, &tableaurowinds[j], nrows) );
231  }
232 
233  SCIP_CALL( SCIPallocBufferArray(scip, &rownorm, nrows) );
234  BMSclearMemoryArray(rownorm, nrows);
235 
236  /* get the relevant columns of the simplex tableau */
237  for( j = nsubspacevars - 1; j >= 0; --j )
238  {
239  assert(SCIPcolGetLPPos(SCIPvarGetCol(subspacevars[j])) >= 0);
240  SCIP_CALL( SCIPgetLPBInvACol(scip, SCIPcolGetLPPos(SCIPvarGetCol(subspacevars[j])), tableaurows[j], tableaurowinds[j], &ntableaurowinds[j]) );
241 
242  if( ntableaurowinds[j] == -1 )
243  {
244  assert(sparse == 0 || sparse == -1);
245  sparse = 0;
246 
247  for( i = nrows - 1; i >= 0; --i )
248  rownorm[i] += tableaurows[j][i] * tableaurows[j][i];
249  }
250  else
251  {
252  assert(sparse == 1 || sparse == -1);
253  sparse = 1;
254 
255  /* allocate temporary memory */
256  if( usedrowids == NULL )
257  {
258  SCIP_CALL( SCIPallocBufferArray(scip, &rowids, nrows) );
259  SCIP_CALL( SCIPallocBufferArray(scip, &usedrowids, nrows) );
260  BMSclearMemoryArray(usedrowids, nrows);
261  }
262 
263  for( i = ntableaurowinds[j] - 1; i >= 0; --i )
264  {
265  tableaurowind = tableaurowinds[j][i];
266  rownorm[tableaurowind] += tableaurows[j][tableaurowind] * tableaurows[j][tableaurowind];
267  if( !usedrowids[tableaurowind] )
268  {
269  usedrowids[tableaurowind] = TRUE;
270  rowids[nrowids] = tableaurowind; /*lint !e644*/
271  ++nrowids;
272  assert(nrowids <= nrows);
273  }
274  }
275  }
276  }
277 
278  /* compute ray direction (dense) */
279  if( sparse == 0 )
280  {
281  /* take average over all rows of the tableau */
282  for( i = nrows - 1; i >= 0; --i )
283  {
284  if( SCIPisFeasZero(scip, rownorm[i]) )
285  continue;
286  else
287  rownorm[i] = SQRT(rownorm[i]);
288 
289  rowweight = 0.0;
290  if( weighted )
291  {
292  rowweight = SCIProwGetDualsol(rows[i]);
293  if( SCIPisFeasZero(scip, rowweight) )
294  continue;
295  }
296  else
297  rowweight = 1.0;
298 
299  for( j = nsubspacevars - 1; j >= 0; --j )
300  {
301  raydirection[j] += tableaurows[j][i] / (rownorm[i] * rowweight);
302  assert(SCIP_REAL_MIN <= raydirection[j] && raydirection[j] <= SCIP_REAL_MAX);
303  }
304  }
305  }
306  /* compute ray direction (sparse) */
307  else
308  {
309  SCIP_Real* rowweights;
310  int r;
311  int k;
312 
313  assert(usedrowids != NULL);
314  assert(rowids != NULL);
315  assert(sparse == 1);
316  assert(0 <= nrowids && nrowids <= nrows);
317 
318  SCIP_CALL( SCIPallocBufferArray(scip, &rowweights, nrows) );
319 
320  /* compute norms of important rows and rowweights */
321  for( i = nrowids - 1; i >= 0; --i )
322  {
323  r = rowids[i];
324  assert(0 <= r && r < nrows);
325  assert(usedrowids[r]);
326 
327  if( SCIPisFeasZero(scip, rownorm[r]) )
328  {
329  usedrowids[r] = FALSE;
330  --nrowids;
331  continue;
332  }
333  else
334  rownorm[r] = SQRT(rownorm[r]);
335 
336  if( weighted )
337  {
338  rowweights[r] = SCIProwGetDualsol(rows[r]);
339  if( SCIPisFeasZero(scip, rowweights[r]) )
340  {
341  usedrowids[r] = FALSE;
342  --nrowids;
343  continue;
344  }
345  }
346  else
347  rowweights[r] = 1.0;
348  }
349 
350  if( nrowids > 0 )
351  {
352  /* take average over all rows of the tableau */
353  for( j = nsubspacevars - 1; j >= 0; --j )
354  {
355  for( k = ntableaurowinds[j] - 1; k >= 0; --k )
356  {
357  tableaurowind = tableaurowinds[j][k];
358 
359  if( usedrowids[tableaurowind] )
360  {
361  raydirection[j] += tableaurows[j][tableaurowind] / (rownorm[tableaurowind] * rowweights[tableaurowind]);
362  assert(SCIP_REAL_MIN <= raydirection[j] && raydirection[j] <= SCIP_REAL_MAX);
363  }
364  }
365  }
366  }
367 
368  SCIPfreeBufferArray(scip, &rowweights);
369  SCIPfreeBufferArray(scip, &usedrowids);
370  SCIPfreeBufferArray(scip, &rowids);
371  }
372  assert(usedrowids == NULL);
373 
374  /* free memory */
375  SCIPfreeBufferArray(scip, &rownorm);
376  for( j = 0; j < nsubspacevars; ++j )
377  {
378  SCIPfreeBufferArray(scip, &tableaurowinds[j]);
379  SCIPfreeBufferArray(scip, &tableaurows[j]);
380  }
381  SCIPfreeBufferArray(scip, &ntableaurowinds);
382  SCIPfreeBufferArray(scip, &tableaurowinds);
383  SCIPfreeBufferArray(scip, &tableaurows);
384 
385  return SCIP_OKAY;
386 }
387 
388 
389 /** generates the direction of the shooting ray as the average of the normalized non-basic vars and rows */
390 static
392  SCIP* scip, /**< SCIP data structure */
393  SCIP_Real* raydirection, /**< shooting ray */
394  int* fracspace, /**< index set of fractional variables */
395  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
396  int nsubspacevars /**< dimension of fractional space */
397  )
398 {
399  SCIP_ROW** rows;
400  SCIP_COL** cols;
401  int nrows;
402  int ncols;
403  int i;
404 
405  assert(scip != NULL);
406  assert(raydirection != NULL);
407  assert(fracspace != NULL);
408  assert(subspacevars != NULL);
409 
410  SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
411  SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
412 
413  /* add up non-basic variables */
414  for( i = nsubspacevars - 1; i >= 0; --i )
415  {
416  SCIP_Real solval;
417 
418  solval = SCIPvarGetLPSol(subspacevars[i]);
419 
420  if( SCIPisFeasEQ(scip, solval, SCIPvarGetLbLocal(subspacevars[i])) )
421  raydirection[i] = +1.0;
422  else if( SCIPisFeasEQ(scip, solval, SCIPvarGetUbLocal(subspacevars[i])) )
423  raydirection[i] = -1.0;
424  else
425  raydirection[i] = 0.0;
426  }
427 
428  /* add up non-basic rows */
429  for( i = nrows - 1; i >= 0; --i )
430  {
431  SCIP_Real dualsol;
432  SCIP_Real factor;
433  SCIP_Real* coeffs;
434  SCIP_Real rownorm;
435  int j;
436  int nnonz;
437 
438  dualsol = SCIProwGetDualsol(rows[i]);
439  if( SCIPisFeasPositive(scip, dualsol) )
440  factor = 1.0;
441  else if( SCIPisFeasNegative(scip, dualsol) )
442  factor = -1.0;
443  else
444  continue;
445 
446  /* get the row's data */
447  coeffs = SCIProwGetVals(rows[i]);
448  cols = SCIProwGetCols(rows[i]);
449 
450  nnonz = SCIProwGetNNonz(rows[i]);
451 
452  rownorm = 0.0;
453  for( j = nnonz - 1; j >= 0; --j )
454  {
455  SCIP_VAR* var;
456  var = SCIPcolGetVar(cols[j]);
457  if( fracspace[SCIPvarGetProbindex(var)] >= 0 )
458  rownorm += coeffs[j] * coeffs[j];
459  }
460 
461  if( SCIPisFeasZero(scip,rownorm) )
462  continue;
463  else
464  {
465  assert(rownorm > 0);
466  rownorm = SQRT(rownorm);
467  }
468 
469  for( j = nnonz - 1; j >= 0; --j )
470  {
471  SCIP_VAR* var;
472  int f;
473 
474  var = SCIPcolGetVar(cols[j]);
475  f = fracspace[SCIPvarGetProbindex(var)];
476 
477  if( f >= 0 )
478  {
479  raydirection[f] += factor * coeffs[j] / rownorm;
480  assert(SCIP_REAL_MIN <= raydirection[f] && raydirection[f] <= SCIP_REAL_MAX);
481  }
482  }
483  }
484  return SCIP_OKAY;
485 }
486 
487 /** generates the starting point for the shooting ray in original coordinates */
488 static
490  SCIP* scip, /**< SCIP data structure */
491  SCIP_Real* rayorigin, /**< origin of the shooting ray */
492  SCIP_VAR** subspacevars, /**< pointer to fractional space variables */
493  int nsubspacevars /**< dimension of fractional space */
494  )
495 {
496  int v;
497 
498  assert(scip != NULL);
499  assert(rayorigin != NULL);
500  assert(subspacevars != NULL);
501 
502  for( v = nsubspacevars - 1; v >= 0; --v )
503  rayorigin[v] = SCIPvarGetLPSol(subspacevars[v]);
504 
505  return SCIP_OKAY;
506 }
507 
508 /** translates the inner point of the LP to an inner point rayorigin of the unit hyper octahedron and
509  * transforms raydirection and rayorigin by reflections stored in sign
510  */
511 static
513  SCIP_Real* rayorigin, /**< origin of the shooting ray */
514  SCIP_Real* raydirection, /**< direction of the shooting ray */
515  SCIP_Bool* sign, /**< marker for flipped coordinates */
516  int nsubspacevars /**< dimension of fractional space */
517  )
518 {
519  int v;
520 
521  assert(rayorigin != NULL);
522  assert(raydirection != NULL);
523  assert(sign != NULL);
524 
525  for( v = nsubspacevars - 1; v >= 0; --v )
526  {
527  /* if raydirection[v] is negative, flip its sign */
528  if( raydirection[v] < 0 )
529  {
530  sign[v] = FALSE;
531  raydirection[v] *= -1.0;
532  rayorigin[v] *= -1.0; /* flip starting point in the same way like raydirection */
533  }
534  else
535  sign[v] = TRUE;
536  }
537 }
538 
539 /** generates all facets, from which facet i could be obtained by a decreasing + to - flip
540  * or a nonincreasing - to + flip and tests whether they are among the fmax nearest ones
541  */
542 static
544  SCIP* scip, /**< SCIP data structure */
545  SCIP_Bool** facets, /**< facets got so far */
546  SCIP_Real* lambda, /**< distances of the facets */
547  SCIP_Real* rayorigin, /**< origin of the shooting ray */
548  SCIP_Real* raydirection, /**< direction of the shooting ray */
549  SCIP_Real* negquotient, /**< array by which coordinates are sorted */
550  int nsubspacevars, /**< dimension of fractional space */
551  int f_max, /**< maximal number of facets to create */
552  int i, /**< current facet */
553  int* nfacets /**< number of facets */
554  )
555 {
556  SCIP_Real p;
557  SCIP_Real q;
558  SCIP_Real lam;
559  int minplus;
560  int j;
561 
562  assert(scip != NULL);
563  assert(facets != NULL);
564  assert(facets[i] != NULL);
565  assert(lambda != NULL);
566  assert(rayorigin != NULL);
567  assert(raydirection != NULL);
568  assert(negquotient != NULL);
569  assert(nfacets != NULL);
570  assert(0 <= i && i < f_max);
571 
572  /* determine the p and q values of the next facet to fix as a closest one */
573  p = 0.5 * nsubspacevars;
574  q = 0.0;
575  for( j = nsubspacevars - 1; j >= 0; --j )
576  {
577  if( facets[i][j] )
578  {
579  p -= rayorigin[j];
580  q += raydirection[j];
581  }
582  else
583  {
584  p += rayorigin[j];
585  q -= raydirection[j];
586  }
587  }
588 
589  /* get the first + entry of the facet */
590  minplus = -1;
591  for( j = 0; j < nsubspacevars; ++j )
592  {
593  if( facets[i][j] )
594  {
595  minplus = j;
596  break;
597  }
598  }
599 
600  /* facet (- - ... -) cannot be hit, because raydirection >= 0 */
601  assert(minplus >= 0);
602  assert(q != 0.0);
603  assert(SCIPisFeasEQ(scip, lambda[i], p/q));
604  assert(lambda[i] >= 0.0);
605 
606  /* reverse search for facets from which the actual facet can be got by a single, decreasing + to - flip */
607  /* a facet will be inserted into the queue, iff it is one of the fmax closest ones already found */
608  for( j = 0; j < nsubspacevars && !facets[i][j] && SCIPisFeasGT(scip, negquotient[j], lambda[i]); ++j )
609  {
610  if( SCIPisFeasPositive(scip, q + 2*raydirection[j]) )
611  {
612  lam = (p - 2*rayorigin[j]) / (q + 2*raydirection[j]);
613  tryToInsert(scip, facets, lambda, i, j, f_max, nsubspacevars, lam, nfacets);
614  }
615  }
616 
617  /* reverse search for facets from which the actual facet can be got by a single, nonincreasing - to + flip */
618  /* a facet will be inserted into the queue, iff it is one of the fmax closest ones already found */
619  for( j = nsubspacevars - 1; j >= 0 && facets[i][j] && SCIPisFeasLE(scip, negquotient[j], lambda[i]); --j )
620  {
621  if( SCIPisFeasPositive(scip, q - 2*raydirection[j]) )
622  {
623  lam = (p + 2*rayorigin[j]) / (q - 2*raydirection[j]);
624  if( negquotient[minplus] <= lam )
625  tryToInsert(scip, facets, lambda, i, j, f_max, nsubspacevars, lam, nfacets);
626  }
627  }
628 #ifndef NDEBUG
629  for( j = 1; j < f_max; j++)
630  assert(SCIPisFeasGE(scip, lambda[j], lambda[j-1]));
631 #endif
632 }
633 
634 /** tests, whether an array is completely zero */
635 static
637  SCIP* scip, /**< SCIP data structure */
638  SCIP_Real* raydirection, /**< array to be checked */
639  int nsubspacevars /**< size of array */
640  )
641 {
642  int v;
643  SCIP_Bool iszero;
644 
645  assert(scip != NULL);
646  assert(raydirection != NULL);
647  iszero = TRUE;
648  for( v = nsubspacevars - 1; v >= 0; --v )
649  {
650  if( !SCIPisFeasZero(scip, raydirection[v]/100) )
651  iszero = FALSE;
652  else
653  raydirection[v] = 0.0;
654  }
655  return iszero;
656 }
657 
658 
659 /*
660  * Callback methods of primal heuristic
661  */
662 
663 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
664 static
665 SCIP_DECL_HEURCOPY(heurCopyOctane)
666 { /*lint --e{715}*/
667  assert(scip != NULL);
668  assert(heur != NULL);
669  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
670 
671  /* call inclusion method of primal heuristic */
673 
674  return SCIP_OKAY;
675 }
676 
677 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
678 static
679 SCIP_DECL_HEURFREE(heurFreeOctane)
680 { /*lint --e{715}*/
681  SCIP_HEURDATA* heurdata;
682 
683  assert(heur != NULL);
684  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
685  assert(scip != NULL);
686 
687  /* free heuristic data */
688  heurdata = SCIPheurGetData(heur);
689  assert(heurdata != NULL);
690  SCIPfreeMemory(scip, &heurdata);
691  SCIPheurSetData(heur, NULL);
692 
693  return SCIP_OKAY;
694 }
695 
696 
697 /** initialization method of primal heuristic (called after problem was transformed) */
698 static
699 SCIP_DECL_HEURINIT(heurInitOctane)
700 { /*lint --e{715}*/
701  SCIP_HEURDATA* heurdata;
702 
703  assert(heur != NULL);
704  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
705 
706  /* get heuristic data */
707  heurdata = SCIPheurGetData(heur);
708  assert(heurdata != NULL);
709 
710  /* create working solution */
711  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
712 
713  /* initialize data */
714  heurdata->lastrule = 0;
715  heurdata->nsuccess = 0;
716 
717  return SCIP_OKAY;
718 }
719 
720 
721 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
722 
723 static
724 SCIP_DECL_HEUREXIT(heurExitOctane)
725 { /*lint --e{715}*/
726  SCIP_HEURDATA* heurdata;
727 
728  assert(heur != NULL);
729  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
730 
731  /* get heuristic data */
732  heurdata = SCIPheurGetData(heur);
733  assert(heurdata != NULL);
734 
735  /* free working solution */
736  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
737 
738  return SCIP_OKAY;
739 }
740 
741 
742 /** execution method of primal heuristic */
743 static
744 SCIP_DECL_HEUREXEC(heurExecOctane)
745 { /*lint --e{715}*/
746  SCIP_HEURDATA* heurdata;
747  SCIP_SOL* sol;
748  SCIP_SOL** first_sols; /* stores the first ffirst sols in order to check for common violation of a row */
749 
750  SCIP_VAR** vars; /* the variables of the problem */
751  SCIP_VAR** fracvars; /* variables, that are fractional in current LP solution */
752  SCIP_VAR** subspacevars; /* the variables on which the search is performed. Either coinciding with vars or with the
753  * space of all fractional variables of the current LP solution */
754 
755  SCIP_Real p; /* n/2 - <delta,x> ( for some facet delta ) */
756  SCIP_Real q; /* <delta,a> */
757 
758  SCIP_Real* rayorigin; /* origin of the ray, vector x in paper */
759  SCIP_Real* raydirection; /* direction of the ray, vector a in paper */
760  SCIP_Real* negquotient; /* negated quotient of rayorigin and raydirection, vector v in paper */
761  SCIP_Real* lambda; /* stores the distance of the facets (s.b.) to the origin of the ray */
762 
763  SCIP_Bool usefracspace; /* determines whether the search concentrates on fractional variables and fixes integer ones */
764  SCIP_Bool cons_viol; /* used for checking whether a linear constraint is violated by one of the possible solutions */
765  SCIP_Bool success;
766  SCIP_Bool* sign; /* signature of the direction of the ray */
767  SCIP_Bool** facets; /* list of extended facets */
768 
769  int nvars; /* number of variables */
770  int nbinvars; /* number of 0-1-variables */
771  int nfracvars; /* number of fractional variables in current LP solution */
772  int nsubspacevars; /* dimension of the subspace on which the search is performed */
773  int nfacets; /* number of facets hidden by the ray that where already found */
774  int i; /* counter */
775  int j; /* counter */
776  int f_max; /* {0,1}-points to be checked */
777  int f_first; /* {0,1}-points to be generated at first in order to check whether a restart is necessary */
778  int r; /* counter */
779  int firstrule;
780 
781  int* perm; /* stores the way in which the coordinates were permuted */
782  int* fracspace; /* maps the variables of the subspace to the original variables */
783 
784  assert(heur != NULL);
785  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
786  assert(scip != NULL);
787  assert(result != NULL);
788  assert(SCIPhasCurrentNodeLP(scip));
789 
790  *result = SCIP_DELAYED;
791 
792  /* do not call heuristic of node was already detected to be infeasible */
793  if( nodeinfeasible )
794  return SCIP_OKAY;
795 
796  /* only call heuristic, if an optimal LP solution is at hand */
798  return SCIP_OKAY;
799 
800  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
802  return SCIP_OKAY;
803 
804  *result = SCIP_DIDNOTRUN;
805 
806  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
807 
808  /* OCTANE is for use in 0-1 programs only */
809  if( nvars != nbinvars )
810  return SCIP_OKAY;
811 
812  /* get heuristic's data */
813  heurdata = SCIPheurGetData(heur);
814  assert( heurdata != NULL );
815 
816  /* don't call heuristic, if it was not successful enough in the past */
817  /*lint --e{647}*/
818  if( SCIPgetNNodes(scip) % (SCIPheurGetNCalls(heur) / (100 * SCIPheurGetNBestSolsFound(heur) + 10*heurdata->nsuccess + 1) + 1) != 0 )
819  return SCIP_OKAY;
820 
821  SCIP_CALL( SCIPgetLPBranchCands(scip, &fracvars, NULL, NULL, &nfracvars, NULL, NULL) );
822 
823  /* don't use integral starting points */
824  if( nfracvars == 0 )
825  return SCIP_OKAY;
826 
827  /* get working pointers from heurdata */
828  sol = heurdata->sol;
829  assert( sol != NULL );
830  f_max = heurdata->f_max;
831  f_first = heurdata->f_first;
832  usefracspace = heurdata->usefracspace;
833 
834  SCIP_CALL( SCIPallocBufferArray(scip, &fracspace, nvars) );
835 
836  /* determine the space one which OCTANE should work either as the whole space or as the space of fractional variables */
837  if( usefracspace )
838  {
839  nsubspacevars = nfracvars;
840  SCIP_CALL( SCIPallocBufferArray(scip, &subspacevars, nsubspacevars) );
841  BMScopyMemoryArray(subspacevars, fracvars, nsubspacevars);
842  for( i = nvars - 1; i >= 0; --i )
843  fracspace[i] = -1;
844  for( i = nsubspacevars - 1; i >= 0; --i )
845  fracspace[SCIPvarGetProbindex(subspacevars[i])] = i;
846  }
847  else
848  {
849  int currentindex;
850 
851  nsubspacevars = nvars;
852  SCIP_CALL( SCIPallocBufferArray(scip, &subspacevars, nsubspacevars) );
853 
854  /* only copy the variables which are in the current LP */
855  currentindex = 0;
856  for( i = 0; i < nvars; ++i )
857  {
858  if( SCIPcolGetLPPos(SCIPvarGetCol(vars[i])) >= 0 )
859  {
860  subspacevars[currentindex] = vars[i];
861  fracspace[i] = currentindex;
862  ++currentindex;
863 
864  }
865  else
866  {
867  fracspace[i] = -1;
868  --nsubspacevars;
869  }
870  }
871  }
872 
873  /* nothing to do for empty search space */
874  if( nsubspacevars == 0 )
875  return SCIP_OKAY;
876 
877  assert(0 < nsubspacevars && nsubspacevars <= nvars);
878 
879  for( i = 0; i < nsubspacevars; i++)
880  assert(fracspace[SCIPvarGetProbindex(subspacevars[i])] == i);
881 
882  /* at most 2^(n-1) facets can be hit */
883  if( nsubspacevars < 30 )
884  {
885  /*lint --e{701}*/
886  assert(f_max > 0);
887  f_max = MIN(f_max, 1 << (nsubspacevars - 1) );
888  }
889 
890  f_first = MIN(f_first, f_max);
891 
892  /* memory allocation */
893  SCIP_CALL( SCIPallocBufferArray(scip, &rayorigin, nsubspacevars) );
894  SCIP_CALL( SCIPallocBufferArray(scip, &raydirection, nsubspacevars) );
895  SCIP_CALL( SCIPallocBufferArray(scip, &negquotient, nsubspacevars) );
896  SCIP_CALL( SCIPallocBufferArray(scip, &sign, nsubspacevars) );
897  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nsubspacevars) );
898  SCIP_CALL( SCIPallocBufferArray(scip, &lambda, f_max + 1) );
899  SCIP_CALL( SCIPallocBufferArray(scip, &facets, f_max + 1) );
900 
901  /* clear raydirection array first for not accidentally using it uninitialized */
902  BMSclearMemoryArray(raydirection, nsubspacevars);
903 
904  for( i = f_max; i >= 0; --i )
905  {
906  /*lint --e{866}*/
907  SCIP_CALL( SCIPallocBufferArray(scip, &facets[i], nsubspacevars) );
908  }
909  SCIP_CALL( SCIPallocBufferArray(scip, &first_sols, f_first) );
910 
911  *result = SCIP_DIDNOTFIND;
912 
913  /* starting OCTANE */
914  SCIPdebugMessage("run Octane heuristic on %s variables, which are %d vars, generate at most %d facets, using rule number %d\n",
915  usefracspace ? "fractional" : "all", nsubspacevars, f_max, (heurdata->lastrule+1)%5);
916 
917  /* generate starting point in original coordinates */
918  SCIP_CALL( generateStartingPoint(scip, rayorigin, subspacevars, nsubspacevars) );
919  for( i = nsubspacevars - 1; i >= 0; --i )
920  rayorigin[i] -= 0.5;
921 
922  firstrule = heurdata->lastrule;
923  ++firstrule;
924  for( r = firstrule; r <= firstrule + 10 && !SCIPisStopped(scip); r++ )
925  {
926  SCIP_ROW** rows;
927  int nrows;
928 
929  /* generate shooting ray in original coordinates by certain rules */
930  switch(r % 5)
931  {
932  case 1:
933  if( heurdata->useavgnbray )
934  {
935  SCIP_CALL( generateAverageNBRay(scip, raydirection, fracspace, subspacevars, nsubspacevars) );
936  }
937  break;
938  case 2:
939  if( heurdata->useobjray )
940  {
941  SCIP_CALL( generateObjectiveRay(scip, raydirection, subspacevars, nsubspacevars) );
942  }
943  break;
944  case 3:
945  if( heurdata->usediffray )
946  {
947  SCIP_CALL( generateDifferenceRay(scip, raydirection, subspacevars, nsubspacevars) );
948  }
949  break;
950  case 4:
951  if( heurdata->useavgwgtray && SCIPisLPSolBasic(scip) )
952  {
953  SCIP_CALL( generateAverageRay(scip, raydirection, subspacevars, nsubspacevars, TRUE) );
954  }
955  break;
956  case 0:
957  if( heurdata->useavgray && SCIPisLPSolBasic(scip) )
958  {
959  SCIP_CALL( generateAverageRay(scip, raydirection, subspacevars, nsubspacevars, FALSE) );
960  }
961  break;
962  default:
963  SCIPerrorMessage("invalid ray rule identifier\n");
964  SCIPABORT();
965  }
966 
967  /* there must be a feasible direction for the shooting ray */
968  if( isZero(scip, raydirection, nsubspacevars) )
969  continue;
970 
971  /* transform coordinates such that raydirection >= 0 */
972  flipCoords(rayorigin, raydirection, sign, nsubspacevars);
973 
974  for( i = f_max - 1; i >= 0; --i)
975  lambda[i] = SCIPinfinity(scip);
976 
977  /* calculate negquotient, initialize perm, facets[0], p, and q */
978  p = 0.5 * nsubspacevars;
979  q = 0.0;
980  for( i = nsubspacevars - 1; i >= 0; --i )
981  {
982  /* calculate negquotient, the ratio of rayorigin and raydirection, paying special attention to the case raydirection[i] == 0 */
983  if( SCIPisFeasZero(scip, raydirection[i]) )
984  {
985  if( rayorigin[i] < 0 )
986  negquotient[i] = SCIPinfinity(scip);
987  else
988  negquotient[i] = -SCIPinfinity(scip);
989  }
990  else
991  negquotient[i] = - (rayorigin[i] / raydirection[i]);
992 
993  perm[i] = i;
994 
995  /* initialization of facets[0] to the all-one facet with p and q its characteristic values */
996  facets[0][i] = TRUE;
997  p -= rayorigin[i];
998  q += raydirection[i];
999  }
1000 
1001  assert(SCIPisPositive(scip, q));
1002 
1003  /* resort the coordinates in nonincreasing order of negquotient */
1004  SCIPsortDownRealRealRealBoolPtr( negquotient, raydirection, rayorigin, sign, (void**) subspacevars, nsubspacevars);
1005 
1006 #ifndef NDEBUG
1007  for( i = 0; i < nsubspacevars; i++ )
1008  assert( raydirection[i] >= 0 );
1009  for( i = 1; i < nsubspacevars; i++ )
1010  assert( negquotient[i - 1] >= negquotient[i] );
1011 #endif
1012  /* finished initialization */
1013 
1014  /* find the first facet of the octahedron hit by a ray shot from rayorigin into direction raydirection */
1015  for( i = 0; i < nsubspacevars && negquotient[i] * q > p; ++i )
1016  {
1017  facets[0][i] = FALSE;
1018  p += 2 * rayorigin[i];
1019  q -= 2 * raydirection[i];
1020  assert(SCIPisPositive(scip, p));
1021  assert(SCIPisPositive(scip, q));
1022  }
1023 
1024  /* avoid dividing by values close to 0.0 */
1025  if( !SCIPisFeasPositive(scip, q) )
1026  continue;
1027 
1028  /* assert necessary for flexelint */
1029  assert(q != 0.0);
1030  lambda[0] = p / q;
1031 
1032  nfacets = 1;
1033 
1034  /* find the first facets hit by the ray */
1035  for( i = 0; i < nfacets && i < f_first; ++i)
1036  generateNeighborFacets(scip, facets, lambda, rayorigin, raydirection, negquotient, nsubspacevars, f_max, i, &nfacets);
1037 
1038  /* construct the first ffirst possible solutions */
1039  for( i = 0; i < nfacets && i < f_first; ++i )
1040  {
1041  SCIP_CALL( SCIPcreateSol(scip, &first_sols[i], heur) );
1042  SCIP_CALL( getSolFromFacet(scip, facets[i], first_sols[i], sign, subspacevars, nsubspacevars) );
1043  assert( first_sols[i] != NULL );
1044  }
1045 
1046  /* try, whether there is a row violated by all of the first ffirst solutions */
1047  cons_viol = FALSE;
1048  SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
1049  for( i = nrows - 1; i >= 0; --i )
1050  {
1051  if( !SCIProwIsLocal(rows[i]) )
1052  {
1053  SCIP_COL** cols;
1054  SCIP_Real constant;
1055  SCIP_Real lhs;
1056  SCIP_Real rhs;
1057  SCIP_Real rowval;
1058  SCIP_Real* coeffs;
1059  int nnonzerovars;
1060  int k;
1061 
1062  /* get the row's data */
1063  constant = SCIProwGetConstant(rows[i]);
1064  lhs = SCIProwGetLhs(rows[i]);
1065  rhs = SCIProwGetRhs(rows[i]);
1066  coeffs = SCIProwGetVals(rows[i]);
1067  nnonzerovars = SCIProwGetNNonz(rows[i]);
1068  cols = SCIProwGetCols(rows[i]);
1069  rowval = constant;
1070 
1071  for( j = nnonzerovars - 1; j >= 0; --j )
1072  rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[0], SCIPcolGetVar(cols[j]));
1073 
1074  /* if the row's lhs is violated by the first sol, test, whether it is violated by the next ones, too */
1075  if( lhs > rowval )
1076  {
1077  cons_viol = TRUE;
1078  for( k = MIN(f_first, nfacets) - 1; k > 0; --k )
1079  {
1080  rowval = constant;
1081  for( j = nnonzerovars - 1; j >= 0; --j )
1082  rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[k], SCIPcolGetVar(cols[j]));
1083  if( lhs <= rowval )
1084  {
1085  cons_viol = FALSE;
1086  break;
1087  }
1088  }
1089  }
1090  /* dito for the right hand side */
1091  else if( rhs < rowval )
1092  {
1093  cons_viol = TRUE;
1094  for( k = MIN(f_first, nfacets) - 1; k > 0; --k )
1095  {
1096  rowval = constant;
1097  for( j = nnonzerovars - 1; j >= 0; --j )
1098  rowval += coeffs[j] * SCIPgetSolVal(scip, first_sols[k], SCIPcolGetVar(cols[j]));
1099  if( rhs >= rowval )
1100  {
1101  cons_viol = FALSE;
1102  break;
1103  }
1104  }
1105  }
1106  /* break as soon as one row is violated by all of the ffirst solutions */
1107  if( cons_viol )
1108  break;
1109  }
1110  }
1111 
1112 
1113  if( !cons_viol )
1114  {
1115  /* if there was no row violated by all solutions, try whether one or more of them are feasible */
1116  for( i = MIN(f_first, nfacets) - 1; i >= 0; --i )
1117  {
1118  assert(first_sols[i] != NULL);
1119  SCIP_CALL( SCIPtrySol(scip, first_sols[i], FALSE, TRUE, FALSE, TRUE, &success) );
1120  if( success )
1121  *result = SCIP_FOUNDSOL;
1122  }
1123  /* search for further facets and construct and try solutions out of facets fixed as closest ones */
1124  for( i = f_first; i < f_max; ++i)
1125  {
1126  if( i >= nfacets )
1127  break;
1128  generateNeighborFacets(scip, facets, lambda, rayorigin, raydirection, negquotient, nsubspacevars, f_max, i, &nfacets);
1129  SCIP_CALL( getSolFromFacet(scip, facets[i], sol, sign, subspacevars, nsubspacevars) );
1130  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, TRUE, FALSE, TRUE, &success) );
1131  if( success )
1132  *result = SCIP_FOUNDSOL;
1133  }
1134  }
1135 
1136  /* finished OCTANE */
1137  for( i = MIN(f_first, nfacets) - 1; i >= 0; --i )
1138  {
1139  SCIP_CALL( SCIPfreeSol(scip, &first_sols[i]) );
1140  }
1141  }
1142  heurdata->lastrule = r;
1143 
1144  if( *result == SCIP_FOUNDSOL )
1145  ++(heurdata->nsuccess);
1146 
1147  /* free temporary memory */
1148  SCIPfreeBufferArray(scip, &first_sols);
1149  for( i = f_max; i >= 0; --i )
1150  SCIPfreeBufferArray(scip, &facets[i]);
1151  SCIPfreeBufferArray(scip, &facets);
1152  SCIPfreeBufferArray(scip, &lambda);
1153  SCIPfreeBufferArray(scip, &perm);
1154  SCIPfreeBufferArray(scip, &sign);
1155  SCIPfreeBufferArray(scip, &negquotient);
1156  SCIPfreeBufferArray(scip, &raydirection);
1157  SCIPfreeBufferArray(scip, &rayorigin);
1158  SCIPfreeBufferArray(scip, &subspacevars);
1159  SCIPfreeBufferArray(scip, &fracspace);
1160 
1161  return SCIP_OKAY;
1162 }
1163 
1164 
1165 /*
1166  * primal heuristic specific interface methods
1167  */
1168 
1169 /** creates the octane primal heuristic and includes it in SCIP */
1171  SCIP* scip /**< SCIP data structure */
1172  )
1173 {
1174  SCIP_HEURDATA* heurdata;
1175  SCIP_HEUR* heur;
1176 
1177  /* create Octane primal heuristic data */
1178  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
1179 
1180  /* include primal heuristic */
1181  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
1183  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOctane, heurdata) );
1184 
1185  assert(heur != NULL);
1186 
1187  /* set non-NULL pointers to callback methods */
1188  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOctane) );
1189  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOctane) );
1190  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOctane) );
1191  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitOctane) );
1192 
1193  /* add octane primal heuristic parameters */
1194  SCIP_CALL( SCIPaddIntParam(scip,
1195  "heuristics/octane/fmax",
1196  "number of 0-1-points to be tested as possible solutions by OCTANE",
1197  &heurdata->f_max, TRUE, DEFAULT_FMAX, 1, INT_MAX, NULL, NULL) );
1198 
1199  SCIP_CALL( SCIPaddIntParam(scip,
1200  "heuristics/octane/ffirst",
1201  "number of 0-1-points to be tested at first whether they violate a common row",
1202  &heurdata->f_first, TRUE, DEFAULT_FFIRST, 1, INT_MAX, NULL, NULL) );
1203 
1205  "heuristics/octane/usefracspace",
1206  "execute OCTANE only in the space of fractional variables (TRUE) or in the full space?",
1207  &heurdata->usefracspace, TRUE, DEFAULT_USEFRACSPACE, NULL, NULL) );
1208 
1210  "heuristics/octane/useobjray",
1211  "should the inner normal of the objective be used as one ray direction?",
1212  &heurdata->useobjray, TRUE, TRUE, NULL, NULL) );
1213 
1215  "heuristics/octane/useavgray",
1216  "should the average of the basic cone be used as one ray direction?",
1217  &heurdata->useavgray, TRUE, TRUE, NULL, NULL) );
1218 
1220  "heuristics/octane/usediffray",
1221  "should the difference between the root solution and the current LP solution be used as one ray direction?",
1222  &heurdata->usediffray, TRUE, FALSE, NULL, NULL) );
1223 
1225  "heuristics/octane/useavgwgtray",
1226  "should the weighted average of the basic cone be used as one ray direction?",
1227  &heurdata->useavgwgtray, TRUE, TRUE, NULL, NULL) );
1228 
1230  "heuristics/octane/useavgnbray",
1231  "should the weighted average of the nonbasic cone be used as one ray direction?",
1232  &heurdata->useavgnbray, TRUE, TRUE, NULL, NULL) );
1233 
1234  return SCIP_OKAY;
1235 }
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:33125
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
#define DEFAULT_USEFRACSPACE
Definition: heur_octane.c:40
SCIP_RETCODE SCIPincludeHeurOctane(SCIP *scip)
Definition: heur_octane.c:1170
void SCIPsortDownRealRealRealBoolPtr(SCIP_Real *realarray1, SCIP_Real *realarray2, SCIP_Real *realarray3, SCIP_Bool *boolarray, void **ptrarray, int len)
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:7297
#define DEFAULT_FMAX
Definition: heur_octane.c:38
#define NULL
Definition: lpi_spx.cpp:130
static SCIP_RETCODE generateStartingPoint(SCIP *scip, SCIP_Real *rayorigin, SCIP_VAR **subspacevars, int nsubspacevars)
Definition: heur_octane.c:489
static SCIP_RETCODE generateDifferenceRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars)
Definition: heur_octane.c:167
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:18915
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:18861
static SCIP_Bool isZero(SCIP *scip, SCIP_Real *raydirection, int nsubspacevars)
Definition: heur_octane.c:636
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:34843
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:7252
#define FALSE
Definition: def.h:56
#define TRUE
Definition: def.h:55
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:41972
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26439
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34983
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16905
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:18881
static void flipCoords(SCIP_Real *rayorigin, SCIP_Real *raydirection, SCIP_Bool *sign, int nsubspacevars)
Definition: heur_octane.c:512
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26482
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
Definition: scip.c:26672
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3547
#define HEUR_PRIORITY
Definition: heur_octane.c:31
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3573
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
Definition: var.c:12607
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:18726
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41984
#define HEUR_DISPCHAR
Definition: heur_octane.c:30
static SCIP_DECL_HEURCOPY(heurCopyOctane)
Definition: heur_octane.c:665
#define DEFAULT_FFIRST
Definition: heur_octane.c:39
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:18925
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41996
static SCIP_RETCODE generateAverageRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars, SCIP_Bool weighted)
Definition: heur_octane.c:189
static SCIP_DECL_HEUREXIT(heurExitOctane)
Definition: heur_octane.c:724
#define HEUR_USESSUBSCIP
Definition: heur_octane.c:36
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:34002
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41907
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:19024
#define HEUR_MAXDEPTH
Definition: heur_octane.c:34
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16771
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition: scip.c:26750
static SCIP_DECL_HEUREXEC(heurExecOctane)
Definition: heur_octane.c:744
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:41637
static SCIP_DECL_HEURINIT(heurInitOctane)
Definition: heur_octane.c:699
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41946
static SCIP_RETCODE generateObjectiveRay(SCIP *scip, SCIP_Real *raydirection, SCIP_VAR **subspacevars, int nsubspacevars)
Definition: heur_octane.c:147
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
#define HEUR_NAME
Definition: heur_octane.c:28
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
#define SCIP_Bool
Definition: def.h:53
static void generateNeighborFacets(SCIP *scip, SCIP_Bool **facets, SCIP_Real *lambda, SCIP_Real *rayorigin, SCIP_Real *raydirection, SCIP_Real *negquotient, int nsubspacevars, int f_max, int i, int *nfacets)
Definition: heur_octane.c:543
static SCIP_RETCODE getSolFromFacet(SCIP *scip, SCIP_Bool *facet, SCIP_SOL *sol, SCIP_Bool *sign, SCIP_VAR **subspacevars, int nsubspacevars)
Definition: heur_octane.c:110
#define HEUR_FREQ
Definition: heur_octane.c:32
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34648
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7345
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7329
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:17431
#define SCIP_REAL_MAX
Definition: def.h:128
#define SCIP_REAL_MIN
Definition: def.h:129
#define HEUR_DESC
Definition: heur_octane.c:29
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1293
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_RETCODE SCIPgetLPBInvACol(SCIP *scip, int c, SCIP_Real *coefs, int *inds, int *ninds)
Definition: scip.c:26999
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:18935
static SCIP_DECL_HEURFREE(heurFreeOctane)
Definition: heur_octane.c:679
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:18871
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41933
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7313
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16750
#define SCIP_Real
Definition: def.h:127
#define MIN(x, y)
Definition: memory.c:67
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41959
#define HEUR_TIMING
Definition: heur_octane.c:35
static SCIP_RETCODE generateAverageNBRay(SCIP *scip, SCIP_Real *raydirection, int *fracspace, SCIP_VAR **subspacevars, int nsubspacevars)
Definition: heur_octane.c:391
octane primal heuristic based on Balas, Ceria, Dawande, Margot, and Pataki
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:18836
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1058
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:10572
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:26847
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:18685
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41697
static void tryToInsert(SCIP *scip, SCIP_Bool **facets, SCIP_Real *lambda, int i, int j, int f_max, int nsubspacevars, SCIP_Real lam, int *nfacets)
Definition: heur_octane.c:65
#define SCIPABORT()
Definition: def.h:238
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:36217
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:37372
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:34607
#define HEUR_FREQOFS
Definition: heur_octane.c:33