Scippy

SCIP

Solving Constraint Integer Programs

lp.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-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lp.c
17  * @ingroup OTHER_CFILES
18  * @brief LP management methods and data structures
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Marc Pfetsch
22  * @author Kati Wolter
23  * @author Gerald Gamrath
24  *
25  * In LP management, we have to differ between the current LP and the SCIP_LP
26  * stored in the LP solver. All LP methods affect the current LP only.
27  * Before solving the current LP with the LP solver or setting an LP state,
28  * the LP solvers data has to be updated to the current LP with a call to
29  * lpFlush().
30  */
31 
32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33 
34 
35 #include "lpi/lpi.h"
36 #include "scip/clock.h"
37 #include "scip/cons.h"
38 #include "scip/event.h"
39 #include "scip/intervalarith.h"
40 #include "scip/lp.h"
41 #include "scip/misc.h"
42 #include "scip/prob.h"
43 #include "scip/pub_lp.h"
44 #include "scip/pub_message.h"
45 #include "scip/pub_misc.h"
46 #include "scip/pub_misc_sort.h"
47 #include "scip/pub_var.h"
48 #include "scip/set.h"
49 #include "scip/sol.h"
50 #include "scip/solve.h"
51 #include "scip/stat.h"
52 #include "scip/struct_event.h"
53 #include "scip/struct_lp.h"
54 #include "scip/struct_prob.h"
55 #include "scip/struct_set.h"
56 #include "scip/struct_stat.h"
57 #include "scip/struct_var.h"
58 #include "scip/var.h"
59 #include <string.h>
60 
61 
62 /* activate this to use the row activities as given by the LPI instead of recalculating
63  * using the LP solver activity is potentially faster, but may not be consistent with the SCIP_ROW calculations
64  * see also #2594 for more details on possible trouble
65  */
66 /* #define SCIP_USE_LPSOLVER_ACTIVITY */
67 
68 /*
69  * debug messages
70  */
71 
72 #ifdef SCIP_DEBUG
73 /** method is to print in row in case SCIP_DEBUG is defined */
74 static
75 void debugRowPrint(
76  SCIP_SET* set, /**< global SCIP settings */
77  SCIP_ROW* row /**< LP row */
78  )
79 {
80  int i;
81 
82  assert(row != NULL);
83 
84  /* print row name */
85  if( row->name != NULL && row->name[0] != '\0' )
86  {
87  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
88  }
89 
90  /* print left hand side */
91  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
92 
93  /* print coefficients */
94  if( row->len == 0 )
95  {
96  SCIPsetDebugMsgPrint(set, "0 ");
97  }
98  for( i = 0; i < row->len; ++i )
99  {
100  assert(row->cols[i] != NULL);
101  assert(row->cols[i]->var != NULL);
102  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
103  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
104  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
105  }
106 
107  /* print constant */
109  {
110  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
111  }
112 
113  /* print right hand side */
114  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
115 }
116 #else
117 #define debugRowPrint(x,y) /**/
118 #endif
119 
120 #ifdef SCIP_DEBUG
121 /** method to output column if SCIP_DEBUG is define */
122 static
123 void debugColPrint(
124  SCIP_SET* set, /**< global SCIP settings */
125  SCIP_COL* col /**< LP column */
126  )
127 {
128  int r;
129 
130  assert(col != NULL);
131  assert(col->var != NULL);
132 
133  /* print bounds */
134  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
135 
136  /* print coefficients */
137  if( col->len == 0 )
138  {
139  SCIPsetDebugMsgPrint(set, "<empty>");
140  }
141  for( r = 0; r < col->len; ++r )
142  {
143  assert(col->rows[r] != NULL);
144  assert(col->rows[r]->name != NULL);
145  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
146  }
147  SCIPsetDebugMsgPrint(set, "\n");
148 }
149 #else
150 #define debugColPrint(x,y) /**/
151 #endif
152 
153 /*
154  * memory growing methods for dynamically allocated arrays
155  */
156 
157 /** ensures, that chgcols array can store at least num entries */
158 static
160  SCIP_LP* lp, /**< current LP data */
161  SCIP_SET* set, /**< global SCIP settings */
162  int num /**< minimum number of entries to store */
163  )
164 {
165  assert(lp->nchgcols <= lp->chgcolssize);
166 
167  if( num > lp->chgcolssize )
168  {
169  int newsize;
170 
171  newsize = SCIPsetCalcMemGrowSize(set, num);
172  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
173  lp->chgcolssize = newsize;
174  }
175  assert(num <= lp->chgcolssize);
176 
177  return SCIP_OKAY;
178 }
179 
180 /** ensures, that chgrows array can store at least num entries */
181 static
183  SCIP_LP* lp, /**< current LP data */
184  SCIP_SET* set, /**< global SCIP settings */
185  int num /**< minimum number of entries to store */
186  )
187 {
188  assert(lp->nchgrows <= lp->chgrowssize);
189 
190  if( num > lp->chgrowssize )
191  {
192  int newsize;
193 
194  newsize = SCIPsetCalcMemGrowSize(set, num);
195  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
196  lp->chgrowssize = newsize;
197  }
198  assert(num <= lp->chgrowssize);
199 
200  return SCIP_OKAY;
201 }
202 
203 /** ensures, that lpicols array can store at least num entries */
204 static
206  SCIP_LP* lp, /**< current LP data */
207  SCIP_SET* set, /**< global SCIP settings */
208  int num /**< minimum number of entries to store */
209  )
210 {
211  assert(lp->nlpicols <= lp->lpicolssize);
212 
213  if( num > lp->lpicolssize )
214  {
215  int newsize;
216 
217  newsize = SCIPsetCalcMemGrowSize(set, num);
218  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
219  lp->lpicolssize = newsize;
220  }
221  assert(num <= lp->lpicolssize);
222 
223  return SCIP_OKAY;
224 }
225 
226 /** ensures, that lpirows array can store at least num entries */
227 static
229  SCIP_LP* lp, /**< current LP data */
230  SCIP_SET* set, /**< global SCIP settings */
231  int num /**< minimum number of entries to store */
232  )
233 {
234  assert(lp->nlpirows <= lp->lpirowssize);
235 
236  if( num > lp->lpirowssize )
237  {
238  int newsize;
239 
240  newsize = SCIPsetCalcMemGrowSize(set, num);
241  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
242  lp->lpirowssize = newsize;
243  }
244  assert(num <= lp->lpirowssize);
245 
246  return SCIP_OKAY;
247 }
248 
249 /** ensures, that cols array can store at least num entries */
250 static
252  SCIP_LP* lp, /**< current LP data */
253  SCIP_SET* set, /**< global SCIP settings */
254  int num /**< minimum number of entries to store */
255  )
256 {
257  assert(lp->ncols <= lp->colssize);
258 
259  if( num > lp->colssize )
260  {
261  int newsize;
262 
263  newsize = SCIPsetCalcMemGrowSize(set, num);
264  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
265  lp->colssize = newsize;
266  }
267  assert(num <= lp->colssize);
268 
269  return SCIP_OKAY;
270 }
271 
272 /** ensures, that soldirection array can store at least num entries */
273 static
275  SCIP_LP* lp, /**< current LP data */
276  int num /**< minimum number of entries to store */
277  )
278 {
279  if( num > lp->soldirectionsize )
280  {
283 
284  lp->soldirectionsize = num;
285  }
286 
287  assert(num <= lp->soldirectionsize);
288 
289  return SCIP_OKAY;
290 }
291 
292 /** ensures, that lazy cols array can store at least num entries */
293 static
295  SCIP_LP* lp, /**< current LP data */
296  SCIP_SET* set, /**< global SCIP settings */
297  int num /**< minimum number of entries to store */
298  )
299 {
300  assert(lp->nlazycols <= lp->lazycolssize);
301 
302  if( num > lp->lazycolssize )
303  {
304  int newsize;
305 
306  newsize = SCIPsetCalcMemGrowSize(set, num);
307  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
308  lp->lazycolssize = newsize;
309  }
310  assert(num <= lp->lazycolssize);
311 
312  return SCIP_OKAY;
313 }
314 
315 /** ensures, that rows array can store at least num entries */
316 static
318  SCIP_LP* lp, /**< current LP data */
319  SCIP_SET* set, /**< global SCIP settings */
320  int num /**< minimum number of entries to store */
321  )
322 {
323  assert(lp->nrows <= lp->rowssize);
324 
325  if( num > lp->rowssize )
326  {
327  int newsize;
328 
329  newsize = SCIPsetCalcMemGrowSize(set, num);
330  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
331  lp->rowssize = newsize;
332  }
333  assert(num <= lp->rowssize);
334 
335  return SCIP_OKAY;
336 }
337 
338 /** ensures, that row array of column can store at least num entries */
339 static
341  SCIP_COL* col, /**< LP column */
342  BMS_BLKMEM* blkmem, /**< block memory */
343  SCIP_SET* set, /**< global SCIP settings */
344  int num /**< minimum number of entries to store */
345  )
346 {
347  assert(col != NULL);
348  assert(col->len <= col->size);
349 
350  if( num > col->size )
351  {
352  int newsize;
353 
354  newsize = SCIPsetCalcMemGrowSize(set, num);
355  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
356  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
357  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
358  col->size = newsize;
359  }
360  assert(num <= col->size);
361 
362  return SCIP_OKAY;
363 }
364 
365 /** save current LP values dependent on the solution */
366 static
368  SCIP_LP* lp, /**< LP data */
369  SCIP_STAT* stat, /**< problem statistics */
370  BMS_BLKMEM* blkmem /**< block memory */
371  )
372 {
373  SCIP_LPSOLVALS* storedsolvals;
374 
375  assert(lp != NULL);
376  assert(stat != NULL);
377  assert(blkmem != NULL);
378 
379  /* allocate memory for storage */
380  if( lp->storedsolvals == NULL )
381  {
383  }
384  storedsolvals = lp->storedsolvals;
385 
386  /* store values */
387  storedsolvals->lpsolstat = lp->lpsolstat;
388  storedsolvals->lpobjval = lp->lpobjval;
389  storedsolvals->primalfeasible = lp->primalfeasible;
390  storedsolvals->primalchecked = lp->primalchecked;
391  storedsolvals->dualfeasible = lp->dualfeasible;
392  storedsolvals->dualchecked = lp->dualchecked;
393  storedsolvals->solisbasic = lp->solisbasic;
394  storedsolvals->lpissolved = lp->solved;
395 
396  return SCIP_OKAY;
397 }
398 
399 /** restore LP solution values in column */
400 static
402  SCIP_LP* lp, /**< LP data */
403  BMS_BLKMEM* blkmem, /**< block memory */
404  SCIP_Longint validlp /**< number of lp for which restored values are valid */
405  )
406 {
407  SCIP_LPSOLVALS* storedsolvals;
408 
409  assert(lp != NULL);
410  assert(blkmem != NULL);
411 
412  /* if stored values are available, restore them */
413  storedsolvals = lp->storedsolvals;
414  if( storedsolvals != NULL )
415  {
416  lp->solved = storedsolvals->lpissolved;
417  lp->validsollp = validlp;
418 
419  lp->lpsolstat = storedsolvals->lpsolstat;
420  lp->lpobjval = storedsolvals->lpobjval;
421  lp->primalfeasible = storedsolvals->primalfeasible;
422  lp->primalchecked = storedsolvals->primalchecked;
423  lp->dualfeasible = storedsolvals->dualfeasible;
424  lp->dualchecked = storedsolvals->dualchecked;
425  lp->solisbasic = storedsolvals->solisbasic;
426 
427  /* solution values are stored only for LPs solved to optimality or unboundedness */
428  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
434  lp->validsollp == -1);
435  }
436  /* no values available, mark LP as unsolved */
437  else
438  {
439  lp->solved = FALSE;
440  lp->validsollp = -1;
441 
443  lp->lpobjval = SCIP_INVALID;
444  lp->primalfeasible = FALSE;
445  lp->primalchecked = FALSE;
446  lp->dualfeasible = FALSE;
447  lp->dualchecked = FALSE;
448  lp->solisbasic = FALSE;
449  lp->validfarkaslp = -1;
450  }
451 
452  lp->validdegeneracylp = -1;
453 
454  /* intentionally keep storage space allocated */
455 
456  return SCIP_OKAY;
457 }
458 
459 /** save current LP solution values stored in each column */
460 static
462  SCIP_COL* col, /**< LP column */
463  BMS_BLKMEM* blkmem /**< block memory */
464  )
465 {
466  SCIP_COLSOLVALS* storedsolvals;
467 
468  assert(col != NULL);
469  assert(blkmem != NULL);
470 
471  /* allocate memory for storage */
472  if( col->storedsolvals == NULL )
473  {
474  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
475  }
476  storedsolvals = col->storedsolvals;
477 
478  /* store values */
479  storedsolvals->primsol = col->primsol;
480  storedsolvals->redcost = col->redcost;
481  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
482 
483  return SCIP_OKAY;
484 }
485 
486 /** restore LP solution values in column */
487 static
489  SCIP_COL* col, /**< LP column */
490  BMS_BLKMEM* blkmem, /**< block memory */
491  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
492  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
493  )
494 {
495  SCIP_COLSOLVALS* storedsolvals;
496 
497  assert(col != NULL);
498  assert(blkmem != NULL);
499 
500  /* if stored values are available, restore them */
501  storedsolvals = col->storedsolvals;
502  if( storedsolvals != NULL )
503  {
504  col->primsol = storedsolvals->primsol;
505  col->redcost = storedsolvals->redcost;
506  col->validredcostlp = validlp;
507  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
508 
509  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
510  col->validfarkaslp = -1;
511  }
512  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
513  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
514  */
515  else
516  {
517  col->primsol = 0.0;
518  col->validredcostlp = -1;
519  col->validfarkaslp = -1;
520  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
521  }
522 
523  /* free memory */
524  if( freebuffer )
525  {
526  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
527  assert(col->storedsolvals == NULL);
528  }
529 
530  return SCIP_OKAY;
531 }
532 
533 /** save current LP solution values stored in each column */
534 static
536  SCIP_ROW* row, /**< LP row */
537  BMS_BLKMEM* blkmem, /**< block memory */
538  SCIP_Bool infeasible /**< is the solution infeasible? */
539  )
540 {
541  SCIP_ROWSOLVALS* storedsolvals;
542 
543  assert(row != NULL);
544  assert(blkmem != NULL);
545 
546  /* allocate memory for storage */
547  if( row->storedsolvals == NULL )
548  {
549  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
550  }
551  storedsolvals = row->storedsolvals;
552 
553  /* store values */
554  if ( infeasible )
555  {
556  storedsolvals->dualsol = row->dualfarkas;
557  storedsolvals->activity = SCIP_INVALID;
558  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
559  }
560  else
561  {
562  storedsolvals->dualsol = row->dualsol;
563  storedsolvals->activity = row->activity;
564  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
565  }
566 
567  return SCIP_OKAY;
568 }
569 
570 /** restore LP solution values in row */
571 static
573  SCIP_ROW* row, /**< LP column */
574  BMS_BLKMEM* blkmem, /**< block memory */
575  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
576  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
577  SCIP_Bool infeasible /**< is the solution infeasible? */
578  )
579 {
580  SCIP_ROWSOLVALS* storedsolvals;
581 
582  assert(row != NULL);
583  assert(blkmem != NULL);
584 
585  /* if stored values are available, restore them */
586  storedsolvals = row->storedsolvals;
587  if( storedsolvals != NULL )
588  {
589  if ( infeasible )
590  row->dualfarkas = storedsolvals->dualsol;
591  else
592  row->dualsol = storedsolvals->dualsol;
593  row->activity = storedsolvals->activity;
594  row->validactivitylp = validlp;
595  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
596  }
597  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
598  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
599  */
600  else
601  {
602  row->dualsol = 0.0;
603  row->dualfarkas = 0.0;
604  row->activity = SCIP_INVALID;
605  row->validactivitylp = -1;
606  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
607  }
608 
609  /* free memory */
610  if( freebuffer )
611  {
612  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
613  assert(row->storedsolvals == NULL);
614  }
615 
616  return SCIP_OKAY;
617 }
618 
619 /** ensures, that column array of row can store at least num entries */
621  SCIP_ROW* row, /**< LP row */
622  BMS_BLKMEM* blkmem, /**< block memory */
623  SCIP_SET* set, /**< global SCIP settings */
624  int num /**< minimum number of entries to store */
625  )
626 {
627  assert(row != NULL);
628  assert(row->len <= row->size);
629 
630  if( num > row->size )
631  {
632  int newsize;
633 
634  newsize = SCIPsetCalcMemGrowSize(set, num);
635  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
636  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
637  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
638  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
639  row->size = newsize;
640  }
641  assert(num <= row->size);
642 
643  return SCIP_OKAY;
644 }
645 
646 
647 #ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
648 static SCIP_Bool msgdisp_checkrow = FALSE;
649 
650 static
651 void checkRow(
652  SCIP_ROW* row
653  )
654 {
655  int i;
656 
657  if( !msgdisp_checkrow )
658  {
659  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
660  msgdisp_checkrow = TRUE;
661  }
662 
663  /* validate sorting of LP part of row */
664  if( row->lpcolssorted && row->nlpcols > 0)
665  {
666  assert(row->cols_index[0] == row->cols[0]->index);
667  for( i = 1; i < row->nlpcols; ++i )
668  {
669  assert(row->cols_index[i] == row->cols[i]->index);
670  assert(row->cols_index[i] >= row->cols_index[i-1]);
671  }
672  }
673 
674  /* validate sorting of non-LP part of row */
675  if( row->nonlpcolssorted && row->len > row->nlpcols )
676  {
677  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
678  for( i = row->nlpcols + 1; i < row->len; ++i )
679  {
680  assert(row->cols_index[i] == row->cols[i]->index);
681  assert(row->cols_index[i] >= row->cols_index[i-1]);
682  }
683  }
684 }
685 #else
686 #define checkRow(row) /**/
687 #endif
688 
689 #ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
690 static
691 void checkRowSqrnorm(
692  SCIP_ROW* row
693  )
694 {
695  SCIP_COL** cols;
696  SCIP_Real sqrnorm;
697  int c;
698 
699  cols = row->cols;
700  assert(cols != NULL || row->len == 0);
701 
702  sqrnorm = 0.0;
703 
704  for( c = row->len - 1; c >= 0; --c )
705  {
706  if( cols[c]->lppos >= 0 )
707  sqrnorm += SQR(row->vals[c]);
708  }
709 
710  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
711 }
712 
713 static
714 void checkRowSumnorm(
715  SCIP_ROW* row
716  )
717 {
718  SCIP_COL** cols;
719  SCIP_Real sumnorm;
720  int c;
721 
722  cols = row->cols;
723  assert(cols != NULL || row->len == 0);
724 
725  sumnorm = 0.0;
726 
727  for( c = row->len - 1; c >= 0; --c )
728  {
729  if( cols[c]->lppos >= 0 )
730  sumnorm += REALABS(row->vals[c]);
731  }
732 
733  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
734 }
735 
736 static
737 void checkRowObjprod(
738  SCIP_ROW* row
739  )
740 {
741  SCIP_COL** cols;
742  SCIP_Real objprod;
743  int c;
744 
745  cols = row->cols;
746  assert(cols != NULL || row->len == 0);
747 
748  objprod = 0.0;
749 
750  for( c = row->len - 1; c >= 0; --c )
751  {
752  if( cols[c]->lppos >= 0 )
753  objprod += row->vals[c] * cols[c]->unchangedobj;
754  }
755 
756  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
757 }
758 #else
759 #define checkRowSqrnorm(row) /**/
760 #define checkRowSumnorm(row) /**/
761 #define checkRowObjprod(row) /**/
762 #endif
763 
764 /*
765  * Local methods for pseudo and loose objective values
766  */
767 
768 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
769 static
771  SCIP_LP* lp, /**< current LP data */
772  SCIP_SET* set, /**< global SCIP settings */
773  SCIP_PROB* prob /**< problem data */
774  )
775 {
776  SCIP_VAR** vars;
777  SCIP_Real obj;
778  int nvars;
779  int v;
780 
781  assert(lp != NULL);
782  assert(set != NULL);
783  assert(prob != NULL);
784  assert(!lp->looseobjvalid);
785 
786  vars = prob->vars;
787  nvars = prob->nvars;
788  lp->looseobjval = 0.0;
789 
790  /* iterate over all variables in the problem */
791  for( v = 0; v < nvars; ++v )
792  {
793  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
794  {
795  obj = SCIPvarGetObj(vars[v]);
796 
797  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
798  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
799  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
800  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
801  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
802  }
803  }
804 
805  /* the recomputed value is reliable */
806  lp->rellooseobjval = lp->looseobjval;
807  lp->looseobjvalid = TRUE;
808 }
809 
810 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
811 static
813  SCIP_LP* lp, /**< current LP data */
814  SCIP_SET* set, /**< global SCIP settings */
815  SCIP_PROB* prob /**< problem data */
816  )
817 {
818  SCIP_VAR** vars;
819  int nvars;
820  int v;
821 
822  assert(lp != NULL);
823  assert(set != NULL);
824  assert(prob != NULL);
825  assert(!lp->pseudoobjvalid);
826 
827  vars = prob->vars;
828  nvars = prob->nvars;
829  lp->pseudoobjval = 0.0;
830 
831  /* iterate over all variables in the problem */
832  for( v = 0; v < nvars; ++v )
833  {
834  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
835  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
836  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
837  {
838  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
839  }
840  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
841  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
842  {
843  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
844  }
845  }
846 
847  /* the recomputed value is reliable */
848  lp->relpseudoobjval = lp->pseudoobjval;
849  lp->pseudoobjvalid = TRUE;
850 }
851 
852 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
853 static
855  SCIP_LP* lp, /**< current LP data */
856  SCIP_SET* set, /**< global SCIP settings */
857  SCIP_PROB* prob /**< problem data */
858  )
859 {
860  SCIP_VAR** vars;
861  int nvars;
862  int v;
863 
864  assert(lp != NULL);
865  assert(set != NULL);
866  assert(prob != NULL);
867  assert(!lp->glbpseudoobjvalid);
868 
869  vars = prob->vars;
870  nvars = prob->nvars;
871  lp->glbpseudoobjval = 0.0;
872 
873  /* iterate over all variables in the problem */
874  for( v = 0; v < nvars; ++v )
875  {
876  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
877  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
878  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
879  {
880  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
881  }
882  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
883  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
884  {
885  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
886  }
887  }
888 
889  /* the recomputed value is reliable */
891  lp->glbpseudoobjvalid = TRUE;
892 }
893 
894 /** gets finite part of objective value of current LP that results from LOOSE variables only */
895 static
897  SCIP_LP* lp, /**< current LP data */
898  SCIP_SET* set, /**< global SCIP settings */
899  SCIP_PROB* prob /**< problem data */
900  )
901 {
902  assert(lp != NULL);
903  assert(set != NULL);
904  assert(prob != NULL);
905  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
906  assert(lp->flushed);
907  assert(lp->looseobjvalinf == 0);
908 
909  /* recalculate the loose objective value, if needed */
910  if( !lp->looseobjvalid )
911  recomputeLooseObjectiveValue(lp, set, prob);
912 
913  return lp->looseobjval;
914 }
915 
916 /** gets finite part of pseudo objective value of current LP */
917 static
919  SCIP_LP* lp, /**< current LP data */
920  SCIP_SET* set, /**< global SCIP settings */
921  SCIP_PROB* prob /**< problem data */
922  )
923 {
924  assert(lp != NULL);
925  assert(set != NULL);
926  assert(prob != NULL);
927 
928  /* recalculate the pseudo objective value, if needed */
929  if( !lp->pseudoobjvalid )
930  recomputePseudoObjectiveValue(lp, set, prob);
931 
932  return lp->pseudoobjval;
933 }
934 
935 /*
936  * Sorting and searching rows and columns
937  */
938 
939 
940 /** comparison method for sorting rows by non-decreasing index */
942 {
943  assert(elem1 != NULL);
944  assert(elem2 != NULL);
945 
946  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
947  return -1;
948  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
949  return +1;
950  else
951  {
952  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
953  return 0;
954  }
955 }
956 
957 
958 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
959 static
961  SCIP_COL* col /**< column to be sorted */
962  )
963 {
964  int i;
965 
966  assert(col != NULL);
967 
968  /* check, if column is already sorted in the LP part */
969  if( col->lprowssorted )
970  return;
971 
972  /* sort coefficients */
973  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
974 
975  /* update links */
976  for( i = 0; i < col->nlprows; ++i )
977  {
978  if( col->linkpos[i] >= 0 )
979  {
980  assert(col->rows[i]->cols[col->linkpos[i]] == col);
981  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
982  col->rows[i]->linkpos[col->linkpos[i]] = i;
983  }
984  }
985 
986  col->lprowssorted = TRUE;
987 }
988 
989 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
990  * ones
991  */
992 static
994  SCIP_COL* col /**< column to be sorted */
995  )
996 {
997  int i;
998 
999  assert(col != NULL);
1000 
1001  /* check, if column is already sorted in the non-LP part */
1002  if( col->nonlprowssorted )
1003  return;
1004 
1005  /* sort coefficients */
1006  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
1007 
1008  /* update links */
1009  for( i = col->nlprows; i < col->len; ++i )
1010  {
1011  if( col->linkpos[i] >= 0 )
1012  {
1013  assert(col->rows[i]->cols[col->linkpos[i]] == col);
1014  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1015  col->rows[i]->linkpos[col->linkpos[i]] = i;
1016  }
1017  }
1018 
1019  col->nonlprowssorted = TRUE;
1020 }
1021 
1022 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1023 static
1025  SCIP_ROW* row /**< row to be sorted */
1026  )
1027 {
1028  int i;
1029 
1030  assert(row != NULL);
1031 
1032  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1033  if( row->lpcolssorted || row->delaysort )
1034  return;
1035 
1036  /* sort coefficients */
1037  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1038 
1039  /* update links */
1040  for( i = 0; i < row->nlpcols; ++i )
1041  {
1042  if( row->linkpos[i] >= 0 )
1043  {
1044  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1045  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1046  row->cols[i]->linkpos[row->linkpos[i]] = i;
1047  }
1048  }
1049 
1050  row->lpcolssorted = TRUE;
1051 }
1052 
1053 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1054  * higher ones
1055  */
1056 static
1058  SCIP_ROW* row /**< row to be sorted */
1059  )
1060 {
1061  int i;
1062 
1063  assert(row != NULL);
1064 
1065  checkRow(row);
1066 
1067  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1068  if( row->nonlpcolssorted || row->delaysort )
1069  return;
1070 
1071  /* sort coefficients */
1072  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1073 
1074  /* update links */
1075  for( i = row->nlpcols; i < row->len; ++i )
1076  {
1077  if( row->linkpos[i] >= 0 )
1078  {
1079  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1080  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1081  row->cols[i]->linkpos[row->linkpos[i]] = i;
1082  }
1083  }
1084 
1085  checkRow(row);
1086 
1087  row->nonlpcolssorted = TRUE;
1088 }
1089 
1090 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1091 static
1093  SCIP_COL* col, /**< column to be searched in */
1094  const SCIP_ROW* row, /**< coefficient to be searched for */
1095  int minpos, /**< first position of search range */
1096  int maxpos /**< last position of search range */
1097  )
1098 {
1099  int pos;
1100  int idx;
1101  int searchidx;
1102 
1103  assert(col != NULL);
1104  assert(row != NULL);
1105 
1106  /* binary search */
1107  searchidx = row->index;
1108  while(minpos <= maxpos)
1109  {
1110  pos = (minpos + maxpos)/2;
1111  assert(0 <= pos && pos < col->len);
1112  assert(col->rows[pos] != NULL);
1113  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1114  idx = col->rows[pos]->index;
1115  if( searchidx == idx )
1116  return pos;
1117  else if( searchidx < idx )
1118  maxpos = pos-1;
1119  else
1120  minpos = pos+1;
1121  }
1122 
1123  return -1;
1124 }
1125 
1126 /** searches coefficient in column, returns position in col vector or -1 if not found */
1127 static
1129  SCIP_COL* col, /**< column to be searched in */
1130  const SCIP_ROW* row /**< coefficient to be searched for */
1131  )
1132 {
1133  int pos;
1134 
1135  assert(col != NULL);
1136  assert(row != NULL);
1137 
1138  pos = -1;
1139 
1140  /* search in the linked LP rows */
1141  if( row->lppos >= 0 )
1142  {
1143  /* column has to be sorted, such that binary search works */
1144  colSortLP(col);
1145  assert(col->lprowssorted);
1146 
1147  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1148  if( pos >= 0 )
1149  return pos;
1150  }
1151 
1152  /* search in the non-LP/unlinked rows */
1153  if( row->lppos == -1 || col->nunlinked > 0 )
1154  {
1155  /* column has to be sorted, such that binary search works */
1156  colSortNonLP(col);
1157  assert(col->nonlprowssorted);
1158 
1159  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1160  }
1161 
1162  return pos;
1163 }
1164 
1165 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1166 static
1168  SCIP_ROW* row, /**< row to be searched in */
1169  const SCIP_COL* col, /**< coefficient to be searched for */
1170  int minpos, /**< first position of search range */
1171  int maxpos /**< last position of search range */
1172  )
1173 {
1174  int pos;
1175  int idx;
1176  int searchidx;
1177 
1178  assert(row != NULL);
1179  assert(col != NULL);
1180 
1181  /* binary search */
1182  searchidx = col->index;
1183  while(minpos <= maxpos)
1184  {
1185  pos = (minpos + maxpos)/2;
1186  assert(0 <= pos && pos < row->len);
1187  assert(row->cols[pos] != NULL);
1188  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1189  assert(row->cols_index[pos] == row->cols[pos]->index);
1190  idx = row->cols_index[pos];
1191  if( searchidx == idx )
1192  return pos;
1193  else if( searchidx < idx )
1194  maxpos = pos-1;
1195  else
1196  minpos = pos+1;
1197  }
1198 
1199  return -1;
1200 }
1201 
1202 /** searches coefficient in row, returns position in row vector or -1 if not found;
1203  * if the sorting of the row is delayed, returns -1
1204  */
1205 static
1207  SCIP_ROW* row, /**< row to be searched in */
1208  const SCIP_COL* col /**< coefficient to be searched for */
1209  )
1210 {
1211  int pos;
1212 
1213  assert(row != NULL);
1214  assert(col != NULL);
1215 
1216  if( row->delaysort )
1217  return -1;
1218 
1219  pos = -1;
1220 
1221  /* search in the linked LP columns */
1222  if( col->lppos >= 0 )
1223  {
1224  /* row has to be sorted, such that binary search works */
1225  rowSortLP(row);
1226  assert(row->lpcolssorted);
1227 
1228  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1229  }
1230 
1231  /* search in the non-LP/unlinked columns */
1232  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1233  {
1234  /* row has to be sorted, such that binary search works */
1235  rowSortNonLP(row);
1236  assert(row->nonlpcolssorted);
1237 
1238  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1239  }
1240 
1241 #ifndef NDEBUG
1242  /* validate result */
1243  assert(-1 <= pos && pos < row->len);
1244  if( pos >= 0 )
1245  assert(row->cols[pos] == col);
1246  else
1247  {
1248  int i;
1249  for( i = 0; i < row->len; ++i )
1250  assert(row->cols[i] != col);
1251  }
1252 #endif
1253 
1254  return pos;
1255 }
1256 
1257 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1258 static
1260  SCIP_COL* col, /**< LP column */
1261  int oldpos, /**< old position of coefficient */
1262  int newpos /**< new position of coefficient */
1263  )
1264 {
1265  assert(col != NULL);
1266  assert(0 <= oldpos && oldpos < col->len);
1267  assert(0 <= newpos && newpos < col->len);
1268  assert(col->rows[oldpos] != NULL);
1269 
1270  if( oldpos == newpos )
1271  return;
1272 
1273  col->rows[newpos] = col->rows[oldpos];
1274  col->vals[newpos] = col->vals[oldpos];
1275  col->linkpos[newpos] = col->linkpos[oldpos];
1276 
1277  /* update link position in row */
1278  if( col->linkpos[newpos] >= 0 )
1279  {
1280  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1281  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1282 
1283  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1284  }
1285 
1286  /* update sorted flags */
1287  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1288  col->lprowssorted = FALSE;
1289  else
1290  col->nonlprowssorted = FALSE;
1291 }
1292 
1293 /** swaps two coefficients in a column, and updates all corresponding data structures */
1294 static
1296  SCIP_COL* col, /**< LP column */
1297  int pos1, /**< position of first coefficient */
1298  int pos2 /**< position of second coefficient */
1299  )
1300 {
1301  SCIP_ROW* tmprow;
1302  SCIP_Real tmpval;
1303  int tmplinkpos;
1304 
1305  assert(col != NULL);
1306  assert(0 <= pos1 && pos1 < col->len);
1307  assert(0 <= pos2 && pos2 < col->len);
1308  assert(col->rows[pos1] != NULL);
1309 
1310  if( pos1 == pos2 )
1311  return;
1312 
1313  /* swap coefficients */
1314  tmprow = col->rows[pos2];
1315  tmpval = col->vals[pos2];
1316  tmplinkpos = col->linkpos[pos2];
1317 
1318  col->rows[pos2] = col->rows[pos1];
1319  col->vals[pos2] = col->vals[pos1];
1320  col->linkpos[pos2] = col->linkpos[pos1];
1321 
1322  col->rows[pos1] = tmprow;
1323  col->vals[pos1] = tmpval;
1324  col->linkpos[pos1] = tmplinkpos;
1325 
1326  /* update link position in rows */
1327  if( col->linkpos[pos1] >= 0 )
1328  {
1329  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1330  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1331 
1332  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1333  }
1334  if( col->linkpos[pos2] >= 0 )
1335  {
1336  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1337  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1338 
1339  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1340  }
1341 
1342  /* update sorted flags */
1343  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1344  col->lprowssorted = FALSE;
1345  else
1346  col->nonlprowssorted = FALSE;
1347  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1348  col->lprowssorted = FALSE;
1349  else
1350  col->nonlprowssorted = FALSE;
1351 }
1352 
1353 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1354 static
1356  SCIP_ROW* row, /**< LP row */
1357  int oldpos, /**< old position of coefficient */
1358  int newpos /**< new position of coefficient */
1359  )
1360 {
1361  assert(row != NULL);
1362  assert(0 <= oldpos && oldpos < row->len);
1363  assert(0 <= newpos && newpos < row->len);
1364  assert(row->cols[oldpos] != NULL);
1365 
1366  if( oldpos == newpos )
1367  return;
1368 
1369  row->cols[newpos] = row->cols[oldpos];
1370  row->cols_index[newpos] = row->cols_index[oldpos];
1371  row->vals[newpos] = row->vals[oldpos];
1372  row->linkpos[newpos] = row->linkpos[oldpos];
1373 
1374  /* update link position in column */
1375  if( row->linkpos[newpos] >= 0 )
1376  {
1377  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1378  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1379 
1380  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1381  }
1382 
1383  /* update sorted flags */
1384  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1385  row->lpcolssorted = FALSE;
1386  else
1387  row->nonlpcolssorted = FALSE;
1388 }
1389 
1390 /** swaps two coefficients in a row, and updates all corresponding data structures */
1391 static
1393  SCIP_ROW* row, /**< LP row */
1394  int pos1, /**< position of first coefficient */
1395  int pos2 /**< position of second coefficient */
1396  )
1397 {
1398  SCIP_COL* tmpcol;
1399  SCIP_Real tmpval;
1400  int tmpindex;
1401  int tmplinkpos;
1402 
1403  assert(row != NULL);
1404  assert(0 <= pos1 && pos1 < row->len);
1405  assert(0 <= pos2 && pos2 < row->len);
1406  assert(row->cols[pos1] != NULL);
1407  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1408 
1409  if( pos1 == pos2 )
1410  return;
1411 
1412  /* swap coefficients */
1413  tmpcol = row->cols[pos2];
1414  tmpindex = row->cols_index[pos2];
1415  tmpval = row->vals[pos2];
1416  tmplinkpos = row->linkpos[pos2];
1417 
1418  row->cols[pos2] = row->cols[pos1];
1419  row->cols_index[pos2] = row->cols_index[pos1];
1420  row->vals[pos2] = row->vals[pos1];
1421  row->linkpos[pos2] = row->linkpos[pos1];
1422 
1423  row->cols[pos1] = tmpcol;
1424  row->cols_index[pos1] = tmpindex;
1425  row->vals[pos1] = tmpval;
1426  row->linkpos[pos1] = tmplinkpos;
1427 
1428  /* update link position in columns */
1429  if( row->linkpos[pos1] >= 0 )
1430  {
1431  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1432  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1433 
1434  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1435  }
1436  if( row->linkpos[pos2] >= 0 )
1437  {
1438  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1439  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1440 
1441  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1442  }
1443 
1444  /* update sorted flags */
1445  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1446  row->lpcolssorted = FALSE;
1447  else
1448  row->nonlpcolssorted = FALSE;
1449  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1450  row->lpcolssorted = FALSE;
1451  else
1452  row->nonlpcolssorted = FALSE;
1453 }
1454 
1455 /** issues a ROWCOEFCHANGED event on the given row */
1456 static
1458  SCIP_ROW* row, /**< row which coefficient has changed */
1459  BMS_BLKMEM* blkmem, /**< block memory */
1460  SCIP_SET* set, /**< global SCIP settings */
1461  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1462  SCIP_COL* col, /**< the column which coefficient has changed */
1463  SCIP_Real oldval, /**< old value of the coefficient */
1464  SCIP_Real newval /**< new value of the coefficient */
1465  )
1466 {
1467  assert(row != NULL);
1468  assert(row->eventfilter != NULL);
1469  assert(col != NULL);
1470 
1471  /* check, if the row is being tracked for coefficient changes
1472  * if so, issue ROWCOEFCHANGED event
1473  */
1474  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1475  {
1476  SCIP_EVENT* event;
1477 
1478  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1479  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1480  }
1481 
1482  return SCIP_OKAY;
1483 }
1484 
1485 /** issues a ROWCONSTCHANGED event on the given row */
1486 static
1488  SCIP_ROW* row, /**< row which coefficient has changed */
1489  BMS_BLKMEM* blkmem, /**< block memory */
1490  SCIP_SET* set, /**< global SCIP settings */
1491  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1492  SCIP_Real oldval, /**< old value of the constant */
1493  SCIP_Real newval /**< new value of the constant */
1494  )
1495 {
1496  assert(row != NULL);
1497  assert(row->eventfilter != NULL);
1498 
1499  /* check, if the row is being tracked for coefficient changes
1500  * if so, issue ROWCONSTCHANGED event
1501  */
1502  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED)) )
1503  {
1504  SCIP_EVENT* event;
1505 
1506  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1507  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1508  }
1509 
1510  return SCIP_OKAY;
1511 }
1512 
1513 /** issues a ROWSIDECHANGED event on the given row */
1514 static
1516  SCIP_ROW* row, /**< row which coefficient has changed */
1517  BMS_BLKMEM* blkmem, /**< block memory */
1518  SCIP_SET* set, /**< global SCIP settings */
1519  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1520  SCIP_SIDETYPE side, /**< the side that has changed */
1521  SCIP_Real oldval, /**< old value of side */
1522  SCIP_Real newval /**< new value of side */
1523  )
1524 {
1525  assert(row != NULL);
1526  assert(row->eventfilter != NULL);
1527 
1528  /* check, if the row is being tracked for coefficient changes
1529  * if so, issue ROWSIDECHANGED event
1530  */
1531  if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
1532  {
1533  SCIP_EVENT* event;
1534 
1535  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1536  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1537  }
1538 
1539  return SCIP_OKAY;
1540 }
1541 
1542 #ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1543 
1544 #ifdef NDEBUG
1545 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1546 #else
1547 #define ASSERT(x) assert(x)
1548 #endif
1549 
1550 static SCIP_Bool msgdisp_checklinks = FALSE;
1551 
1552 
1553 static
1554 void checkLinks(
1555  SCIP_LP* lp /**< current LP data */
1556  )
1557 {
1558  SCIP_COL* col;
1559  SCIP_ROW* row;
1560  int i;
1561  int j;
1562 
1563  ASSERT(lp != NULL);
1564 
1565  if( !msgdisp_checklinks )
1566  {
1567  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1568  msgdisp_checklinks = TRUE;
1569  }
1570 
1571  for( i = 0; i < lp->ncols; ++i )
1572  {
1573  col = lp->cols[i];
1574  ASSERT(col != NULL);
1575  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1576  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1577  ASSERT(col->nlprows <= col->len);
1578  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1579 
1580  for( j = 0; j < col->len; ++j )
1581  {
1582  row = col->rows[j];
1583  ASSERT(row != NULL);
1584  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1585  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1586  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1587  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1588  }
1589  }
1590 
1591  for( i = 0; i < lp->nrows; ++i )
1592  {
1593  row = lp->rows[i];
1594  ASSERT(row != NULL);
1595  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1596  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1597  ASSERT(row->nlpcols <= row->len);
1598  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1599 
1600  for( j = 0; j < row->len; ++j )
1601  {
1602  col = row->cols[j];
1603  ASSERT(col != NULL);
1604  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1605  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1606  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1607  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1608  }
1609  }
1610 }
1611 
1612 #undef ASSERT
1613 
1614 #else
1615 #define checkLinks(lp) /**/
1616 #endif
1617 
1618 /*
1619  * Changing announcements
1620  */
1621 
1622 /** announces, that the given coefficient in the constraint matrix changed */
1623 static
1625  SCIP_ROW* row, /**< LP row */
1626  SCIP_COL* col, /**< LP col */
1627  SCIP_LP* lp /**< current LP data */
1628  )
1629 {
1630  assert(row != NULL);
1631  assert(col != NULL);
1632  assert(lp != NULL);
1633 
1634  if( row->lpipos >= 0 && col->lpipos >= 0 )
1635  {
1636  assert(row->lpipos < lp->nlpirows);
1637  assert(col->lpipos < lp->nlpicols);
1638 
1639  /* we have to remember the change only in the row or in the column,
1640  * because the readdition of one vector would change the other automatically.
1641  */
1642  if( row->lpipos >= lp->lpifirstchgrow )
1643  row->coefchanged = TRUE;
1644  else if( col->lpipos >= lp->lpifirstchgcol )
1645  col->coefchanged = TRUE;
1646  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1647  {
1648  row->coefchanged = TRUE;
1649  lp->lpifirstchgrow = row->lpipos;
1650  }
1651  else
1652  {
1653  col->coefchanged = TRUE;
1654  lp->lpifirstchgcol = col->lpipos;
1655  }
1656 
1657  /* mark the current LP unflushed */
1658  lp->flushed = FALSE;
1659  }
1660 
1662  row->minactivity = SCIP_INVALID;
1663  row->maxactivity = SCIP_INVALID;
1664  row->validpsactivitydomchg = -1;
1665  row->validactivitybdsdomchg = -1;
1666 }
1667 
1668 
1669 
1670 /*
1671  * local column changing methods
1672  */
1673 
1674 /* forward declaration for colAddCoef() */
1675 static
1677  SCIP_ROW* row, /**< LP row */
1678  BMS_BLKMEM* blkmem, /**< block memory */
1679  SCIP_SET* set, /**< global SCIP settings */
1680  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1681  SCIP_LP* lp, /**< current LP data */
1682  SCIP_COL* col, /**< LP column */
1683  SCIP_Real val, /**< value of coefficient */
1684  int linkpos /**< position of row in the column's row array, or -1 */
1685  );
1686 
1687 /** adds a previously non existing coefficient to an LP column */
1688 static
1690  SCIP_COL* col, /**< LP column */
1691  BMS_BLKMEM* blkmem, /**< block memory */
1692  SCIP_SET* set, /**< global SCIP settings */
1693  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1694  SCIP_LP* lp, /**< current LP data */
1695  SCIP_ROW* row, /**< LP row */
1696  SCIP_Real val, /**< value of coefficient */
1697  int linkpos /**< position of column in the row's col array, or -1 */
1698  )
1699 {
1700  int pos;
1701 
1702  assert(blkmem != NULL);
1703  assert(col != NULL);
1704  assert(col->nlprows <= col->len);
1705  assert(col->var != NULL);
1706  assert(row != NULL);
1707  assert(!SCIPsetIsZero(set, val));
1708  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1709 
1710  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1711  assert(col->rows != NULL);
1712  assert(col->vals != NULL);
1713  assert(col->linkpos != NULL);
1714 
1715  pos = col->len;
1716  col->len++;
1717 
1718  /* if the row is in current LP and is linked to the column, we have to insert it at the end of the linked LP rows
1719  * part of the column's arrays
1720  */
1721  if( row->lppos >= 0 && linkpos >= 0 )
1722  {
1723  /* move the first non-LP/not linked row to the end */
1724  if( col->nlprows < pos )
1725  {
1726  colMoveCoef(col, col->nlprows, pos);
1727  pos = col->nlprows;
1728  }
1729  col->nlprows++;
1730  }
1731 
1732  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1733  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1734 
1735  /* insert the row at the correct position and update the links */
1736  col->rows[pos] = row;
1737  col->vals[pos] = val;
1738  col->linkpos[pos] = linkpos;
1739  if( linkpos == -1 )
1740  {
1741  col->nunlinked++;
1742 
1743  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1744  * of the row is not complete
1745  */
1746  if( col->lppos >= 0 )
1747  {
1748  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1749  * has to be updated
1750  */
1751  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1752  if( row->lppos >= 0 )
1753  pos = col->nlprows-1;
1754  linkpos = col->linkpos[pos];
1755 
1756  assert(0 <= linkpos && linkpos < row->len);
1757  assert(row->cols[linkpos] == col);
1758  assert(col->rows[pos] == row);
1759  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1760  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1761  }
1762  }
1763  else
1764  {
1765  assert(row->linkpos[linkpos] == -1);
1766  assert(row->nunlinked > 0);
1767  row->linkpos[linkpos] = pos;
1768  row->nunlinked--;
1769 
1770  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1771  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1772  */
1773  if( col->lppos >= 0 )
1774  {
1775  row->nlpcols++;
1776  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1777 
1778  /* if no swap was necessary, mark nonlpcols to be unsorted */
1779  if( linkpos == row->nlpcols-1 )
1780  row->lpcolssorted = FALSE;
1781  }
1782  }
1783 
1784  /* update the sorted flags */
1785  if( row->lppos >= 0 && linkpos >= 0 )
1786  {
1787  assert(col->nlprows >= 1);
1788  assert(col->rows[col->nlprows-1] == row);
1789  if( col->nlprows > 1 )
1790  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1791  }
1792  else
1793  {
1794  assert(col->len - col->nlprows >= 1);
1795  assert(col->rows[col->len-1] == row);
1796  if( col->len - col->nlprows > 1 )
1797  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1798  }
1799 
1800  coefChanged(row, col, lp);
1801 
1802  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1803  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1804 
1805  return SCIP_OKAY;
1806 }
1807 
1808 /** deletes coefficient at given position from column */
1809 static
1811  SCIP_COL* col, /**< column to be changed */
1812  SCIP_SET* set, /**< global SCIP settings */
1813  SCIP_LP* lp, /**< current LP data */
1814  int pos /**< position in column vector to delete */
1815  )
1816 {
1817  SCIP_ROW* row;
1818 
1819  assert(col != NULL);
1820  assert(col->var != NULL);
1821  assert(set != NULL);
1822  assert(0 <= pos && pos < col->len);
1823  assert(col->rows[pos] != NULL);
1824  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1825  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1826 
1827  row = col->rows[pos];
1828  assert((row->lppos >= 0) == (pos < col->nlprows));
1829 
1830  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1831  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1832 
1833  if( col->linkpos[pos] == -1 )
1834  col->nunlinked--;
1835 
1836  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1837  if( pos < col->nlprows )
1838  {
1839  colMoveCoef(col, col->nlprows-1, pos);
1840  col->nlprows--;
1841  pos = col->nlprows;
1842  }
1843 
1844  /* move last coefficient to position of empty slot */
1845  colMoveCoef(col, col->len-1, pos);
1846  col->len--;
1847 
1848  coefChanged(row, col, lp);
1849 
1850  return SCIP_OKAY;
1851 }
1852 
1853 /** changes a coefficient at given position of an LP column */
1854 static
1856  SCIP_COL* col, /**< LP column */
1857  SCIP_SET* set, /**< global SCIP settings */
1858  SCIP_LP* lp, /**< current LP data */
1859  int pos, /**< position in column vector to change */
1860  SCIP_Real val /**< value of coefficient */
1861  )
1862 {
1863  assert(col != NULL);
1864  assert(col->var != NULL);
1865  assert(0 <= pos && pos < col->len);
1866  assert(col->rows[pos] != NULL);
1867  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1868 
1869  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1870  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1871 
1872  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1873  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1874 
1875  if( SCIPsetIsZero(set, val) )
1876  {
1877  /* delete existing coefficient */
1878  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1879  }
1880  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1881  {
1882  /* change existing coefficient */
1883  col->vals[pos] = val;
1884  coefChanged(col->rows[pos], col, lp);
1885  }
1886 
1887  return SCIP_OKAY;
1888 }
1889 
1890 
1891 
1892 
1893 /*
1894  * local row changing methods
1895  */
1896 
1897 /** update row norms after addition of coefficient */
1898 static
1900  SCIP_ROW* row, /**< LP row */
1901  SCIP_SET* set, /**< global SCIP settings */
1902  SCIP_COL* col, /**< column of added coefficient */
1903  SCIP_Real val, /**< value of added coefficient */
1904  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1905  )
1906 {
1907  SCIP_Real absval;
1908 
1909  assert(row != NULL);
1910  assert(row->nummaxval >= 0);
1911  assert(row->numminval >= 0);
1912  assert(set != NULL);
1913  assert(col != NULL);
1914 
1915  absval = REALABS(val);
1916  assert(!SCIPsetIsZero(set, absval));
1917 
1918  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1919  if( col->lppos >= 0 )
1920  {
1921  /* update squared Euclidean norm and sum norm */
1922  row->sqrnorm += SQR(absval);
1923  row->sumnorm += absval;
1924 
1925  /* update objective function scalar product */
1926  row->objprod += val * col->unchangedobj;
1927  }
1928 
1929  if( updateidxvals )
1930  {
1931  /* update min/maxidx */
1932  row->minidx = MIN(row->minidx, col->index);
1933  row->maxidx = MAX(row->maxidx, col->index);
1934 
1935  /* update maximal and minimal non-zero value */
1936  if( row->nummaxval > 0 )
1937  {
1938  if( SCIPsetIsGT(set, absval, row->maxval) )
1939  {
1940  row->maxval = absval;
1941  row->nummaxval = 1;
1942  }
1943  else if( SCIPsetIsGE(set, absval, row->maxval) )
1944  {
1945  /* make sure the maxval is always exactly the same */
1946  row->maxval = MAX(absval, row->maxval);
1947  row->nummaxval++;
1948  }
1949  }
1950  if( row->numminval > 0 )
1951  {
1952  if( SCIPsetIsLT(set, absval, row->minval) )
1953  {
1954  row->minval = absval;
1955  row->numminval = 1;
1956  }
1957  else if( SCIPsetIsLE(set, absval, row->minval) )
1958  {
1959  /* make sure the minval is always exactly the same */
1960  row->minval = MIN(absval, row->minval);
1961  row->numminval++;
1962  }
1963  }
1964  }
1965  else
1966  {
1967  assert(row->minidx <= col->index);
1968  assert(row->maxidx >= col->index);
1969  assert(row->numminval <= 0 || absval >= row->minval);
1970  assert(row->nummaxval <= 0 || absval <= row->maxval);
1971  }
1972 }
1973 
1974 /** update row norms after deletion of coefficient */
1975 static
1977  SCIP_ROW* row, /**< LP row */
1978  SCIP_SET* set, /**< global SCIP settings */
1979  SCIP_COL* col, /**< column of deleted coefficient */
1980  SCIP_Real val, /**< value of deleted coefficient */
1981  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1982  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1983  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1984  )
1985 {
1986  SCIP_Real absval;
1987 
1988  assert(row != NULL);
1989  assert(row->nummaxval >= 0);
1990  assert(row->numminval >= 0);
1991  assert(set != NULL);
1992  assert(col != NULL);
1993 
1994  absval = REALABS(val);
1995  assert(!SCIPsetIsZero(set, absval));
1996  assert(row->nummaxval == 0 || row->maxval >= absval);
1997  assert(row->numminval == 0 || row->minval <= absval);
1998 
1999  /* update min/maxidx validity */
2000  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
2001  row->validminmaxidx = FALSE;
2002 
2003  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
2004  if( forcenormupdate || col->lppos >= 0 )
2005  {
2006  /* update squared Euclidean norm and sum norm */
2007  row->sqrnorm -= SQR(absval);
2008  row->sqrnorm = MAX(row->sqrnorm, 0.0);
2009  row->sumnorm -= absval;
2010  row->sumnorm = MAX(row->sumnorm, 0.0);
2011 
2012  /* update objective function scalar product */
2013  row->objprod -= val * col->unchangedobj;
2014  }
2015 
2016  if( updateval )
2017  {
2018  /* update maximal and minimal non-zero value */
2019  if( row->nummaxval > 0 )
2020  {
2021  if( SCIPsetIsGE(set, absval, row->maxval) )
2022  row->nummaxval--;
2023  }
2024  if( row->numminval > 0 )
2025  {
2026  if( SCIPsetIsLE(set, absval, row->minval) )
2027  row->numminval--;
2028  }
2029  }
2030 }
2031 
2032 /** adds a previously non existing coefficient to an LP row */
2033 static
2035  SCIP_ROW* row, /**< LP row */
2036  BMS_BLKMEM* blkmem, /**< block memory */
2037  SCIP_SET* set, /**< global SCIP settings */
2038  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2039  SCIP_LP* lp, /**< current LP data */
2040  SCIP_COL* col, /**< LP column */
2041  SCIP_Real val, /**< value of coefficient */
2042  int linkpos /**< position of row in the column's row array, or -1 */
2043  )
2044 {
2045  int pos;
2046 
2047  assert(row != NULL);
2048  assert(row->nlpcols <= row->len);
2049  assert(blkmem != NULL);
2050  assert(col != NULL);
2051  assert(col->var != NULL);
2052  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2053  assert(!SCIPsetIsZero(set, val));
2054  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2055 
2056  if( row->nlocks > 0 )
2057  {
2058  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2059  return SCIP_INVALIDDATA;
2060  }
2061 
2062  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2063  assert(row->cols != NULL);
2064  assert(row->vals != NULL);
2065 
2066  pos = row->len;
2067  row->len++;
2068 
2069  /* if the column is in current LP and is linked to the row, we have to insert it at the end of the linked LP columns
2070  * part of the row's arrays
2071  */
2072  if( col->lppos >= 0 && linkpos >= 0 )
2073  {
2074  /* move the first non-LP/not linked column to the end */
2075  if( row->nlpcols < pos )
2076  {
2077  rowMoveCoef(row, row->nlpcols, pos);
2078  pos = row->nlpcols;
2079  }
2080  row->nlpcols++;
2081  }
2082 
2083  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2084  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2085 
2086  /* insert the column at the correct position and update the links */
2087  row->cols[pos] = col;
2088  row->cols_index[pos] = col->index;
2089  row->vals[pos] = val;
2090  row->linkpos[pos] = linkpos;
2091  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2092  if( linkpos == -1 )
2093  {
2094  row->nunlinked++;
2095 
2096  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2097  * of the column is not complete
2098  */
2099  if( row->lppos >= 0 )
2100  {
2101  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2102  * has to be updated
2103  */
2104  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2105  if( col->lppos >= 0 )
2106  pos = row->nlpcols-1;
2107  linkpos = row->linkpos[pos];
2108 
2109  assert(0 <= linkpos && linkpos < col->len);
2110  assert(col->rows[linkpos] == row);
2111  assert(row->cols[pos] == col);
2112  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2113  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2114  }
2115  }
2116  else
2117  {
2118  assert(col->linkpos[linkpos] == -1);
2119  assert(col->nunlinked > 0);
2120  col->linkpos[linkpos] = pos;
2121  col->nunlinked--;
2122 
2123  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2124  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2125  */
2126  if( row->lppos >= 0 )
2127  {
2128  col->nlprows++;
2129  colSwapCoefs(col, linkpos, col->nlprows-1);
2130 
2131  /* if no swap was necessary, mark lprows to be unsorted */
2132  if( linkpos == col->nlprows-1 )
2133  col->lprowssorted = FALSE;
2134  }
2135  }
2136 
2137  /* update the sorted flags */
2138  if( col->lppos >= 0 && linkpos >= 0 )
2139  {
2140  assert(row->nlpcols >= 1);
2141  assert(row->cols[row->nlpcols-1] == col);
2142  if( row->nlpcols > 1 )
2143  {
2144  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2145  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2146  }
2147  }
2148  else
2149  {
2150  assert(row->len - row->nlpcols >= 1);
2151  assert(row->cols[row->len-1] == col);
2152  if( row->len - row->nlpcols > 1 )
2153  {
2154  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2155  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2156  }
2157  }
2158 
2159  /* update row norm */
2160  rowAddNorms(row, set, col, val, TRUE);
2161 
2162  coefChanged(row, col, lp);
2163 
2164  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2165  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2166 
2167  /* issue row coefficient changed event */
2168  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2169 
2170  return SCIP_OKAY;
2171 }
2172 
2173 /** deletes coefficient at given position from row */
2174 static
2176  SCIP_ROW* row, /**< row to be changed */
2177  BMS_BLKMEM* blkmem, /**< block memory */
2178  SCIP_SET* set, /**< global SCIP settings */
2179  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2180  SCIP_LP* lp, /**< current LP data */
2181  int pos /**< position in row vector to delete */
2182  )
2183 {
2184  SCIP_COL* col;
2185  SCIP_Real val;
2186 
2187  assert(row != NULL);
2188  assert(set != NULL);
2189  assert(0 <= pos && pos < row->len);
2190  assert(row->cols[pos] != NULL);
2191  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2192 
2193  col = row->cols[pos];
2194  val = row->vals[pos];
2195  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2196 
2197  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2198  val, SCIPvarGetName(col->var), pos, row->name);*/
2199 
2200  if( row->nlocks > 0 )
2201  {
2202  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2203  return SCIP_INVALIDDATA;
2204  }
2205 
2206  if( row->linkpos[pos] == -1 )
2207  row->nunlinked--;
2208 
2209  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2210  if( pos < row->nlpcols )
2211  {
2212  rowMoveCoef(row, row->nlpcols-1, pos);
2213  assert(!row->lpcolssorted);
2214  row->nlpcols--;
2215  pos = row->nlpcols;
2216  }
2217 
2218  /* move last coefficient to position of empty slot */
2219  rowMoveCoef(row, row->len-1, pos);
2220  row->len--;
2221 
2222  /* update norms */
2223  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2224 
2225  coefChanged(row, col, lp);
2226 
2227  /* issue row coefficient changed event */
2228  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2229 
2230  return SCIP_OKAY;
2231 }
2232 
2233 /** changes a coefficient at given position of an LP row */
2234 static
2236  SCIP_ROW* row, /**< LP row */
2237  BMS_BLKMEM* blkmem, /**< block memory */
2238  SCIP_SET* set, /**< global SCIP settings */
2239  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2240  SCIP_LP* lp, /**< current LP data */
2241  int pos, /**< position in row vector to change */
2242  SCIP_Real val /**< value of coefficient */
2243  )
2244 {
2245  SCIP_COL* col;
2246 
2247  assert(row != NULL);
2248  assert(0 <= pos && pos < row->len);
2249 
2250  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2251  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2252 
2253  if( row->nlocks > 0 )
2254  {
2255  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2256  return SCIP_INVALIDDATA;
2257  }
2258 
2259  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2260  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2261  col = row->cols[pos];
2262  assert(row->cols[pos] != NULL);
2263 
2264  if( SCIPsetIsZero(set, val) )
2265  {
2266  /* delete existing coefficient */
2267  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2268  }
2269  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2270  {
2271  SCIP_Real oldval;
2272 
2273  oldval = row->vals[pos];
2274 
2275  /* change existing coefficient */
2276  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2277  row->vals[pos] = val;
2278  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2279  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2280  coefChanged(row, col, lp);
2281 
2282  /* issue row coefficient changed event */
2283  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2284  }
2285 
2286  return SCIP_OKAY;
2287 }
2288 
2289 /** notifies LP row, that its sides were changed */
2290 static
2292  SCIP_ROW* row, /**< LP row */
2293  SCIP_SET* set, /**< global SCIP settings */
2294  SCIP_LP* lp, /**< current LP data */
2295  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2296  )
2297 {
2298  assert(row != NULL);
2299  assert(lp != NULL);
2300 
2301  if( row->lpipos >= 0 )
2302  {
2303  /* insert row in the chgrows list (if not already there) */
2304  if( !row->lhschanged && !row->rhschanged )
2305  {
2306  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2307  lp->chgrows[lp->nchgrows] = row;
2308  lp->nchgrows++;
2309  }
2310 
2311  /* mark side change in the row */
2312  switch( sidetype )
2313  {
2314  case SCIP_SIDETYPE_LEFT:
2315  row->lhschanged = TRUE;
2316  break;
2317  case SCIP_SIDETYPE_RIGHT:
2318  row->rhschanged = TRUE;
2319  break;
2320  default:
2321  SCIPerrorMessage("unknown row side type\n");
2322  SCIPABORT();
2323  return SCIP_INVALIDDATA; /*lint !e527*/
2324  }
2325 
2326  /* mark the current LP unflushed */
2327  lp->flushed = FALSE;
2328 
2329  assert(lp->nchgrows > 0);
2330  }
2331 
2332  return SCIP_OKAY;
2333 }
2334 
2335 
2336 
2337 
2338 /*
2339  * double linked coefficient matrix methods
2340  */
2341 
2342 /** insert column coefficients in corresponding rows */
2343 static
2345  SCIP_COL* col, /**< column data */
2346  BMS_BLKMEM* blkmem, /**< block memory */
2347  SCIP_SET* set, /**< global SCIP settings */
2348  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2349  SCIP_LP* lp /**< current LP data */
2350  )
2351 {
2352  int i;
2353 
2354  assert(col != NULL);
2355  assert(col->var != NULL);
2356  assert(blkmem != NULL);
2357  assert(set != NULL);
2358  assert(lp != NULL);
2359 
2360  if( col->nunlinked > 0 )
2361  {
2362  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2363 
2364  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2365  for( i = col->nlprows; i < col->len; ++i )
2366  {
2367  assert(!SCIPsetIsZero(set, col->vals[i]));
2368  if( col->linkpos[i] == -1 )
2369  {
2370  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2371  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2372  }
2373  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2374  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2375  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2376  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2377  }
2378  }
2379  assert(col->nunlinked == 0);
2380 
2381  checkLinks(lp);
2382 
2383  return SCIP_OKAY;
2384 }
2385 
2386 /** removes column coefficients from corresponding rows */
2387 static
2389  SCIP_COL* col, /**< column data */
2390  BMS_BLKMEM* blkmem, /**< block memory */
2391  SCIP_SET* set, /**< global SCIP settings */
2392  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2393  SCIP_LP* lp /**< current LP data */
2394  )
2395 {
2396  int i;
2397 
2398  assert(col != NULL);
2399  assert(col->var != NULL);
2400  assert(blkmem != NULL);
2401  assert(set != NULL);
2402  assert(lp != NULL);
2403 
2404  if( col->nunlinked < col->len )
2405  {
2406  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2407  for( i = 0; i < col->len; ++i )
2408  {
2409  if( col->linkpos[i] >= 0 )
2410  {
2411  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2412  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2413  col->linkpos[i] = -1;
2414  col->nunlinked++;
2415  }
2416  }
2417  }
2418  assert(col->nunlinked == col->len);
2419 
2420  checkLinks(lp);
2421 
2422  return SCIP_OKAY;
2423 }
2424 
2425 /** insert row coefficients in corresponding columns */
2426 static
2428  SCIP_ROW* row, /**< row data */
2429  BMS_BLKMEM* blkmem, /**< block memory */
2430  SCIP_SET* set, /**< global SCIP settings */
2431  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2432  SCIP_LP* lp /**< current LP data */
2433  )
2434 {
2435  int i;
2436 
2437  assert(row != NULL);
2438  assert(blkmem != NULL);
2439  assert(set != NULL);
2440  assert(lp != NULL);
2441 
2442  if( row->nunlinked > 0 )
2443  {
2444  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2445 
2446  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2447  for( i = row->nlpcols; i < row->len; ++i )
2448  {
2449  assert(!SCIPsetIsZero(set, row->vals[i]));
2450  if( row->linkpos[i] == -1 )
2451  {
2452  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2453  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2454  }
2455  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2456  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2457  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2458  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2459  }
2460  }
2461  assert(row->nunlinked == 0);
2462 
2463  checkLinks(lp);
2464 
2465  return SCIP_OKAY;
2466 }
2467 
2468 /** removes row coefficients from corresponding columns */
2469 static
2471  SCIP_ROW* row, /**< row data */
2472  SCIP_SET* set, /**< global SCIP settings */
2473  SCIP_LP* lp /**< current LP data */
2474  )
2475 {
2476  int i;
2477 
2478  assert(row != NULL);
2479  assert(set != NULL);
2480  assert(lp != NULL);
2481 
2482  if( row->nunlinked < row->len )
2483  {
2484  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2485  for( i = 0; i < row->len; ++i )
2486  {
2487  if( row->linkpos[i] >= 0 )
2488  {
2489  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2490  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2491  row->nunlinked++;
2492  }
2493  }
2494  }
2495  assert(row->nunlinked == row->len);
2496 
2497  return SCIP_OKAY;
2498 }
2499 
2500 
2501 
2502 
2503 /*
2504  * local LP parameter methods
2505  */
2506 
2507 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2508 static
2510  SCIP_LP* lp, /**< current LP data */
2511  SCIP_LPPARAM lpparam, /**< LP parameter */
2512  int value, /**< value to set parameter to */
2513  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2514  )
2515 {
2516  SCIP_RETCODE retcode;
2517 
2518  assert(lp != NULL);
2519  assert(success != NULL);
2520 
2521  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2522 
2523  /* check, if parameter is unknown */
2524  if( retcode == SCIP_PARAMETERUNKNOWN )
2525  {
2526  *success = FALSE;
2527  return SCIP_OKAY;
2528  }
2529  *success = TRUE;
2530 
2531  return retcode;
2532 }
2533 
2534 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2535 static
2537  SCIP_LP* lp, /**< current LP data */
2538  SCIP_LPPARAM lpparam, /**< LP parameter */
2539  SCIP_Bool value, /**< value to set parameter to */
2540  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2541  )
2542 {
2543  return lpSetIntpar(lp, lpparam, (int)value, success);
2544 }
2545 
2546 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2547 static
2549  SCIP_LP* lp, /**< current LP data */
2550  SCIP_LPPARAM lpparam, /**< LP parameter */
2551  SCIP_Real value, /**< value to set parameter to */
2552  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2553  )
2554 {
2555  SCIP_RETCODE retcode;
2556 
2557  assert(lp != NULL);
2558  assert(success != NULL);
2559 
2560  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2561 
2562  /* check, if parameter is unknown */
2563  if( retcode == SCIP_PARAMETERUNKNOWN )
2564  {
2565  *success = FALSE;
2566  return SCIP_OKAY;
2567  }
2568  *success = TRUE;
2569 
2570  return retcode;
2571 }
2572 
2573 #ifndef NDEBUG
2574 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2575 static
2577  SCIP_LP* lp, /**< current LP data */
2578  SCIP_LPPARAM lpparam, /**< LP parameter */
2579  int value /**< value parameter should have */
2580  )
2581 {
2582  SCIP_RETCODE retcode;
2583  int lpivalue;
2584 
2585  assert(lp != NULL);
2586 
2587  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2588 
2589  /* ignore unknown parameter error */
2590  if( retcode == SCIP_PARAMETERUNKNOWN )
2591  return SCIP_OKAY;
2592 
2593  /* check value */
2594  assert(lpivalue == value);
2595 
2596  return retcode;
2597 }
2598 
2599 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2600 static
2602  SCIP_LP* lp, /**< current LP data */
2603  SCIP_LPPARAM lpparam, /**< LP parameter */
2604  SCIP_Bool value /**< value parameter should have */
2605  )
2606 {
2607  return lpCheckIntpar(lp, lpparam, (int)value);
2608 }
2609 
2610 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2611 static
2613  SCIP_LP* lp, /**< current LP data */
2614  SCIP_LPPARAM lpparam, /**< LP parameter */
2615  SCIP_Real value /**< value parameter should have */
2616  )
2617 {
2618  SCIP_RETCODE retcode;
2619  SCIP_Real lpivalue;
2620 
2621  assert(lp != NULL);
2622 
2623  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2624 
2625  /* ignore unknown parameter error */
2626  if( retcode == SCIP_PARAMETERUNKNOWN )
2627  return SCIP_OKAY;
2628 
2629  /* check value */
2630  assert(lpivalue == value); /*lint !e777*/
2631 
2632  return retcode;
2633 }
2634 #else
2635 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2636 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2637 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2638 #endif
2639 
2640 /** should the objective limit of the LP solver be disabled */
2641 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2642 
2643 /** sets the objective limit of the LP solver
2644  *
2645  * Note that we are always minimizing.
2646  */
2647 static
2649  SCIP_LP* lp, /**< current LP data */
2650  SCIP_SET* set, /**< global SCIP settings */
2651  SCIP_Real objlim, /**< new objective limit */
2652  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2653  )
2654 {
2655  assert(lp != NULL);
2656  assert(set != NULL);
2657  assert(success != NULL);
2658 
2659  *success = FALSE;
2660 
2661  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2662  * solver's objective limit handling, so we return here and do not apply the objective limit. */
2663  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2664  return SCIP_OKAY;
2665 
2666  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2667  if( SCIPsetIsInfinity(set, objlim) )
2668  objlim = SCIPlpiInfinity(lp->lpi);
2669 
2671 
2672  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2673  {
2674  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2675  if( *success )
2676  {
2677  SCIP_Real actualobjlim;
2678 
2679  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2680  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2681  if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2682  {
2683  /* mark the current solution invalid */
2684  lp->solved = FALSE;
2685  lp->primalfeasible = FALSE;
2686  lp->primalchecked = FALSE;
2687  lp->lpobjval = SCIP_INVALID;
2689  }
2690  lp->lpiobjlim = actualobjlim;
2691  }
2692  }
2693 
2694  return SCIP_OKAY;
2695 }
2696 
2697 /** sets the feasibility tolerance of the LP solver */
2698 static
2700  SCIP_LP* lp, /**< current LP data */
2701  SCIP_Real feastol, /**< new feasibility tolerance */
2702  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2703  )
2704 {
2705  assert(lp != NULL);
2706  assert(feastol >= 0.0);
2707  assert(success != NULL);
2708 
2710 
2711  if( feastol != lp->lpifeastol ) /*lint !e777*/
2712  {
2713  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2714  if( *success )
2715  {
2716  SCIP_Real actualfeastol;
2717 
2718  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2719  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2720  if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2721  {
2722  /* mark the current solution invalid */
2723  lp->solved = FALSE;
2724  lp->primalfeasible = FALSE;
2725  lp->primalchecked = FALSE;
2726  lp->lpobjval = SCIP_INVALID;
2728  }
2729  else
2730  *success = FALSE;
2731  lp->lpifeastol = actualfeastol;
2732  }
2733  }
2734  else
2735  *success = FALSE;
2736 
2737  return SCIP_OKAY;
2738 }
2739 
2740 /** sets the reduced costs feasibility tolerance of the LP solver */
2741 static
2743  SCIP_LP* lp, /**< current LP data */
2744  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2745  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2746  )
2747 {
2748  assert(lp != NULL);
2749  assert(dualfeastol >= 0.0);
2750  assert(success != NULL);
2751 
2753 
2754  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2755  {
2756  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2757  if( *success )
2758  {
2759  SCIP_Real actualdualfeastol;
2760 
2761  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2762  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2763  if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2764  {
2765  /* mark the current solution invalid */
2766  lp->solved = FALSE;
2767  lp->dualfeasible = FALSE;
2768  lp->dualchecked = FALSE;
2769  lp->lpobjval = SCIP_INVALID;
2771  }
2772  else
2773  *success = FALSE;
2774  lp->lpidualfeastol = actualdualfeastol;
2775  }
2776  }
2777  else
2778  *success = FALSE;
2779 
2780  return SCIP_OKAY;
2781 }
2782 
2783 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2784 static
2786  SCIP_LP* lp, /**< current LP data */
2787  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2788  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2789  )
2790 {
2791  assert(lp != NULL);
2792  assert(barrierconvtol >= 0.0);
2793  assert(success != NULL);
2794 
2796 
2797  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2798  {
2799  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2800  if( *success )
2801  {
2802  SCIP_Real actualbarrierconvtol;
2803 
2804  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2805  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
2806  if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
2808  {
2809  /* mark the current solution invalid */
2810  lp->solved = FALSE;
2811  lp->dualfeasible = FALSE;
2812  lp->dualchecked = FALSE;
2813  lp->lpobjval = SCIP_INVALID;
2815  }
2816  else
2817  *success = FALSE;
2818  lp->lpibarrierconvtol = actualbarrierconvtol;
2819  }
2820  }
2821  else
2822  *success = FALSE;
2823 
2824  return SCIP_OKAY;
2825 }
2826 
2827 /** sets the FROMSCRATCH setting of the LP solver */
2828 static
2830  SCIP_LP* lp, /**< current LP data */
2831  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2832  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2833  )
2834 {
2835  assert(lp != NULL);
2836  assert(success != NULL);
2837 
2839 
2840  if( fromscratch != lp->lpifromscratch )
2841  {
2842  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2843  if( *success )
2844  lp->lpifromscratch = fromscratch;
2845  }
2846  else
2847  *success = FALSE;
2848 
2849  return SCIP_OKAY;
2850 }
2851 
2852 /** sets the FASTMIP setting of the LP solver */
2853 static
2855  SCIP_LP* lp, /**< current LP data */
2856  int fastmip, /**< new FASTMIP setting */
2857  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2858  )
2859 {
2860  assert(lp != NULL);
2861  assert(success != NULL);
2862  assert(0 <= fastmip && fastmip <= 1);
2863 
2865 
2866  if( fastmip != lp->lpifastmip )
2867  {
2868  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2869  if( *success )
2870  {
2871  lp->lpifastmip = fastmip;
2872  lp->solved = FALSE;
2873  /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
2874  * demanding setting; however, in the current code, this should have not effect. */
2875  }
2876  }
2877  else
2878  *success = FALSE;
2879 
2880  return SCIP_OKAY;
2881 }
2882 
2883 /** sets the SCALING setting of the LP solver */
2884 static
2886  SCIP_LP* lp, /**< current LP data */
2887  int scaling, /**< new SCALING setting */
2888  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2889  )
2890 {
2891  assert(lp != NULL);
2892  assert(success != NULL);
2893 
2895 
2896  if( scaling != lp->lpiscaling )
2897  {
2898  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2899  if( *success )
2900  lp->lpiscaling = scaling;
2901  }
2902  else
2903  *success = FALSE;
2904 
2905  return SCIP_OKAY;
2906 }
2907 
2908 /** sets the number of THREADS of the LP solver */
2909 static
2911  SCIP_LP* lp, /**< current LP data */
2912  int threads, /**< new number of threads used to solve the LP */
2913  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2914  )
2915 {
2916  assert(lp != NULL);
2917  assert(success != NULL);
2918 
2920 
2921  if( threads != lp->lpithreads )
2922  {
2923  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2924  if( *success )
2925  lp->lpithreads = threads;
2926  }
2927  else
2928  *success = FALSE;
2929 
2930  return SCIP_OKAY;
2931 }
2932 
2933 /** sets the PRESOLVING setting of the LP solver */
2934 static
2936  SCIP_LP* lp, /**< current LP data */
2937  SCIP_Bool presolving, /**< new PRESOLVING setting */
2938  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2939  )
2940 {
2941  assert(lp != NULL);
2942  assert(success != NULL);
2943 
2945 
2946  if( presolving != lp->lpipresolving )
2947  {
2948  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2949  if( *success )
2950  lp->lpipresolving = presolving;
2951  }
2952  else
2953  *success = FALSE;
2954 
2955  return SCIP_OKAY;
2956 }
2957 
2958 /** sets the ROWREPSWITCH setting of the LP solver */
2959 static
2961  SCIP_LP* lp, /**< current LP data */
2962  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2963  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2964  )
2965 {
2966  assert(lp != NULL);
2967  assert(success != NULL);
2968 
2970 
2971  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2972  {
2973  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2974  if( *success )
2975  lp->lpirowrepswitch = rowrepswitch;
2976  }
2977  else
2978  *success = FALSE;
2979 
2980  return SCIP_OKAY;
2981 }
2982 
2983 /** sets the iteration limit of the LP solver */
2984 static
2986  SCIP_LP* lp, /**< current LP data */
2987  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2988  )
2989 {
2990  SCIP_Bool success;
2991 
2992  assert(lp != NULL);
2993  assert(itlim >= -1);
2994 
2995  if( itlim == -1 )
2996  itlim = INT_MAX;
2997 
2999 
3000  if( itlim != lp->lpiitlim )
3001  {
3002  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
3003  if( success )
3004  {
3005  if( itlim > lp->lpiitlim )
3006  {
3007  /* mark the current solution invalid */
3008  lp->solved = FALSE;
3009  lp->lpobjval = SCIP_INVALID;
3011  }
3012  lp->lpiitlim = itlim;
3013  }
3014  }
3015 
3016  return SCIP_OKAY;
3017 }
3018 
3019 /** sets the pricing strategy of the LP solver */
3020 static
3022  SCIP_LP* lp, /**< current LP data */
3023  SCIP_PRICING pricing /**< pricing strategy */
3024  )
3025 {
3026  SCIP_Bool success;
3027 
3028  assert(lp != NULL);
3029 
3031 
3032  if( pricing != lp->lpipricing )
3033  {
3034  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3035  if( success )
3036  lp->lpipricing = pricing;
3037  }
3038 
3039  return SCIP_OKAY;
3040 }
3041 
3042 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3043 static
3045  SCIP_LP* lp, /**< current LP data */
3046  char pricingchar /**< character representing the pricing strategy */
3047  )
3048 {
3050 
3051  switch( pricingchar )
3052  {
3053  case 'l':
3054  pricing = SCIP_PRICING_LPIDEFAULT;
3055  break;
3056  case 'a':
3057  pricing = SCIP_PRICING_AUTO;
3058  break;
3059  case 'f':
3060  pricing = SCIP_PRICING_FULL;
3061  break;
3062  case 'p':
3063  pricing = SCIP_PRICING_PARTIAL;
3064  break;
3065  case 's':
3066  pricing = SCIP_PRICING_STEEP;
3067  break;
3068  case 'q':
3069  pricing = SCIP_PRICING_STEEPQSTART;
3070  break;
3071  case 'd':
3072  pricing = SCIP_PRICING_DEVEX;
3073  break;
3074  default:
3075  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3076  return SCIP_INVALIDDATA;
3077  }
3078 
3079  SCIP_CALL( lpSetPricing(lp, pricing) );
3080 
3081  return SCIP_OKAY;
3082 }
3083 
3084 /** sets the verbosity of the LP solver */
3085 static
3087  SCIP_LP* lp, /**< current LP data */
3088  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3089  )
3090 {
3091  SCIP_Bool success;
3092 
3093  assert(lp != NULL);
3094 
3096 
3097  if( lpinfo != lp->lpilpinfo )
3098  {
3099  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3100  if( success )
3101  lp->lpilpinfo = lpinfo;
3102  }
3103 
3104  return SCIP_OKAY;
3105 }
3106 
3107 /** sets the CONDITIONLIMIT setting of the LP solver */
3108 static
3110  SCIP_LP* lp, /**< current LP data */
3111  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3112  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3113  )
3114 {
3115  assert(lp != NULL);
3116  assert(success != NULL);
3117 
3119 
3120  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3121  {
3122  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3123  if( *success )
3124  lp->lpiconditionlimit = condlimit;
3125  }
3126  else
3127  *success = FALSE;
3128 
3129  return SCIP_OKAY;
3130 }
3131 
3132 /** sets the MARKOWITZ setting of the LP solver */
3133 static
3135  SCIP_LP* lp, /**< current LP data */
3136  SCIP_Real threshhold, /**< new MARKOWITZ value */
3137  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3138  )
3139 {
3140  assert(lp != NULL);
3141  assert(success != NULL);
3142 
3144 
3145  if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3146  {
3147  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3148  if( *success )
3149  lp->lpimarkowitz = threshhold;
3150  }
3151  else
3152  *success = FALSE;
3153 
3154  return SCIP_OKAY;
3155 }
3156 
3157 /** sets the type of timer of the LP solver */
3158 static
3160  SCIP_LP* lp, /**< current LP data */
3161  SCIP_CLOCKTYPE timing, /**< new timing value */
3162  SCIP_Bool enabled, /**< is timing enabled? */
3163  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3164  )
3165 {
3166  int lptiming;
3167 
3168  assert(lp != NULL);
3169  assert(success != NULL);
3170  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*/
3171 
3173 
3174  if( !enabled )
3175  lptiming = 0;
3176  else
3177  lptiming = (int) timing;
3178 
3179  if( lptiming != lp->lpitiming ) /*lint !e777*/
3180  {
3181  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3182  if( *success )
3183  lp->lpitiming = lptiming;
3184  }
3185  else
3186  *success = FALSE;
3187 
3188  return SCIP_OKAY;
3189 }
3190 
3191 /** sets the initial random seed of the LP solver */
3192 static
3194  SCIP_LP* lp, /**< current LP data */
3195  int randomseed, /**< new initial random seed */
3196  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3197  )
3198 {
3199  assert(lp != NULL);
3200  assert(success != NULL);
3201 
3202  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3203 
3204  if( randomseed == 0 )
3205  {
3206  lp->lpirandomseed = randomseed;
3207  *success = TRUE;
3208  }
3209  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3210  {
3211  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3212  if( *success )
3213  lp->lpirandomseed = randomseed;
3214  }
3215  else
3216  *success = FALSE;
3217 
3218  return SCIP_OKAY;
3219 }
3220 
3221 /** sets the LP solution polishing method */
3222 static
3224  SCIP_LP* lp, /**< current LP data */
3225  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3226  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3227  )
3228 {
3229  assert(lp != NULL);
3230  assert(success != NULL);
3231 
3232  if( polishing != lp->lpisolutionpolishing )
3233  {
3234  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3235  if( *success )
3236  lp->lpisolutionpolishing = polishing;
3237  }
3238  else
3239  *success = FALSE;
3240 
3241  return SCIP_OKAY;
3242 }
3243 
3244 /** sets the LP refactorization interval */
3245 static
3247  SCIP_LP* lp, /**< current LP data */
3248  int refactor, /**< LP refactorization interval (0: automatic) */
3249  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3250  )
3251 {
3252  assert(lp != NULL);
3253  assert(success != NULL);
3254 
3255  if( refactor != lp->lpirefactorinterval )
3256  {
3257  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3258  if( *success )
3259  lp->lpirefactorinterval = refactor;
3260  }
3261  else
3262  *success = FALSE;
3263 
3264  return SCIP_OKAY;
3265 }
3266 
3267 
3268 /*
3269  * Column methods
3270  */
3271 
3272 /** creates an LP column */
3274  SCIP_COL** col, /**< pointer to column data */
3275  BMS_BLKMEM* blkmem, /**< block memory */
3276  SCIP_SET* set, /**< global SCIP settings */
3277  SCIP_STAT* stat, /**< problem statistics */
3278  SCIP_VAR* var, /**< variable, this column represents */
3279  int len, /**< number of nonzeros in the column */
3280  SCIP_ROW** rows, /**< array with rows of column entries */
3281  SCIP_Real* vals, /**< array with coefficients of column entries */
3282  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3283  )
3284 {
3285  int i;
3286 
3287  assert(col != NULL);
3288  assert(blkmem != NULL);
3289  assert(set != NULL);
3290  assert(stat != NULL);
3291  assert(var != NULL);
3292  assert(len >= 0);
3293  assert(len == 0 || (rows != NULL && vals != NULL));
3294 
3295  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3296 
3297  if( len > 0 )
3298  {
3299  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3300  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3301  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3302 
3303  for( i = 0; i < len; ++i )
3304  {
3305  assert(rows[i] != NULL);
3306  assert(!SCIPsetIsZero(set, vals[i]));
3307  (*col)->linkpos[i] = -1;
3308  }
3309  }
3310  else
3311  {
3312  (*col)->rows = NULL;
3313  (*col)->vals = NULL;
3314  (*col)->linkpos = NULL;
3315  }
3316 
3317  (*col)->var = var;
3318  (*col)->obj = SCIPvarGetObj(var);
3319  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3320  (*col)->lb = SCIPvarGetLbLocal(var);
3321  (*col)->ub = SCIPvarGetUbLocal(var);
3322  (*col)->flushedobj = 0.0;
3323  (*col)->flushedlb = 0.0;
3324  (*col)->flushedub = 0.0;
3325  (*col)->index = stat->ncolidx;
3326  SCIPstatIncrement(stat, set, ncolidx);
3327  (*col)->size = len;
3328  (*col)->len = len;
3329  (*col)->nlprows = 0;
3330  (*col)->nunlinked = len;
3331  (*col)->lppos = -1;
3332  (*col)->lpipos = -1;
3333  (*col)->lpdepth = -1;
3334  (*col)->primsol = 0.0;
3335  (*col)->redcost = SCIP_INVALID;
3336  (*col)->farkascoef = SCIP_INVALID;
3337  (*col)->minprimsol = (*col)->ub;
3338  (*col)->maxprimsol = (*col)->lb;
3339  (*col)->sbdown = SCIP_INVALID;
3340  (*col)->sbup = SCIP_INVALID;
3341  (*col)->sbsolval = SCIP_INVALID;
3342  (*col)->sblpobjval = SCIP_INVALID;
3343  (*col)->sbnode = -1;
3344  (*col)->validredcostlp = -1;
3345  (*col)->validfarkaslp = -1;
3346  (*col)->validsblp = -1;
3347  (*col)->sbitlim = -1;
3348  (*col)->nsbcalls = 0;
3349  (*col)->age = 0;
3350  (*col)->obsoletenode = -1;
3351  (*col)->var_probindex = SCIPvarGetProbindex(var);
3352  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3353  (*col)->lprowssorted = TRUE;
3354  (*col)->nonlprowssorted = (len <= 1);
3355  (*col)->objchanged = FALSE;
3356  (*col)->lbchanged = FALSE;
3357  (*col)->ubchanged = FALSE;
3358  (*col)->coefchanged = FALSE;
3359  (*col)->integral = SCIPvarIsIntegral(var);
3360  (*col)->removable = removable;
3361  (*col)->sbdownvalid = FALSE;
3362  (*col)->sbupvalid = FALSE;
3363  (*col)->lazylb = SCIPvarGetLbLazy(var);
3364  (*col)->lazyub = SCIPvarGetUbLazy(var);
3365  (*col)->storedsolvals = NULL;
3366 
3367  return SCIP_OKAY;
3368 }
3369 
3370 /** frees an LP column */
3372  SCIP_COL** col, /**< pointer to LP column */
3373  BMS_BLKMEM* blkmem, /**< block memory */
3374  SCIP_SET* set, /**< global SCIP settings */
3375  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3376  SCIP_LP* lp /**< current LP data */
3377  )
3378 {
3379  assert(blkmem != NULL);
3380  assert(col != NULL);
3381  assert(*col != NULL);
3382  assert((*col)->var != NULL);
3383  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3384  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3385  assert((*col)->lppos == -1);
3386  assert((*col)->lpipos == -1);
3387 
3388  /* remove column indices from corresponding rows */
3389  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3390 
3391  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3392  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3393  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3394  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3395  BMSfreeBlockMemory(blkmem, col);
3396 
3397  return SCIP_OKAY;
3398 }
3399 
3400 /** output column to file stream */
3402  SCIP_COL* col, /**< LP column */
3403  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3404  FILE* file /**< output file (or NULL for standard output) */
3405  )
3406 {
3407  int r;
3408 
3409  assert(col != NULL);
3410  assert(col->var != NULL);
3411 
3412  /* print bounds */
3413  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3414 
3415  /* print coefficients */
3416  if( col->len == 0 )
3417  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3418  for( r = 0; r < col->len; ++r )
3419  {
3420  assert(col->rows[r] != NULL);
3421  assert(col->rows[r]->name != NULL);
3422  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3423  }
3424  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3425 }
3426 
3427 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3428  */
3430  SCIP_COL* col /**< column to be sorted */
3431  )
3432 {
3433  /* sort LP rows */
3434  colSortLP(col);
3435 
3436  /* sort non-LP rows */
3437  colSortNonLP(col);
3438 }
3439 
3440 /** adds a previously non existing coefficient to an LP column */
3442  SCIP_COL* col, /**< LP column */
3443  BMS_BLKMEM* blkmem, /**< block memory */
3444  SCIP_SET* set, /**< global SCIP settings */
3445  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3446  SCIP_LP* lp, /**< current LP data */
3447  SCIP_ROW* row, /**< LP row */
3448  SCIP_Real val /**< value of coefficient */
3449  )
3450 {
3451  assert(lp != NULL);
3452  assert(!lp->diving);
3453 
3454  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3455 
3456  checkLinks(lp);
3457 
3458  return SCIP_OKAY;
3459 }
3460 
3461 /** deletes existing coefficient from column */
3463  SCIP_COL* col, /**< column to be changed */
3464  BMS_BLKMEM* blkmem, /**< block memory */
3465  SCIP_SET* set, /**< global SCIP settings */
3466  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3467  SCIP_LP* lp, /**< current LP data */
3468  SCIP_ROW* row /**< coefficient to be deleted */
3469  )
3470 {
3471  int pos;
3472 
3473  assert(col != NULL);
3474  assert(col->var != NULL);
3475  assert(lp != NULL);
3476  assert(!lp->diving);
3477  assert(row != NULL);
3478 
3479  /* search the position of the row in the column's row vector */
3480  pos = colSearchCoef(col, row);
3481  if( pos == -1 )
3482  {
3483  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3484  return SCIP_INVALIDDATA;
3485  }
3486  assert(0 <= pos && pos < col->len);
3487  assert(col->rows[pos] == row);
3488 
3489  /* if row knows of the column, remove the column from the row's col vector */
3490  if( col->linkpos[pos] >= 0 )
3491  {
3492  assert(row->cols[col->linkpos[pos]] == col);
3493  assert(row->cols_index[col->linkpos[pos]] == col->index);
3494  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3495  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3496  }
3497 
3498  /* delete the row from the column's row vector */
3499  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3500 
3501  checkLinks(lp);
3502 
3503  return SCIP_OKAY;
3504 }
3505 
3506 /** changes or adds a coefficient to an LP column */
3508  SCIP_COL* col, /**< LP column */
3509  BMS_BLKMEM* blkmem, /**< block memory */
3510  SCIP_SET* set, /**< global SCIP settings */
3511  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3512  SCIP_LP* lp, /**< current LP data */
3513  SCIP_ROW* row, /**< LP row */
3514  SCIP_Real val /**< value of coefficient */
3515  )
3516 {
3517  int pos;
3518 
3519  assert(col != NULL);
3520  assert(lp != NULL);
3521  assert(!lp->diving);
3522  assert(row != NULL);
3523 
3524  /* search the position of the row in the column's row vector */
3525  pos = colSearchCoef(col, row);
3526 
3527  /* check, if row already exists in the column's row vector */
3528  if( pos == -1 )
3529  {
3530  /* add previously not existing coefficient */
3531  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3532  }
3533  else
3534  {
3535  /* modify already existing coefficient */
3536  assert(0 <= pos && pos < col->len);
3537  assert(col->rows[pos] == row);
3538 
3539  /* if row knows of the column, change the corresponding coefficient in the row */
3540  if( col->linkpos[pos] >= 0 )
3541  {
3542  assert(row->cols[col->linkpos[pos]] == col);
3543  assert(row->cols_index[col->linkpos[pos]] == col->index);
3544  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3545  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3546  }
3547 
3548  /* change the coefficient in the column */
3549  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3550  }
3551 
3552  checkLinks(lp);
3553 
3554  return SCIP_OKAY;
3555 }
3556 
3557 /** increases value of an existing or non-existing coefficient in an LP column */
3559  SCIP_COL* col, /**< LP column */
3560  BMS_BLKMEM* blkmem, /**< block memory */
3561  SCIP_SET* set, /**< global SCIP settings */
3562  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3563  SCIP_LP* lp, /**< current LP data */
3564  SCIP_ROW* row, /**< LP row */
3565  SCIP_Real incval /**< value to add to the coefficient */
3566  )
3567 {
3568  int pos;
3569 
3570  assert(col != NULL);
3571  assert(lp != NULL);
3572  assert(!lp->diving);
3573  assert(row != NULL);
3574 
3575  if( SCIPsetIsZero(set, incval) )
3576  return SCIP_OKAY;
3577 
3578  /* search the position of the row in the column's row vector */
3579  pos = colSearchCoef(col, row);
3580 
3581  /* check, if row already exists in the column's row vector */
3582  if( pos == -1 )
3583  {
3584  /* add previously not existing coefficient */
3585  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3586  }
3587  else
3588  {
3589  /* modify already existing coefficient */
3590  assert(0 <= pos && pos < col->len);
3591  assert(col->rows[pos] == row);
3592 
3593  /* if row knows of the column, change the corresponding coefficient in the row */
3594  if( col->linkpos[pos] >= 0 )
3595  {
3596  assert(row->cols[col->linkpos[pos]] == col);
3597  assert(row->cols_index[col->linkpos[pos]] == col->index);
3598  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3599  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3600  }
3601 
3602  /* change the coefficient in the column */
3603  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3604  }
3605 
3606  checkLinks(lp);
3607 
3608  return SCIP_OKAY;
3609 }
3610 
3611 /** insert column in the chgcols list (if not already there) */
3612 static
3614  SCIP_COL* col, /**< LP column to change */
3615  SCIP_SET* set, /**< global SCIP settings */
3616  SCIP_LP* lp /**< current LP data */
3617  )
3618 {
3619  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3620  {
3621  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3622  lp->chgcols[lp->nchgcols] = col;
3623  lp->nchgcols++;
3624  }
3625 
3626  /* mark the current LP unflushed */
3627  lp->flushed = FALSE;
3628 
3629  return SCIP_OKAY;
3630 }
3631 
3632 /** Is the new value reliable or may we have cancellation?
3633  *
3634  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3635  * cancellations which can occur during increasing the oldvalue to the newvalue
3636  */
3637 static
3639  SCIP_SET* set, /**< global SCIP settings */
3640  SCIP_Real newvalue, /**< new value */
3641  SCIP_Real oldvalue /**< old reliable value */
3642  )
3643 {
3644  SCIP_Real quotient;
3645 
3646  assert(set != NULL);
3647  assert(oldvalue < SCIP_INVALID);
3648 
3649  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3650 
3651  return SCIPsetIsZero(set, quotient);
3652 }
3653 
3654 /** update norms of objective function vector */
3655 static
3657  SCIP_LP* lp, /**< current LP data */
3658  SCIP_SET* set, /**< global SCIP settings */
3659  SCIP_Real oldobj, /**< old objective value of variable */
3660  SCIP_Real newobj /**< new objective value of variable */
3661  )
3662 {
3663  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3664  {
3665  if( !lp->objsqrnormunreliable )
3666  {
3667  SCIP_Real oldvalue;
3668 
3669  oldvalue = lp->objsqrnorm;
3670  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3671 
3672  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3673  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3674  lp->objsqrnormunreliable = TRUE;
3675  else
3676  {
3677  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3678 
3679  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3680  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3681 
3682  assert(lp->objsqrnorm >= 0.0);
3683  }
3684  }
3685 
3686  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3687  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3688  }
3689 }
3690 
3691 /** changes objective value of column */
3693  SCIP_COL* col, /**< LP column to change */
3694  SCIP_SET* set, /**< global SCIP settings */
3695  SCIP_LP* lp, /**< current LP data */
3696  SCIP_Real newobj /**< new objective value */
3697  )
3698 {
3699  assert(col != NULL);
3700  assert(col->var != NULL);
3701  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3702  assert(SCIPvarGetCol(col->var) == col);
3703  assert(lp != NULL);
3704 
3705  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3706 
3707  /* only add actual changes */
3708  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3709  {
3710  /* only variables with a real position in the LPI can be inserted */
3711  if( col->lpipos >= 0 )
3712  {
3713  /* insert column in the chgcols list (if not already there) */
3714  SCIP_CALL( insertColChgcols(col, set, lp) );
3715 
3716  /* mark objective value change in the column */
3717  col->objchanged = TRUE;
3718 
3719  assert(lp->nchgcols > 0);
3720  }
3721  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3722  * LP and the LP has to be flushed
3723  */
3724  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3725  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3726  {
3727  /* mark the LP unflushed */
3728  lp->flushed = FALSE;
3729  }
3730  }
3731 
3732  /* store new objective function value */
3733  col->obj = newobj;
3734 
3735  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3736  if( !lp->divingobjchg )
3737  {
3738  SCIP_Real oldobj = col->unchangedobj;
3739 
3740  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3741  col->unchangedobj = newobj;
3742 
3743  /* update the objective function vector norms */
3744  lpUpdateObjNorms(lp, set, oldobj, newobj);
3745  }
3746 
3747  return SCIP_OKAY;
3748 }
3749 
3750 /** changes lower bound of column */
3752  SCIP_COL* col, /**< LP column to change */
3753  SCIP_SET* set, /**< global SCIP settings */
3754  SCIP_LP* lp, /**< current LP data */
3755  SCIP_Real newlb /**< new lower bound value */
3756  )
3757 {
3758  assert(col != NULL);
3759  assert(col->var != NULL);
3760  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3761  assert(SCIPvarGetCol(col->var) == col);
3762  assert(lp != NULL);
3763 
3764  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3765 
3766  /* only add actual changes */
3767  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3768  {
3769  /* only variables with a real position in the LPI can be inserted */
3770  if( col->lpipos >= 0 )
3771  {
3772  /* insert column in the chgcols list (if not already there) */
3773  SCIP_CALL( insertColChgcols(col, set, lp) );
3774 
3775  /* mark bound change in the column */
3776  col->lbchanged = TRUE;
3777 
3778  assert(lp->nchgcols > 0);
3779  }
3780  /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
3781  * flushed
3782  */
3783  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3784  {
3785  /* mark the LP unflushed */
3786  lp->flushed = FALSE;
3787  }
3788  }
3789 
3790  col->lb = newlb;
3791 
3792  return SCIP_OKAY;
3793 }
3794 
3795 /** changes upper bound of column */
3797  SCIP_COL* col, /**< LP column to change */
3798  SCIP_SET* set, /**< global SCIP settings */
3799  SCIP_LP* lp, /**< current LP data */
3800  SCIP_Real newub /**< new upper bound value */
3801  )
3802 {
3803  assert(col != NULL);
3804  assert(col->var != NULL);
3805  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3806  assert(SCIPvarGetCol(col->var) == col);
3807  assert(lp != NULL);
3808 
3809  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3810 
3811  /* only add actual changes */
3812  if( !SCIPsetIsEQ(set, col->ub, newub) )
3813  {
3814  /* only variables with a real position in the LPI can be inserted */
3815  if( col->lpipos >= 0 )
3816  {
3817  /* insert column in the chgcols list (if not already there) */
3818  SCIP_CALL( insertColChgcols(col, set, lp) );
3819 
3820  /* mark bound change in the column */
3821  col->ubchanged = TRUE;
3822 
3823  assert(lp->nchgcols > 0);
3824  }
3825  /* in any case, when the best bound is zero and gets changed, the variable has to enter the LP and the LP has to be
3826  * flushed
3827  */
3828  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3829  {
3830  /* mark the LP unflushed */
3831  lp->flushed = FALSE;
3832  }
3833  }
3834 
3835  col->ub = newub;
3836 
3837  return SCIP_OKAY;
3838 }
3839 
3840 /** calculates the reduced costs of a column using the given dual solution vector */
3842  SCIP_COL* col, /**< LP column */
3843  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3844  )
3845 {
3846  SCIP_ROW* row;
3847  SCIP_Real redcost;
3848  int i;
3849 
3850  assert(col != NULL);
3851  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3852  assert(SCIPvarGetCol(col->var) == col);
3853  assert(dualsol != NULL);
3854 
3855  redcost = col->obj;
3856  for( i = 0; i < col->nlprows; ++i )
3857  {
3858  row = col->rows[i];
3859  assert(row != NULL);
3860  assert(row->lppos >= 0);
3861  redcost -= col->vals[i] * dualsol[row->lppos];
3862  }
3863 
3864  if( col->nunlinked > 0 )
3865  {
3866  for( i = col->nlprows; i < col->len; ++i )
3867  {
3868  row = col->rows[i];
3869  assert(row != NULL);
3870  assert(row->lppos == -1 || col->linkpos[i] == -1);
3871  if( row->lppos >= 0 )
3872  redcost -= col->vals[i] * dualsol[row->lppos];
3873  }
3874  }
3875 #ifndef NDEBUG
3876  else
3877  {
3878  for( i = col->nlprows; i < col->len; ++i )
3879  {
3880  row = col->rows[i];
3881  assert(row != NULL);
3882  assert(row->lppos == -1);
3883  assert(col->linkpos[i] >= 0);
3884  }
3885  }
3886 #endif
3887 
3888  return redcost;
3889 }
3890 
3891 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3892 static
3894  SCIP_COL* col /**< LP column */
3895  )
3896 {
3897  SCIP_ROW* row;
3898  SCIP_Real redcost;
3899  int i;
3900 
3901  assert(col != NULL);
3902  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3903  assert(SCIPvarGetCol(col->var) == col);
3904 
3905  redcost = col->obj;
3906  for( i = 0; i < col->nlprows; ++i )
3907  {
3908  row = col->rows[i];
3909  assert(row != NULL);
3910  assert(row->dualsol < SCIP_INVALID);
3911  assert(row->lppos >= 0);
3912  assert(col->linkpos[i] >= 0);
3913  redcost -= col->vals[i] * row->dualsol;
3914  }
3915 
3916  if( col->nunlinked > 0 )
3917  {
3918  for( i = col->nlprows; i < col->len; ++i )
3919  {
3920  row = col->rows[i];
3921  assert(row != NULL);
3922  assert(row->lppos >= 0 || row->dualsol == 0.0);
3923  assert(row->lppos == -1 || col->linkpos[i] == -1);
3924  if( row->lppos >= 0 )
3925  redcost -= col->vals[i] * row->dualsol;
3926  }
3927  }
3928 #ifndef NDEBUG
3929  else
3930  {
3931  for( i = col->nlprows; i < col->len; ++i )
3932  {
3933  row = col->rows[i];
3934  assert(row != NULL);
3935  assert(row->dualsol == 0.0);
3936  assert(row->lppos == -1);
3937  assert(col->linkpos[i] >= 0);
3938  }
3939  }
3940 #endif
3941 
3942  return redcost;
3943 }
3944 
3945 /** gets the reduced costs of a column in last LP or after recalculation */
3947  SCIP_COL* col, /**< LP column */
3948  SCIP_STAT* stat, /**< problem statistics */
3949  SCIP_LP* lp /**< current LP data */
3950  )
3951 {
3952  assert(col != NULL);
3953  assert(stat != NULL);
3954  assert(lp != NULL);
3955  assert(col->validredcostlp <= stat->lpcount);
3956  assert(lp->validsollp == stat->lpcount);
3957 
3958  if( col->validredcostlp < stat->lpcount )
3959  {
3960  col->redcost = colCalcInternalRedcost(col);
3961  col->validredcostlp = stat->lpcount;
3962  }
3963  assert(col->validredcostlp == stat->lpcount);
3964  assert(col->redcost < SCIP_INVALID);
3965 
3966  return col->redcost;
3967 }
3968 
3969 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3971  SCIP_COL* col, /**< LP column */
3972  SCIP_SET* set, /**< global SCIP settings */
3973  SCIP_STAT* stat, /**< problem statistics */
3974  SCIP_LP* lp /**< current LP data */
3975  )
3976 {
3977  assert(col != NULL);
3978  assert(set != NULL);
3979  assert(stat != NULL);
3980  assert(lp != NULL);
3981  assert(lp->validsollp == stat->lpcount);
3982 
3983  /* A column's reduced cost is defined as
3984  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3985  * The activity is equal to the activity of the corresponding row in the dual LP.
3986  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3987  * The sides of the dual row depend on the bounds of the column:
3988  * - lb == ub : dual row is a free row with infinite sides
3989  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3990  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3991  * - lb < ub <= 0: obj <= activity => redcost <= 0
3992  */
3993  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3994  {
3995  /* dual row is free */
3996  return SCIPsetInfinity(set);
3997  }
3998  else
3999  {
4000  SCIP_Real redcost;
4001 
4002  /* calculate reduced costs */
4003  redcost = SCIPcolGetRedcost(col, stat, lp);
4004 
4005  if( !SCIPsetIsNegative(set, col->lb) )
4006  {
4007  /* dual row is activity <= obj <=> redcost >= 0 */
4008  return redcost;
4009  }
4010  else if( SCIPsetIsPositive(set, col->ub) )
4011  {
4012  /* dual row is activity == obj <=> redcost == 0 */
4013  return -REALABS(redcost);
4014  }
4015  else
4016  {
4017  /* dual row is activity >= obj <=> redcost <= 0 */
4018  return -redcost;
4019  }
4020  }
4021 }
4022 
4023 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4025  SCIP_COL* col, /**< LP column */
4026  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4027  )
4028 {
4029  SCIP_ROW* row;
4030  SCIP_Real farkas;
4031  int i;
4032 
4033  assert(col != NULL);
4034  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4035  assert(SCIPvarGetCol(col->var) == col);
4036  assert(dualfarkas != NULL);
4037 
4038  farkas = 0.0;
4039  for( i = 0; i < col->nlprows; ++i )
4040  {
4041  row = col->rows[i];
4042  assert(row != NULL);
4043  assert(row->lppos >= 0);
4044  farkas += col->vals[i] * dualfarkas[row->lppos];
4045  }
4046 
4047  if( col->nunlinked > 0 )
4048  {
4049  for( i = col->nlprows; i < col->len; ++i )
4050  {
4051  row = col->rows[i];
4052  assert(row != NULL);
4053  assert(row->lppos == -1 || col->linkpos[i] == -1);
4054  if( row->lppos >= 0 )
4055  farkas += col->vals[i] * dualfarkas[row->lppos];
4056  }
4057  }
4058 #ifndef NDEBUG
4059  else
4060  {
4061  for( i = col->nlprows; i < col->len; ++i )
4062  {
4063  row = col->rows[i];
4064  assert(row != NULL);
4065  assert(row->lppos == -1);
4066  assert(col->linkpos[i] >= 0);
4067  }
4068  }
4069 #endif
4070 
4071  return farkas;
4072 }
4073 
4074 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4075 static
4077  SCIP_COL* col /**< LP column */
4078  )
4079 {
4080  SCIP_ROW* row;
4081  SCIP_Real farkas;
4082  int i;
4083 
4084  assert(col != NULL);
4085  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4086  assert(SCIPvarGetCol(col->var) == col);
4087 
4088  farkas = 0.0;
4089  for( i = 0; i < col->nlprows; ++i )
4090  {
4091  row = col->rows[i];
4092  assert(row != NULL);
4093  assert(row->dualfarkas < SCIP_INVALID);
4094  assert(row->lppos >= 0);
4095  assert(col->linkpos[i] >= 0);
4096  farkas += col->vals[i] * row->dualfarkas;
4097  }
4098 
4099  if( col->nunlinked > 0 )
4100  {
4101  for( i = col->nlprows; i < col->len; ++i )
4102  {
4103  row = col->rows[i];
4104  assert(row != NULL);
4105  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4106  assert(row->lppos == -1 || col->linkpos[i] == -1);
4107  if( row->lppos >= 0 )
4108  farkas += col->vals[i] * row->dualfarkas;
4109  }
4110  }
4111 #ifndef NDEBUG
4112  else
4113  {
4114  for( i = col->nlprows; i < col->len; ++i )
4115  {
4116  row = col->rows[i];
4117  assert(row != NULL);
4118  assert(row->dualfarkas == 0.0);
4119  assert(row->lppos == -1);
4120  assert(col->linkpos[i] >= 0);
4121  }
4122  }
4123 #endif
4124 
4125  return farkas;
4126 }
4127 
4128 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4130  SCIP_COL* col, /**< LP column */
4131  SCIP_STAT* stat, /**< problem statistics */
4132  SCIP_LP* lp /**< current LP data */
4133  )
4134 {
4135  assert(col != NULL);
4136  assert(stat != NULL);
4137  assert(lp != NULL);
4138  assert(col->validfarkaslp <= stat->lpcount);
4139  assert(lp->validfarkaslp == stat->lpcount);
4140 
4141  if( col->validfarkaslp < stat->lpcount )
4142  {
4144  col->validfarkaslp = stat->lpcount;
4145  }
4146  assert(col->validfarkaslp == stat->lpcount);
4147  assert(col->farkascoef < SCIP_INVALID);
4148 
4149  return col->farkascoef;
4150 }
4151 
4152 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4153  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4154  */
4156  SCIP_COL* col, /**< LP column */
4157  SCIP_STAT* stat, /**< problem statistics */
4158  SCIP_LP* lp /**< current LP data */
4159  )
4160 {
4161  SCIP_Real farkascoef;
4162 
4163  assert(col != NULL);
4164 
4165  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4166 
4167  if( farkascoef > 0.0 )
4168  return col->ub * farkascoef;
4169  else
4170  return col->lb * farkascoef;
4171 }
4172 
4173 /** start strong branching - call before any strong branching */
4175  SCIP_LP* lp /**< LP data */
4176  )
4177 {
4178  assert(lp != NULL);
4179  assert(!lp->strongbranching);
4180 
4181  lp->strongbranching = TRUE;
4182  SCIPdebugMessage("starting strong branching ...\n");
4184 
4185  return SCIP_OKAY;
4186 }
4187 
4188 /** end strong branching - call after any strong branching */
4190  SCIP_LP* lp /**< LP data */
4191  )
4192 {
4193  assert(lp != NULL);
4194  assert(lp->strongbranching);
4195 
4196  lp->strongbranching = FALSE;
4197  SCIPdebugMessage("ending strong branching ...\n");
4199 
4200  return SCIP_OKAY;
4201 }
4202 
4203 /** sets strong branching information for a column variable */
4205  SCIP_COL* col, /**< LP column */
4206  SCIP_SET* set, /**< global SCIP settings */
4207  SCIP_STAT* stat, /**< dynamic problem statistics */
4208  SCIP_LP* lp, /**< LP data */
4209  SCIP_Real lpobjval, /**< objective value of the current LP */
4210  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4211  SCIP_Real sbdown, /**< dual bound after branching column down */
4212  SCIP_Real sbup, /**< dual bound after branching column up */
4213  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4214  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4215  SCIP_Longint iter, /**< total number of strong branching iterations */
4216  int itlim /**< iteration limit applied to the strong branching call */
4217  )
4218 {
4219  assert(col != NULL);
4220  assert(col->var != NULL);
4221  assert(SCIPcolIsIntegral(col));
4222  assert(SCIPvarIsIntegral(col->var));
4223  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4224  assert(SCIPvarGetCol(col->var) == col);
4225  assert(col->lpipos >= 0);
4226  assert(col->lppos >= 0);
4227  assert(set != NULL);
4228  assert(stat != NULL);
4229  assert(lp != NULL);
4230  assert(lp->strongbranchprobing);
4231  assert(col->lppos < lp->ncols);
4232  assert(lp->cols[col->lppos] == col);
4233  assert(itlim >= 1);
4234 
4235  col->sblpobjval = lpobjval;
4236  col->sbsolval = primsol;
4237  col->validsblp = stat->nlps;
4238  col->sbnode = stat->nnodes;
4239 
4240  col->sbitlim = itlim;
4241  col->nsbcalls++;
4242 
4243  col->sbdown = MIN(sbdown, lp->cutoffbound);
4244  col->sbup = MIN(sbup, lp->cutoffbound);
4245  col->sbdownvalid = sbdownvalid;
4246  col->sbupvalid = sbupvalid;
4247 
4248  SCIPstatIncrement(stat, set, nstrongbranchs);
4249  SCIPstatAdd(stat, set, nsblpiterations, iter);
4250  if( stat->nnodes == 1 )
4251  {
4252  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4253  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4254  }
4255 }
4256 
4257 /** invalidates strong branching information for a column variable */
4259  SCIP_COL* col, /**< LP column */
4260  SCIP_SET* set, /**< global SCIP settings */
4261  SCIP_STAT* stat, /**< dynamic problem statistics */
4262  SCIP_LP* lp /**< LP data */
4263  )
4264 {
4265  assert(col != NULL);
4266  assert(col->var != NULL);
4267  assert(SCIPcolIsIntegral(col));
4268  assert(SCIPvarIsIntegral(col->var));
4269  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4270  assert(SCIPvarGetCol(col->var) == col);
4271  assert(col->lpipos >= 0);
4272  assert(col->lppos >= 0);
4273  assert(set != NULL);
4274  assert(stat != NULL);
4275  assert(lp != NULL);
4276  assert(lp->strongbranchprobing);
4277  assert(col->lppos < lp->ncols);
4278  assert(lp->cols[col->lppos] == col);
4279 
4280  col->sbdown = SCIP_INVALID;
4281  col->sbup = SCIP_INVALID;
4282  col->sbdownvalid = FALSE;
4283  col->sbupvalid = FALSE;
4284  col->validsblp = -1;
4285  col->sbsolval = SCIP_INVALID;
4286  col->sblpobjval = SCIP_INVALID;
4287  col->sbnode = -1;
4288  col->sbitlim = -1;
4289 }
4290 
4291 
4292 /** gets strong branching information on a column variable */
4294  SCIP_COL* col, /**< LP column */
4295  SCIP_Bool integral, /**< should integral strong branching be performed? */
4296  SCIP_SET* set, /**< global SCIP settings */
4297  SCIP_STAT* stat, /**< dynamic problem statistics */
4298  SCIP_PROB* prob, /**< problem data */
4299  SCIP_LP* lp, /**< LP data */
4300  int itlim, /**< iteration limit for strong branchings */
4301  SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4302  SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4303  SCIP_Real* down, /**< stores dual bound after branching column down */
4304  SCIP_Real* up, /**< stores dual bound after branching column up */
4305  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4306  * otherwise, it can only be used as an estimate value */
4307  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4308  * otherwise, it can only be used as an estimate value */
4309  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4310  )
4311 {
4312  SCIP_Real sbdown;
4313  SCIP_Real sbup;
4314  SCIP_Bool sbdownvalid;
4315  SCIP_Bool sbupvalid;
4316  SCIP_Longint validsblp;
4317  SCIP_Real sbsolval;
4318  SCIP_Real sblpobjval;
4319  SCIP_Longint sbnode;
4320  int sbitlim;
4321  int nsbcalls;
4322 
4323  assert(col != NULL);
4324  assert(col->var != NULL);
4325  assert(SCIPcolIsIntegral(col));
4326  assert(SCIPvarIsIntegral(col->var));
4327  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4328  assert(SCIPvarGetCol(col->var) == col);
4329  assert(col->primsol < SCIP_INVALID);
4330  assert(col->lpipos >= 0);
4331  assert(col->lppos >= 0);
4332  assert(set != NULL);
4333  assert(stat != NULL);
4334  assert(lp != NULL);
4335  assert(lp->flushed);
4336  assert(lp->solved);
4337  assert(lp->strongbranching);
4338  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4339  assert(lp->validsollp == stat->lpcount);
4340  assert(col->lppos < lp->ncols);
4341  assert(lp->cols[col->lppos] == col);
4342  assert(itlim >= 1);
4343  /* assert(down != NULL);
4344  * assert(up != NULL); temporary hack for cloud branching
4345  */
4346  assert(lperror != NULL);
4347 
4348  *lperror = FALSE;
4349 
4350  sbdown = col->sbdown;
4351  sbup = col->sbup;
4352  sbdownvalid = col->sbdownvalid;
4353  sbupvalid = col->sbupvalid;
4354  sbitlim = col->sbitlim;
4355  nsbcalls = col->nsbcalls;
4356 
4357  validsblp = stat->nlps;
4358  sbsolval = col->primsol;
4359  sblpobjval = SCIPlpGetObjval(lp, set, prob);
4360  sbnode = stat->nnodes;
4361  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4362 
4363  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4364  if( lp->looseobjvalinf > 0 )
4365  {
4366  sbdown = -SCIPsetInfinity(set);
4367  sbup = -SCIPsetInfinity(set);
4368  sbdownvalid = FALSE;
4369  sbupvalid = FALSE;
4370  }
4371  else
4372  {
4373  SCIP_RETCODE retcode;
4374  int iter;
4375 
4376  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4377  SCIPvarGetName(col->var), col->primsol, itlim);
4378 
4379  /* start timing */
4380  SCIPclockStart(stat->strongbranchtime, set);
4381 
4382  /* call LPI strong branching */
4383  sbitlim = itlim;
4384  nsbcalls++;
4385 
4386  sbdown = lp->lpobjval;
4387  sbup = lp->lpobjval;
4388 
4389  if( integral )
4390  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4391  else
4392  {
4393  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4394  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4395  }
4396 
4397  /* check return code for errors */
4398  if( retcode == SCIP_LPERROR )
4399  {
4400  *lperror = TRUE;
4401  sbdown = SCIP_INVALID;
4402  sbup = SCIP_INVALID;
4403  sbdownvalid = FALSE;
4404  sbupvalid = FALSE;
4405  validsblp = -1;
4406  sbsolval = SCIP_INVALID;
4407  sblpobjval = SCIP_INVALID;
4408  sbnode = -1;
4409  }
4410  else
4411  {
4412  SCIP_Real looseobjval;
4413 
4414  *lperror = FALSE;
4415  SCIP_CALL( retcode );
4416 
4417  looseobjval = getFiniteLooseObjval(lp, set, prob);
4418  sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4419  sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4420 
4421  /* update strong branching statistics */
4422  if( updatestat )
4423  {
4424  if( iter == -1 )
4425  {
4426  /* calculate average iteration number */
4427  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4428  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4429  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4430  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4431  : 0;
4432  if( iter/2 >= itlim )
4433  iter = 2*itlim;
4434  }
4435  SCIPstatIncrement(stat, set, nstrongbranchs);
4436  SCIPstatAdd(stat, set, nsblpiterations, iter);
4437  if( stat->nnodes == 1 )
4438  {
4439  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4440  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4441  }
4442  }
4443  }
4444 
4445  /* stop timing */
4446  SCIPclockStop(stat->strongbranchtime, set);
4447  }
4448  assert(*lperror || sbdown < SCIP_INVALID);
4449  assert(*lperror || sbup < SCIP_INVALID);
4450 
4451  if( down != NULL)
4452  *down = sbdown;
4453  if( up != NULL )
4454  *up = sbup;
4455  if( downvalid != NULL )
4456  *downvalid = sbdownvalid;
4457  if( upvalid != NULL )
4458  *upvalid = sbupvalid;
4459 
4460  if( updatecol )
4461  {
4462  col->sbdown = sbdown;
4463  col->sbup = sbup;
4464  col->sbdownvalid = sbdownvalid;
4465  col->sbupvalid = sbupvalid;
4466  col->validsblp = validsblp;
4467  col->sbsolval = sbsolval;
4468  col->sblpobjval = sblpobjval;
4469  col->sbnode = sbnode;
4470  col->sbitlim = sbitlim;
4471  col->nsbcalls = nsbcalls;
4472  }
4473 
4474  return SCIP_OKAY;
4475 }
4476 
4477 /** gets strong branching information on column variables */
4479  SCIP_COL** cols, /**< LP columns */
4480  int ncols, /**< number of columns */
4481  SCIP_Bool integral, /**< should integral strong branching be performed? */
4482  SCIP_SET* set, /**< global SCIP settings */
4483  SCIP_STAT* stat, /**< dynamic problem statistics */
4484  SCIP_PROB* prob, /**< problem data */
4485  SCIP_LP* lp, /**< LP data */
4486  int itlim, /**< iteration limit for strong branchings */
4487  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4488  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4489  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4490  * otherwise, they can only be used as an estimate value */
4491  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4492  * otherwise, they can only be used as an estimate value */
4493  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4494  )
4495 {
4496  SCIP_RETCODE retcode;
4497  SCIP_Real* sbdown;
4498  SCIP_Real* sbup;
4499  SCIP_Bool* sbdownvalid;
4500  SCIP_Bool* sbupvalid;
4501  SCIP_Real* primsols;
4502  SCIP_COL** subcols;
4503  int* lpipos;
4504  int* subidx;
4505  int nsubcols;
4506  int iter;
4507  int j;
4508 
4509  assert(cols != NULL);
4510  assert(set != NULL);
4511  assert(stat != NULL);
4512  assert(lp != NULL);
4513  assert(lp->flushed);
4514  assert(lp->solved);
4515  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4516  assert(lp->validsollp == stat->lpcount);
4517  assert(itlim >= 1);
4518  assert(down != NULL);
4519  assert(up != NULL);
4520  assert(lperror != NULL);
4521 
4522  *lperror = FALSE;
4523 
4524  if ( ncols <= 0 )
4525  return SCIP_OKAY;
4526 
4527  /* start timing */
4528  SCIPclockStart(stat->strongbranchtime, set);
4529 
4530  /* initialize storage */
4531  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4532  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4533  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4534  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4535  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4536  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4537  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4538  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4539 
4540  nsubcols = 0;
4541  for( j = 0; j < ncols; ++j )
4542  {
4543  SCIP_COL* col;
4544  col = cols[j];
4545 
4546  assert(col->lppos < lp->ncols);
4547  assert(lp->cols[col->lppos] == col);
4548  assert(SCIPcolIsIntegral(col));
4549  assert(SCIPvarIsIntegral(col->var));
4550  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4551  assert(SCIPvarGetCol(col->var) == col);
4552  assert(col->primsol < SCIP_INVALID);
4553  assert(col->lpipos >= 0);
4554  assert(col->lppos >= 0);
4555 
4556  col->validsblp = stat->nlps;
4557  col->sbsolval = col->primsol;
4558  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4559  col->sbnode = stat->nnodes;
4560  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4561 
4562  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4563  if( lp->looseobjvalinf > 0 )
4564  {
4565  /* directly set up column and result vectors*/
4566  col->sbdown = -SCIPsetInfinity(set);
4567  col->sbup = -SCIPsetInfinity(set);
4568  col->sbdownvalid = FALSE;
4569  col->sbupvalid = FALSE;
4570  down[j] = col->sbdown;
4571  up[j] = col->sbup;
4572  if( downvalid != NULL )
4573  downvalid[j] = col->sbdownvalid;
4574  if( upvalid != NULL )
4575  upvalid[j] = col->sbupvalid;
4576  }
4577  else
4578  {
4579  col->sbitlim = itlim;
4580  col->nsbcalls++;
4581 
4582  lpipos[nsubcols] = col->lpipos;
4583  primsols[nsubcols] = col->primsol;
4584  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4585  subidx[nsubcols] = j;
4586  subcols[nsubcols++] = col;
4587  }
4588  }
4589 
4590  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4591 
4592  /* call LPI strong branching */
4593  if ( integral )
4594  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4595  else
4596  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4597 
4598  /* check return code for errors */
4599  if( retcode == SCIP_LPERROR )
4600  {
4601  *lperror = TRUE;
4602 
4603  for( j = 0; j < nsubcols; ++j )
4604  {
4605  SCIP_COL* col;
4606  int idx;
4607 
4608  col = subcols[j];
4609  idx = subidx[j];
4610 
4611  col->sbdown = SCIP_INVALID;
4612  col->sbup = SCIP_INVALID;
4613  col->sbdownvalid = FALSE;
4614  col->sbupvalid = FALSE;
4615  col->validsblp = -1;
4616  col->sbsolval = SCIP_INVALID;
4617  col->sblpobjval = SCIP_INVALID;
4618  col->sbnode = -1;
4619 
4620  down[idx] = col->sbdown;
4621  up[idx] = col->sbup;
4622  if( downvalid != NULL )
4623  downvalid[idx] = col->sbdownvalid;
4624  if( upvalid != NULL )
4625  upvalid[idx] = col->sbupvalid;
4626  }
4627  }
4628  else
4629  {
4630  SCIP_Real looseobjval;
4631 
4632  *lperror = FALSE;
4633  SCIP_CALL( retcode );
4634 
4635  looseobjval = getFiniteLooseObjval(lp, set, prob);
4636 
4637  for( j = 0; j < nsubcols; ++j )
4638  {
4639  SCIP_COL* col;
4640  int idx;
4641 
4642  col = subcols[j];
4643  idx = subidx[j];
4644 
4645  assert( col->sbdown < SCIP_INVALID);
4646  assert( col->sbup < SCIP_INVALID);
4647 
4648  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4649  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4650  col->sbdownvalid = sbdownvalid[j];
4651  col->sbupvalid = sbupvalid[j];
4652 
4653  down[idx] = col->sbdown;
4654  up[idx] = col->sbup;
4655  if( downvalid != NULL )
4656  downvalid[idx] = col->sbdownvalid;
4657  if( upvalid != NULL )
4658  upvalid[idx] = col->sbupvalid;
4659  }
4660 
4661  /* update strong branching statistics */
4662  if( iter == -1 )
4663  {
4664  /* calculate average iteration number */
4665  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4666  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4667  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4668  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4669  : 0;
4670  if( iter/2 >= itlim )
4671  iter = 2*itlim;
4672  }
4673  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4674  SCIPstatAdd(stat, set, nsblpiterations, iter);
4675  if( stat->nnodes == 1 )
4676  {
4677  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4678  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4679  }
4680  }
4681 
4682  SCIPsetFreeBufferArray(set, &sbupvalid);
4683  SCIPsetFreeBufferArray(set, &sbdownvalid);
4684  SCIPsetFreeBufferArray(set, &sbup);
4685  SCIPsetFreeBufferArray(set, &sbdown);
4686  SCIPsetFreeBufferArray(set, &primsols);
4687  SCIPsetFreeBufferArray(set, &lpipos);
4688  SCIPsetFreeBufferArray(set, &subidx);
4689  SCIPsetFreeBufferArray(set, &subcols);
4690 
4691  /* stop timing */
4692  SCIPclockStop(stat->strongbranchtime, set);
4693 
4694  return SCIP_OKAY;
4695 }
4696 
4697 /** gets last strong branching information available for a column variable;
4698  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4699  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4700  */
4702  SCIP_COL* col, /**< LP column */
4703  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4704  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4705  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4706  * otherwise, it can only be used as an estimate value */
4707  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4708  * otherwise, it can only be used as an estimate value */
4709  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4710  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4711  )
4712 {
4713  assert(col != NULL);
4714 
4715  if( down != NULL )
4716  *down = col->sbdown;
4717  if( up != NULL )
4718  *up = col->sbup;
4719  if( downvalid != NULL )
4720  *downvalid = col->sbdownvalid;
4721  if( upvalid != NULL )
4722  *upvalid = col->sbupvalid;
4723  if( solval != NULL )
4724  *solval = col->sbsolval;
4725  if( lpobjval != NULL )
4726  *lpobjval = col->sblpobjval;
4727 }
4728 
4729 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4730  * the LP where the strong branching on this column was applied;
4731  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4732  */
4734  SCIP_COL* col, /**< LP column */
4735  SCIP_STAT* stat /**< dynamic problem statistics */
4736  )
4737 {
4738  assert(col != NULL);
4739  assert(stat != NULL);
4740 
4741  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4742 }
4743 
4744 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4746  SCIP_COL* col, /**< LP column */
4747  SCIP_STAT* stat /**< problem statistics */
4748  )
4749 {
4750  assert(col != NULL);
4751  assert(stat != NULL);
4752  assert(stat->nnodes > 0);
4753 
4754  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4755  col->obsoletenode = stat->nnodes;
4756 }
4757 
4758 
4759 /*
4760  * Row methods
4761  */
4762 
4763 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4764 static
4766  SCIP_ROW* row, /**< LP row */
4767  SCIP_SET* set /**< global SCIP settings */
4768  )
4769 {
4770  int i;
4771 
4772  assert(row != NULL);
4773  assert(set != NULL);
4774 
4775  row->sqrnorm = 0.0;
4776  row->sumnorm = 0.0;
4777  row->objprod = 0.0;
4778  row->maxval = 0.0;
4779  row->nummaxval = 1;
4780  row->minval = SCIPsetInfinity(set);
4781  row->numminval = 1;
4782  row->minidx = INT_MAX;
4783  row->maxidx = INT_MIN;
4784  row->validminmaxidx = TRUE;
4785  row->lpcolssorted = TRUE;
4786  row->nonlpcolssorted = TRUE;
4787 
4788  /* check, if row is sorted
4789  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4790  */
4791  for( i = 0; i < row->nlpcols; ++i )
4792  {
4793  assert(row->cols[i] != NULL);
4794  assert(!SCIPsetIsZero(set, row->vals[i]));
4795  assert(row->cols[i]->lppos >= 0);
4796  assert(row->linkpos[i] >= 0);
4797  assert(row->cols[i]->index == row->cols_index[i]);
4798 
4799  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4800  if( i > 0 )
4801  {
4802  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4803  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4804  }
4805  }
4806  for( i = row->nlpcols; i < row->len; ++i )
4807  {
4808  assert(row->cols[i] != NULL);
4809  assert(!SCIPsetIsZero(set, row->vals[i]));
4810  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4811  assert(row->cols[i]->index == row->cols_index[i]);
4812 
4813  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4814  if( i > row->nlpcols )
4815  {
4816  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4817  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4818  }
4819  }
4820 }
4821 
4822 /** calculates min/maxval and min/maxidx from scratch */
4823 static
4825  SCIP_ROW* row, /**< LP row */
4826  SCIP_SET* set /**< global SCIP settings */
4827  )
4828 {
4829  SCIP_COL* col;
4830  SCIP_Real absval;
4831  int i;
4832 
4833  assert(row != NULL);
4834  assert(set != NULL);
4835 
4836  row->maxval = 0.0;
4837  row->nummaxval = 1;
4838  row->numintcols = 0;
4839  row->minval = SCIPsetInfinity(set);
4840  row->numminval = 1;
4841  row->minidx = INT_MAX;
4842  row->maxidx = INT_MIN;
4843  row->validminmaxidx = TRUE;
4844 
4845  /* calculate maxval, minval, minidx, and maxidx */
4846  for( i = 0; i < row->len; ++i )
4847  {
4848  col = row->cols[i];
4849  assert(col != NULL);
4850  assert(!SCIPsetIsZero(set, row->vals[i]));
4851 
4852  absval = REALABS(row->vals[i]);
4853  assert(!SCIPsetIsZero(set, absval));
4854 
4855  /* update min/maxidx */
4856  row->minidx = MIN(row->minidx, col->index);
4857  row->maxidx = MAX(row->maxidx, col->index);
4858  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4859 
4860  /* update maximal and minimal non-zero value */
4861  if( row->nummaxval > 0 )
4862  {
4863  if( SCIPsetIsGT(set, absval, row->maxval) )
4864  {
4865  row->maxval = absval;
4866  row->nummaxval = 1;
4867  }
4868  else if( SCIPsetIsGE(set, absval, row->maxval) )
4869  {
4870  /* make sure the maxval is always exactly the same */
4871  row->maxval = MAX(absval, row->maxval);
4872  row->nummaxval++;
4873  }
4874  }
4875  if( row->numminval > 0 )
4876  {
4877  if( SCIPsetIsLT(set, absval, row->minval) )
4878  {
4879  row->minval = absval;
4880  row->numminval = 1;
4881  }
4882  else if( SCIPsetIsLE(set, absval, row->minval) )
4883  {
4884  /* make sure the minval is always exactly the same */
4885  row->minval = MIN(absval, row->minval);
4886  row->numminval++;
4887  }
4888  }
4889  }
4890 }
4891 
4892 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4893 static
4895  SCIP_Real val, /**< value that should be scaled to an integral value */
4896  SCIP_Real scalar, /**< scalar that should be tried */
4897  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4898  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4899  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4900  )
4901 {
4902  SCIP_Real sval;
4903  SCIP_Real downval;
4904  SCIP_Real upval;
4905 
4906  assert(mindelta <= 0.0);
4907  assert(maxdelta >= 0.0);
4908 
4909  sval = val * scalar;
4910  downval = floor(sval);
4911  upval = ceil(sval);
4912 
4913  if( SCIPrelDiff(sval, downval) <= maxdelta )
4914  {
4915  if( intval != NULL )
4916  *intval = downval;
4917  return TRUE;
4918  }
4919  else if( SCIPrelDiff(sval, upval) >= mindelta )
4920  {
4921  if( intval != NULL )
4922  *intval = upval;
4923  return TRUE;
4924  }
4925 
4926  return FALSE;
4927 }
4928 
4929 /** scales row with given factor, and rounds coefficients to integers if close enough;
4930  * the constant is automatically moved to the sides;
4931  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4932  */
4933 static
4935  SCIP_ROW* row, /**< LP row */
4936  BMS_BLKMEM* blkmem, /**< block memory */
4937  SCIP_SET* set, /**< global SCIP settings */
4938  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4939  SCIP_STAT* stat, /**< problem statistics */
4940  SCIP_LP* lp, /**< current LP data */
4941  SCIP_Real scaleval, /**< value to scale row with */
4942  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4943  * if they are close to integral values? */
4944  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4945  * upto which the integral is used instead of the scaled real coefficient */
4946  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4947  * upto which the integral is used instead of the scaled real coefficient */
4948  )
4949 {
4950  SCIP_COL* col;
4951  SCIP_Real val;
4952  SCIP_Real newval;
4953  SCIP_Real intval;
4954  SCIP_Real mindelta;
4955  SCIP_Real maxdelta;
4956  SCIP_Real lb;
4957  SCIP_Real ub;
4958  SCIP_Bool mindeltainf;
4959  SCIP_Bool maxdeltainf;
4960  int oldlen;
4961  int c;
4962 
4963  assert(row != NULL);
4964  assert(row->len == 0 || row->cols != NULL);
4965  assert(row->len == 0 || row->vals != NULL);
4966  assert(SCIPsetIsPositive(set, scaleval));
4967  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4968  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4969 
4970  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4971 
4972  mindelta = 0.0;
4973  maxdelta = 0.0;
4974  mindeltainf = FALSE;
4975  maxdeltainf = FALSE;
4976  oldlen = row->len;
4977 
4978  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4979  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4980  * this rounding can lead to
4981  */
4982  row->integral = TRUE;
4983 
4984  c = 0;
4985  while( c < row->len )
4986  {
4987  col = row->cols[c];
4988  val = row->vals[c];
4989  assert(!SCIPsetIsZero(set, val));
4990 
4991  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4992  if( row->local )
4993  {
4994  lb = col->lb;
4995  ub = col->ub;
4996  }
4997  else
4998  {
4999  lb = SCIPvarGetLbGlobal(col->var);
5000  ub = SCIPvarGetUbGlobal(col->var);
5001  }
5002 
5003  /* calculate scaled coefficient */
5004  newval = val * scaleval;
5005  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5006  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5007  {
5008  if( !SCIPsetIsEQ(set, intval, newval) )
5009  {
5010  if( intval < newval )
5011  {
5012  mindelta += (intval - newval)*ub;
5013  maxdelta += (intval - newval)*lb;
5014  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5015  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5016  }
5017  else
5018  {
5019  mindelta += (intval - newval)*lb;
5020  maxdelta += (intval - newval)*ub;
5021  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5022  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5023  }
5024  }
5025  newval = intval;
5026  }
5027 
5028  if( !SCIPsetIsEQ(set, val, newval) )
5029  {
5030  /* if column knows of the row, change the corresponding coefficient in the column */
5031  if( row->linkpos[c] >= 0 )
5032  {
5033  assert(col->rows[row->linkpos[c]] == row);
5034  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5035  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5036  }
5037 
5038  /* change the coefficient in the row, and update the norms and integrality status */
5039  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5040 
5041  /* current coefficient has been deleted from the row because it was almost zero */
5042  if( oldlen != row->len )
5043  {
5044  assert(row->len == oldlen - 1);
5045  c--;
5046  oldlen = row->len;
5047  }
5048  }
5049  else
5050  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5051 
5052  ++c;
5053  }
5054 
5055  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5056  * to not destroy feasibility due to rounding
5057  */
5058  /**@todo ensure that returned cut does not have infinite lhs and rhs */
5059  if( !SCIPsetIsInfinity(set, -row->lhs) )
5060  {
5061  if( mindeltainf )
5062  newval = -SCIPsetInfinity(set);
5063  else
5064  {
5065  newval = (row->lhs - row->constant) * scaleval + mindelta;
5066  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5067  newval = SCIPsetSumCeil(set, newval);
5068  }
5069  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5070  }
5071  if( !SCIPsetIsInfinity(set, row->rhs) )
5072  {
5073  if( maxdeltainf )
5074  newval = SCIPsetInfinity(set);
5075  else
5076  {
5077  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5078  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5079  newval = SCIPsetSumFloor(set, newval);
5080  }
5081  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5082  }
5083 
5084  /* clear the row constant */
5085  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5086 
5087  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5088  debugRowPrint(set, row);
5089 
5090 #ifdef SCIP_DEBUG
5091  /* check integrality status of row */
5092  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5093  {}
5094  assert(row->integral == (c == row->len));
5095 #endif
5096 
5097  /* invalid the activity */
5098  row->validactivitylp = -1;
5099 
5100  return SCIP_OKAY;
5101 }
5102 
5103 /** creates and captures an LP row */
5105  SCIP_ROW** row, /**< pointer to LP row data */
5106  BMS_BLKMEM* blkmem, /**< block memory */
5107  SCIP_SET* set, /**< global SCIP settings */
5108  SCIP_STAT* stat, /**< problem statistics */
5109  const char* name, /**< name of row */
5110  int len, /**< number of nonzeros in the row */
5111  SCIP_COL** cols, /**< array with columns of row entries */
5112  SCIP_Real* vals, /**< array with coefficients of row entries */
5113  SCIP_Real lhs, /**< left hand side of row */
5114  SCIP_Real rhs, /**< right hand side of row */
5115  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5116  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5117  SCIP_Bool local, /**< is row only valid locally? */
5118  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5119  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5120  )
5121 {
5122  assert(row != NULL);
5123  assert(blkmem != NULL);
5124  assert(stat != NULL);
5125  assert(len >= 0);
5126  assert(len == 0 || (cols != NULL && vals != NULL));
5127  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5128  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5129  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5130  */
5131  assert(lhs <= rhs);
5132 
5133  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5134 
5135  (*row)->integral = TRUE;
5136  if( len > 0 )
5137  {
5138  SCIP_VAR* var;
5139  int i;
5140 
5141  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5142  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5143  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5144  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5145 
5146  for( i = 0; i < len; ++i )
5147  {
5148  assert(cols[i] != NULL);
5149  assert(!SCIPsetIsZero(set, vals[i]));
5150 
5151  var = cols[i]->var;
5152  (*row)->cols_index[i] = cols[i]->index;
5153  (*row)->linkpos[i] = -1;
5154  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5155  {
5156  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5157  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5158  }
5159  else
5160  {
5161  (*row)->integral = FALSE;
5162  }
5163  }
5164  }
5165  else
5166  {
5167  (*row)->cols = NULL;
5168  (*row)->cols_index = NULL;
5169  (*row)->vals = NULL;
5170  (*row)->linkpos = NULL;
5171  }
5172 
5173  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5174  (*row)->constant = 0.0;
5175  (*row)->lhs = lhs;
5176  (*row)->rhs = rhs;
5177  (*row)->flushedlhs = -SCIPsetInfinity(set);
5178  (*row)->flushedrhs = SCIPsetInfinity(set);
5179  (*row)->sqrnorm = 0.0;
5180  (*row)->sumnorm = 0.0;
5181  (*row)->objprod = 0.0;
5182  (*row)->maxval = 0.0;
5183  (*row)->minval = SCIPsetInfinity(set);
5184  (*row)->dualsol = 0.0;
5185  (*row)->activity = SCIP_INVALID;
5186  (*row)->dualfarkas = 0.0;
5187  (*row)->pseudoactivity = SCIP_INVALID;
5188  (*row)->minactivity = SCIP_INVALID;
5189  (*row)->maxactivity = SCIP_INVALID;
5190  (*row)->origin = origin;
5191  (*row)->eventfilter = NULL;
5192  (*row)->index = stat->nrowidx;
5193  SCIPstatIncrement(stat, set, nrowidx);
5194  (*row)->size = len;
5195  (*row)->len = len;
5196  (*row)->nlpcols = 0;
5197  (*row)->nunlinked = len;
5198  (*row)->nuses = 0;
5199  (*row)->lppos = -1;
5200  (*row)->lpipos = -1;
5201  (*row)->lpdepth = -1;
5202  (*row)->minidx = INT_MAX;
5203  (*row)->maxidx = INT_MIN;
5204  (*row)->nummaxval = 0;
5205  (*row)->numminval = 0;
5206  (*row)->numintcols = -1;
5207  (*row)->validactivitylp = -1;
5208  (*row)->validpsactivitydomchg = -1;
5209  (*row)->validactivitybdsdomchg = -1;
5210  (*row)->nlpsaftercreation = 0L;
5211  (*row)->activeinlpcounter = 0L;
5212  (*row)->age = 0;
5213  (*row)->rank = 0;
5214  (*row)->obsoletenode = -1;
5215  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5216  (*row)->lpcolssorted = TRUE;
5217  (*row)->nonlpcolssorted = (len <= 1);
5218  (*row)->delaysort = FALSE;
5219  (*row)->validminmaxidx = FALSE;
5220  (*row)->lhschanged = FALSE;
5221  (*row)->rhschanged = FALSE;
5222  (*row)->coefchanged = FALSE;
5223  (*row)->local = local;
5224  (*row)->modifiable = modifiable;
5225  (*row)->nlocks = 0;
5226  (*row)->origintype = origintype; /*lint !e641*/
5227  (*row)->removable = removable;
5228  (*row)->inglobalcutpool = FALSE;
5229  (*row)->storedsolvals = NULL;
5230 
5231  /* calculate row norms and min/maxidx, and check if row is sorted */
5232  rowCalcNorms(*row, set);
5233 
5234  /* capture the row */
5235  SCIProwCapture(*row);
5236 
5237  /* create event filter */
5238  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5239 
5240  /* capture origin constraint if available */
5241  if( origintype == SCIP_ROWORIGINTYPE_CONS )
5242  {
5243  SCIP_CONS* cons = (SCIP_CONS*) origin;
5244  assert(cons != NULL);
5245  SCIPconsCapture(cons);
5246  }
5247 
5248  return SCIP_OKAY;
5249 } /*lint !e715*/
5250 
5251 /** frees an LP row */
5253  SCIP_ROW** row, /**< pointer to LP row */
5254  BMS_BLKMEM* blkmem, /**< block memory */
5255  SCIP_SET* set, /**< global SCIP settings */
5256  SCIP_LP* lp /**< current LP data */
5257  )
5258 {
5259  assert(blkmem != NULL);
5260  assert(row != NULL);
5261  assert(*row != NULL);
5262  assert((*row)->nuses == 0);
5263  assert((*row)->lppos == -1);
5264  assert((*row)->eventfilter != NULL);
5265 
5266  /* release constraint that has been used for creating the row */
5267  if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5268  {
5269  SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5270  assert(cons != NULL);
5271  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5272  }
5273 
5274  /* remove column indices from corresponding rows */
5275  SCIP_CALL( rowUnlink(*row, set, lp) );
5276 
5277  /* free event filter */
5278  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5279 
5280  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5281  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5282  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5283  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5284  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5285  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5286  BMSfreeBlockMemory(blkmem, row);
5287 
5288  return SCIP_OKAY;
5289 }
5290 
5291 /** output row to file stream */
5293  SCIP_ROW* row, /**< LP row */
5294  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5295  FILE* file /**< output file (or NULL for standard output) */
5296  )
5297 {
5298  int i;
5299 
5300  assert(row != NULL);
5301 
5302  /* print row name */
5303  if( row->name != NULL && row->name[0] != '\0' )
5304  {
5305  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5306  }
5307 
5308  /* print left hand side */
5309  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5310 
5311  /* print coefficients */
5312  if( row->len == 0 )
5313  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5314  for( i = 0; i < row->len; ++i )
5315  {
5316  assert(row->cols[i] != NULL);
5317  assert(row->cols[i]->var != NULL);
5318  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5319  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5320  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5321  }
5322 
5323  /* print constant */
5324  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5325  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5326 
5327  /* print right hand side */
5328  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5329 }
5330 
5331 /** increases usage counter of LP row */
5333  SCIP_ROW* row /**< LP row */
5334  )
5335 {
5336  assert(row != NULL);
5337  assert(row->nuses >= 0);
5338  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5339 
5340  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5341  row->nuses++;
5342 }
5343 
5344 /** decreases usage counter of LP row, and frees memory if necessary */
5346  SCIP_ROW** row, /**< pointer to LP row */
5347  BMS_BLKMEM* blkmem, /**< block memory */
5348  SCIP_SET* set, /**< global SCIP settings */
5349  SCIP_LP* lp /**< current LP data */
5350  )
5351 {
5352  assert(blkmem != NULL);
5353  assert(row != NULL);
5354  assert(*row != NULL);
5355  assert((*row)->nuses >= 1);
5356  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5357 
5358  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5359  (*row)->nuses--;
5360  if( (*row)->nuses == 0 )
5361  {
5362  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5363  }
5364 
5365  *row = NULL;
5366 
5367  return SCIP_OKAY;
5368 }
5369 
5370 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5372  SCIP_ROW* row /**< LP row */
5373  )
5374 {
5375  assert(row != NULL);
5376 
5377  /* check, if row is modifiable */
5378  if( !row->modifiable )
5379  {
5380  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5381  row->nlocks++;
5382  }
5383 }
5384 
5385 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5387  SCIP_ROW* row /**< LP row */
5388  )
5389 {
5390  assert(row != NULL);
5391 
5392  /* check, if row is modifiable */
5393  if( !row->modifiable )
5394  {
5395  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5396  assert(row->nlocks > 0);
5397  row->nlocks--;
5398  }
5399 }
5400 
5401 /** adds a previously non existing coefficient to an LP row */
5403  SCIP_ROW* row, /**< LP row */
5404  BMS_BLKMEM* blkmem, /**< block memory */
5405  SCIP_SET* set, /**< global SCIP settings */
5406  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5407  SCIP_LP* lp, /**< current LP data */
5408  SCIP_COL* col, /**< LP column */
5409  SCIP_Real val /**< value of coefficient */
5410  )
5411 {
5412  assert(lp != NULL);
5413  assert(!lp->diving || row->lppos == -1);
5414 
5415  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5416 
5417  checkLinks(lp);
5418 
5419  return SCIP_OKAY;
5420 }
5421 
5422 /** deletes coefficient from row */
5424  SCIP_ROW* row, /**< row to be changed */
5425  BMS_BLKMEM* blkmem, /**< block memory */
5426  SCIP_SET* set, /**< global SCIP settings */
5427  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5428  SCIP_LP* lp, /**< current LP data */
5429  SCIP_COL* col /**< coefficient to be deleted */
5430  )
5431 {
5432  int pos;
5433 
5434  assert(row != NULL);
5435  assert(!row->delaysort);
5436  assert(lp != NULL);
5437  assert(!lp->diving || row->lppos == -1);
5438  assert(col != NULL);
5439  assert(col->var != NULL);
5440 
5441  /* search the position of the column in the row's col vector */
5442  pos = rowSearchCoef(row, col);
5443  if( pos == -1 )
5444  {
5445  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5446  return SCIP_INVALIDDATA;
5447  }
5448  assert(0 <= pos && pos < row->len);
5449  assert(row->cols[pos] == col);
5450  assert(row->cols_index[pos] == col->index);
5451 
5452  /* if column knows of the row, remove the row from the column's row vector */
5453  if( row->linkpos[pos] >= 0 )
5454  {
5455  assert(col->rows[row->linkpos[pos]] == row);
5456  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5457  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5458  }
5459 
5460  /* delete the column from the row's col vector */
5461  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5462 
5463  checkLinks(lp);
5464 
5465  return SCIP_OKAY;
5466 }
5467 
5468 /** changes or adds a coefficient to an LP row */
5470  SCIP_ROW* row, /**< LP row */
5471  BMS_BLKMEM* blkmem, /**< block memory */
5472  SCIP_SET* set, /**< global SCIP settings */
5473  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5474  SCIP_LP* lp, /**< current LP data */
5475  SCIP_COL* col, /**< LP column */
5476  SCIP_Real val /**< value of coefficient */
5477  )
5478 {
5479  int pos;
5480 
5481  assert(row != NULL);
5482  assert(!row->delaysort);
5483  assert(lp != NULL);
5484  assert(!lp->diving || row->lppos == -1);
5485  assert(col != NULL);
5486 
5487  /* search the position of the column in the row's col vector */
5488  pos = rowSearchCoef(row, col);
5489 
5490  /* check, if column already exists in the row's col vector */
5491  if( pos == -1 )
5492  {
5493  /* add previously not existing coefficient */
5494  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5495  }
5496  else
5497  {
5498  /* modify already existing coefficient */
5499  assert(0 <= pos && pos < row->len);
5500  assert(row->cols[pos] == col);
5501  assert(row->cols_index[pos] == col->index);
5502 
5503  /* if column knows of the row, change the corresponding coefficient in the column */
5504  if( row->linkpos[pos] >= 0 )
5505  {
5506  assert(col->rows[row->linkpos[pos]] == row);
5507  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5508  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5509  }
5510 
5511  /* change the coefficient in the row */
5512  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5513  }
5514 
5515  checkLinks(lp);
5516 
5517  return SCIP_OKAY;
5518 }
5519 
5520 /** increases value of an existing or non-existing coefficient in an LP row */
5522  SCIP_ROW* row, /**< LP row */
5523  BMS_BLKMEM* blkmem, /**< block memory */
5524  SCIP_SET* set, /**< global SCIP settings */
5525  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5526  SCIP_LP* lp, /**< current LP data */
5527  SCIP_COL* col, /**< LP column */
5528  SCIP_Real incval /**< value to add to the coefficient */
5529  )
5530 {
5531  int pos;
5532 
5533  assert(row != NULL);
5534  assert(lp != NULL);
5535  assert(!lp->diving || row->lppos == -1);
5536  assert(col != NULL);
5537 
5538  if( SCIPsetIsZero(set, incval) )
5539  return SCIP_OKAY;
5540 
5541  /* search the position of the column in the row's col vector */
5542  pos = rowSearchCoef(row, col);
5543 
5544  /* check, if column already exists in the row's col vector */
5545  if( pos == -1 )
5546  {
5547  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5548  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5549  }
5550  else
5551  {
5552  /* modify already existing coefficient */
5553  assert(0 <= pos && pos < row->len);
5554  assert(row->cols[pos] == col);
5555  assert(row->cols_index[pos] == col->index);
5556 
5557  /* if column knows of the row, change the corresponding coefficient in the column */
5558  if( row->linkpos[pos] >= 0 )
5559  {
5560  assert(col->rows[row->linkpos[pos]] == row);
5561  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5562  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5563  }
5564 
5565  /* change the coefficient in the row */
5566  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5567  }
5568 
5569  checkLinks(lp);
5570 
5571  /* invalid the activity */
5572  row->validactivitylp = -1;
5573 
5574  return SCIP_OKAY;
5575 }
5576 
5577 /** changes constant value of a row */
5579  SCIP_ROW* row, /**< LP row */
5580  BMS_BLKMEM* blkmem, /**< block memory */
5581  SCIP_SET* set, /**< global SCIP settings */
5582  SCIP_STAT* stat, /**< problem statistics */
5583  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5584  SCIP_LP* lp, /**< current LP data */
5585  SCIP_Real constant /**< new constant value */
5586  )
5587 {
5588  assert(row != NULL);
5589  assert(row->lhs <= row->rhs);
5590  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5591  assert(stat != NULL);
5592  assert(lp != NULL);
5593  assert(!lp->diving || row->lppos == -1);
5594 
5595  if( !SCIPsetIsEQ(set, constant, row->constant) )
5596  {
5597  SCIP_Real oldconstant;
5598 
5599  if( row->validpsactivitydomchg == stat->domchgcount )
5600  {
5601  assert(row->pseudoactivity < SCIP_INVALID);
5602  row->pseudoactivity += constant - row->constant;
5603  }
5604  if( row->validactivitybdsdomchg == stat->domchgcount )
5605  {
5606  assert(row->minactivity < SCIP_INVALID);
5607  assert(row->maxactivity < SCIP_INVALID);
5608  row->minactivity += constant - row->constant;
5609  row->maxactivity += constant - row->constant;
5610  }
5611 
5612  if( !SCIPsetIsInfinity(set, -row->lhs) )
5613  {
5614  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5615  }
5616  if( !SCIPsetIsInfinity(set, row->rhs) )
5617  {
5618  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5619  }
5620 
5621  oldconstant = row->constant;
5622 
5623  row->constant = constant;
5624 
5625  /* issue row constant changed event */
5626  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5627  }
5628 
5629  return SCIP_OKAY;
5630 }
5631 
5632 /** add constant value to a row */
5634  SCIP_ROW* row, /**< LP row */
5635  BMS_BLKMEM* blkmem, /**< block memory */
5636  SCIP_SET* set, /**< global SCIP settings */
5637  SCIP_STAT* stat, /**< problem statistics */
5638  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5639  SCIP_LP* lp, /**< current LP data */
5640  SCIP_Real addval /**< constant value to add to the row */
5641  )
5642 {
5643  assert(row != NULL);
5644  assert(row->lhs <= row->rhs);
5645  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5646  assert(stat != NULL);
5647  assert(lp != NULL);
5648  assert(!lp->diving || row->lppos == -1);
5649 
5650  if( !SCIPsetIsZero(set, addval) )
5651  {
5652  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5653  }
5654 
5655  return SCIP_OKAY;
5656 }
5657 
5658 /** changes left hand side of LP row */
5660  SCIP_ROW* row, /**< LP row */
5661  BMS_BLKMEM* blkmem, /**< block memory */
5662  SCIP_SET* set, /**< global SCIP settings */
5663  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5664  SCIP_LP* lp, /**< current LP data */
5665  SCIP_Real lhs /**< new left hand side */
5666  )
5667 {
5668  assert(row != NULL);
5669  assert(lp != NULL);
5670 
5671  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5672  {
5673  SCIP_Real oldlhs;
5674 
5675  oldlhs = row->lhs;
5676 
5677  row->lhs = lhs;
5678  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5679 
5680  if( !lp->diving )
5681  {
5682  /* issue row side changed event */
5683  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5684  }
5685  }
5686 
5687  return SCIP_OKAY;
5688 }
5689 
5690 /** changes right hand side of LP row */
5692  SCIP_ROW* row, /**< LP row */
5693  BMS_BLKMEM* blkmem, /**< block memory */
5694  SCIP_SET* set, /**< global SCIP settings */
5695  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5696  SCIP_LP* lp, /**< current LP data */
5697  SCIP_Real rhs /**< new right hand side */
5698  )
5699 {
5700  assert(row != NULL);
5701  assert(lp != NULL);
5702 
5703  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5704  {
5705  SCIP_Real oldrhs;
5706 
5707  oldrhs = row->rhs;
5708 
5709  row->rhs = rhs;
5710  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5711 
5712  if( !lp->diving )
5713  {
5714  /* issue row side changed event */
5715  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5716  }
5717  }
5718 
5719  return SCIP_OKAY;
5720 }
5721 
5722 /** changes the local flag of LP row */
5724  SCIP_ROW* row, /**< LP row */
5725  SCIP_Bool local /**< new value for local flag */
5726  )
5727 {
5728  assert(row != NULL);
5729 
5730  row->local = local;
5731 
5732  return SCIP_OKAY;
5733 }
5734 
5735 /** additional scalars that are tried in integrality scaling */
5736 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5737 static const int nscalars = 9;
5738 
5739 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5741  SCIP_ROW* row, /**< LP row */
5742  SCIP_SET* set, /**< global SCIP settings */
5743  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5744  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5745  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5746  SCIP_Real maxscale, /**< maximal allowed scalar */
5747  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5748  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5749  SCIP_Bool* success /**< stores whether returned value is valid */
5750  )
5751 {
5752 #ifndef NDEBUG
5753  SCIP_COL* col;
5754 #endif
5755  SCIP_Longint gcd;
5756  SCIP_Longint scm;
5757  SCIP_Longint nominator;
5758  SCIP_Longint denominator;
5759  SCIP_Real val;
5760  SCIP_Real absval;
5761  SCIP_Real minval;
5762  SCIP_Real scaleval;
5763  SCIP_Real twomultval;
5764  SCIP_Bool scalable;
5765  SCIP_Bool twomult;
5766  SCIP_Bool rational;
5767  int c;
5768  int s;
5769 
5770  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5771  assert(row != NULL);
5772  assert(row->len == 0 || row->cols != NULL);
5773  assert(row->len == 0 || row->cols_index != NULL);
5774  assert(row->len == 0 || row->vals != NULL);
5775  assert(maxdnom >= 1);
5776  assert(mindelta < 0.0);
5777  assert(maxdelta > 0.0);
5778  assert(success != NULL);
5779 
5780  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5781  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5782 
5783  if( intscalar != NULL )
5784  *intscalar = SCIP_INVALID;
5785  *success = FALSE;
5786 
5787  /* get minimal absolute non-zero value */
5788  minval = SCIP_REAL_MAX;
5789  for( c = 0; c < row->len; ++c )
5790  {
5791 #ifndef NDEBUG
5792  col = row->cols[c];
5793  assert(col != NULL);
5794  assert(col->var != NULL);
5795  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5796  assert(SCIPvarGetCol(col->var) == col);
5797 #endif
5798  val = row->vals[c];
5799  assert(!SCIPsetIsZero(set, val));
5800 
5801  if( val < mindelta || val > maxdelta )
5802  {
5803  absval = REALABS(val);
5804  minval = MIN(minval, absval);
5805  }
5806  }
5807  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5808  {
5809  /* all coefficients are zero (inside tolerances) */
5810  if( intscalar != NULL )
5811  *intscalar = 1.0;
5812  *success = TRUE;
5813  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5814 
5815  return SCIP_OKAY;
5816  }
5817  assert(minval > MIN(-mindelta, maxdelta));
5818  assert(SCIPsetIsPositive(set, minval));
5819  assert(!SCIPsetIsInfinity(set, minval));
5820 
5821  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5822  * and a power of 2
5823  */
5824  scaleval = 1.0/minval;
5825  scalable = (scaleval <= maxscale);
5826  for( c = 0; c < row->len && scalable; ++c )
5827  {
5828  /* don't look at continuous variables, if we don't have to */
5829  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5830  continue;
5831 
5832  /* check, if the coefficient can be scaled with a simple scalar */
5833  val = row->vals[c];
5834  absval = REALABS(val);
5835  while( scaleval <= maxscale
5836  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5837  {
5838  for( s = 0; s < nscalars; ++s )
5839  {
5840  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5841  {
5842  scaleval *= scalars[s];
5843  break;
5844  }
5845  }
5846  if( s >= nscalars )
5847  scaleval *= 2.0;
5848  }
5849  scalable = (scaleval <= maxscale);
5850  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5851  }
5852  if( scalable )
5853  {
5854  /* make row coefficients integral by dividing them by the smallest coefficient
5855  * (and multiplying them with a power of 2)
5856  */
5857  assert(scaleval <= maxscale);
5858  if( intscalar != NULL )
5859  *intscalar = scaleval;
5860  *success = TRUE;
5861  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5862 
5863  return SCIP_OKAY;
5864  }
5865 
5866  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5867  twomultval = 1.0;
5868  twomult = (twomultval <= maxscale);
5869  for( c = 0; c < row->len && twomult; ++c )
5870  {
5871  /* don't look at continuous variables, if we don't have to */
5872  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5873  continue;
5874 
5875  /* check, if the coefficient can be scaled with a simple scalar */
5876  val = row->vals[c];
5877  absval = REALABS(val);
5878  while( twomultval <= maxscale
5879  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5880  {
5881  for( s = 0; s < nscalars; ++s )
5882  {
5883  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5884  {
5885  twomultval *= scalars[s];
5886  break;
5887  }
5888  }
5889  if( s >= nscalars )
5890  twomultval *= 2.0;
5891  }
5892  twomult = (twomultval <= maxscale);
5893  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5894  val, twomultval, val*twomultval, twomult);
5895  }
5896  if( twomult )
5897  {
5898  /* make row coefficients integral by multiplying them with a power of 2 */
5899  assert(twomultval <= maxscale);
5900  if( intscalar != NULL )
5901  *intscalar = twomultval;
5902  *success = TRUE;
5903  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5904 
5905  return SCIP_OKAY;
5906  }
5907 
5908  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5909  * and the smallest common multiple of the denominators
5910  */
5911  gcd = 1;
5912  scm = 1;
5913  rational = (maxdnom > 1);
5914 
5915  /* first coefficient (to initialize gcd) */
5916  for( c = 0; c < row->len && rational; ++c )
5917  {
5918  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5919  {
5920  val = row->vals[c];
5921  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5922  if( rational && nominator != 0 )
5923  {
5924  assert(denominator > 0);
5925  gcd = ABS(nominator);
5926  scm = denominator;
5927  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5928  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5929  val, nominator, denominator, gcd, scm, rational);
5930  break;
5931  }
5932  }
5933  }
5934 
5935  /* remaining coefficients */
5936  for( ++c; c < row->len && rational; ++c )
5937  {
5938  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5939  {
5940  val = row->vals[c];
5941  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5942  if( rational && nominator != 0 )
5943  {
5944  assert(denominator > 0);
5945  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5946  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5947  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5948  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5949  val, nominator, denominator, gcd, scm, rational);
5950  }
5951  }
5952  }
5953 
5954  if( rational )
5955  {
5956  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5957  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5958  if( intscalar != NULL )
5959  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5960  *success = TRUE;
5961  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5962  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5963  }
5964  else
5965  {
5966  assert(!(*success));
5967  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5968  }
5969 
5970  return SCIP_OKAY;
5971 }
5972 
5973 /** tries to scale row, s.t. all coefficients become integral */
5975  SCIP_ROW* row, /**< LP row */
5976  BMS_BLKMEM* blkmem, /**< block memory */
5977  SCIP_SET* set, /**< global SCIP settings */
5978  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5979  SCIP_STAT* stat, /**< problem statistics */
5980  SCIP_LP* lp, /**< current LP data */
5981  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5982  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5983  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5984  SCIP_Real maxscale, /**< maximal value to scale row with */
5985  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5986  SCIP_Bool* success /**< stores whether row could be made rational */
5987  )
5988 {
5989  SCIP_Real intscalar;
5990 
5991  assert(success != NULL);
5992 
5993  /* calculate scalar to make coefficients integral */
5994  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5995  &intscalar, success) );
5996 
5997  if( *success )
5998  {
5999  /* scale the row */
6000  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
6001  }
6002 
6003  return SCIP_OKAY;
6004 }
6005 
6006 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6007  * higher ones
6008  */
6010  SCIP_ROW* row /**< row to be sorted */
6011  )
6012 {
6013  assert(row != NULL);
6014 
6015  /* sort LP columns */
6016  rowSortLP(row);
6017 
6018  /* sort non-LP columns */
6019  rowSortNonLP(row);
6020 
6021 #ifdef SCIP_MORE_DEBUG
6022  /* check the sorting */
6023  {
6024  int c;
6025  if( !row->delaysort )
6026  {
6027  for( c = 1; c < row->nlpcols; ++c )
6028  assert(row->cols[c]->index >= row->cols[c-1]->index);
6029  for( c = row->nlpcols + 1; c < row->len; ++c )
6030  assert(row->cols[c]->index >= row->cols[c-1]->index);
6031  }
6032  }
6033 #endif
6034 }
6035 
6036 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6037  * zero entries from row
6038  * the row must not be linked to the columns; otherwise, we would need to update the columns as
6039  * well, which is too expensive
6040  */
6041 static
6043  SCIP_ROW* row, /**< row to be sorted */
6044  SCIP_SET* set /**< global SCIP settings */
6045  )
6046 {
6047  assert(row != NULL);
6048  assert(!row->delaysort);
6049  assert(row->nunlinked == row->len);
6050  assert(row->nlpcols == 0);
6051 
6052  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6053 
6054  /* do nothing on empty rows; if row is sorted, nothing has to be done */
6055  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6056  {
6057  SCIP_COL** cols;
6058  int* cols_index;
6059  SCIP_Real* vals;
6060  int s;
6061  int t;
6062 
6063  /* make sure, the row is sorted */
6064  SCIProwSort(row);
6065  assert(row->lpcolssorted);
6066  assert(row->nonlpcolssorted);
6067 
6068  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6069  cols = row->cols;
6070  cols_index = row->cols_index;
6071  vals = row->vals;
6072  assert(cols != NULL);
6073  assert(cols_index != NULL);
6074  assert(vals != NULL);
6075 
6076  t = 0;
6077  row->integral = TRUE;
6078  assert(!SCIPsetIsZero(set, vals[0]));
6079  assert(row->linkpos[0] == -1);
6080 
6081  for( s = 1; s < row->len; ++s )
6082  {
6083  assert(!SCIPsetIsZero(set, vals[s]));
6084  assert(row->linkpos[s] == -1);
6085 
6086  if( cols[s] == cols[t] )
6087  {
6088  /* merge entries with equal column */
6089  vals[t] += vals[s];
6090  }
6091  else
6092  {
6093  /* go to the next entry, overwriting current entry if coefficient is zero */
6094  if( !SCIPsetIsZero(set, vals[t]) )
6095  {
6096  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6097  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6098 
6099  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6100  t++;
6101  }
6102  cols[t] = cols[s];
6103  cols_index[t] = cols_index[s];
6104  vals[t] = vals[s];
6105  }
6106  }
6107  if( !SCIPsetIsZero(set, vals[t]) )
6108  {
6109  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6110  t++;
6111  }
6112  assert(s == row->len);
6113  assert(t <= row->len);
6114 
6115  row->len = t;
6116  row->nunlinked = t;
6117 
6118  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6119  if( t < s )
6120  rowCalcNorms(row, set);
6121  }
6122 
6123 #ifndef NDEBUG
6124  /* check for double entries */
6125  {
6126  int i;
6127  int j;
6128 
6129  for( i = 0; i < row->len; ++i )
6130  {
6131  assert(row->cols[i] != NULL);
6132  assert(row->cols[i]->index == row->cols_index[i]);
6133  for( j = i+1; j < row->len; ++j )
6134  assert(row->cols[i] != row->cols[j]);
6135  }
6136  }
6137 #endif
6138 }
6139 
6140 /** enables delaying of row sorting */
6142  SCIP_ROW* row /**< LP row */
6143  )
6144 {
6145  assert(row != NULL);
6146  assert(!row->delaysort);
6147 
6148  row->delaysort = TRUE;
6149 }
6150 
6151 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6153  SCIP_ROW* row, /**< LP row */
6154  SCIP_SET* set /**< global SCIP settings */
6155  )
6156 {
6157  assert(row != NULL);
6158  assert(row->delaysort);
6159 
6160  row->delaysort = FALSE;
6161  rowMerge(row, set);
6162 }
6163 
6164 /** recalculates the current activity of a row */
6166  SCIP_ROW* row, /**< LP row */
6167  SCIP_STAT* stat /**< problem statistics */
6168  )
6169 {
6170  SCIP_COL* col;
6171  int c;
6172 
6173  assert(row != NULL);
6174  assert(stat != NULL);
6175 
6176  row->activity = row->constant;
6177  for( c = 0; c < row->nlpcols; ++c )
6178  {
6179  col = row->cols[c];
6180  assert(col != NULL);
6181  assert(col->primsol < SCIP_INVALID);
6182  assert(col->lppos >= 0);
6183  assert(row->linkpos[c] >= 0);
6184  row->activity += row->vals[c] * col->primsol;
6185  }
6186 
6187  if( row->nunlinked > 0 )
6188  {
6189  for( c = row->nlpcols; c < row->len; ++c )
6190  {
6191  col = row->cols[c];
6192  assert(col != NULL);
6193  assert(col->lppos >= 0 || col->primsol == 0.0);
6194  assert(col->lppos == -1 || row->linkpos[c] == -1);
6195  if( col->lppos >= 0 )
6196  row->activity += row->vals[c] * col->primsol;
6197  }
6198  }
6199 #ifndef NDEBUG
6200  else
6201  {
6202  for( c = row->nlpcols; c < row->len; ++c )
6203  {
6204  col = row->cols[c];
6205  assert(col != NULL);
6206  assert(col->primsol == 0.0);
6207  assert(col->lppos == -1);
6208  assert(row->linkpos[c] >= 0);
6209  }
6210  }
6211 #endif
6212 
6213  row->validactivitylp = stat->lpcount;
6214 }
6215 
6216 /** returns the activity of a row in the current LP solution */
6218  SCIP_ROW* row, /**< LP row */
6219  SCIP_SET* set, /**< global SCIP settings */
6220  SCIP_STAT* stat, /**< problem statistics */
6221  SCIP_LP* lp /**< current LP data */
6222  )
6223 {
6224  SCIP_Real inf;
6225  SCIP_Real activity;
6226 
6227  assert(row != NULL);
6228  assert(stat != NULL);
6229  assert(lp != NULL);
6230  assert(row->validactivitylp <= stat->lpcount);
6231  assert(lp->validsollp == stat->lpcount);
6232 
6233  if( row->validactivitylp != stat->lpcount )
6234  SCIProwRecalcLPActivity(row, stat);
6235  assert(row->validactivitylp == stat->lpcount);
6236  assert(row->activity < SCIP_INVALID);
6237 
6238  activity = row->activity;
6239  inf = SCIPsetInfinity(set);
6240  activity = MAX(activity, -inf);
6241  activity = MIN(activity, +inf);
6242 
6243  return activity;
6244 }
6245 
6246 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6248  SCIP_ROW* row, /**< LP row */
6249  SCIP_SET* set, /**< global SCIP settings */
6250  SCIP_STAT* stat, /**< problem statistics */
6251  SCIP_LP* lp /**< current LP data */
6252  )
6253 {
6254  SCIP_Real activity;
6255 
6256  assert(row != NULL);
6257 
6258  activity = SCIProwGetLPActivity(row, set, stat, lp);
6259 
6260  return MIN(row->rhs - activity, activity - row->lhs);
6261 }
6262 
6263 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6264  *
6265  * @todo Implement calculation of activities similar to LPs.
6266  */
6268  SCIP_ROW* row, /**< LP row */
6269  SCIP_SET* set, /**< global SCIP settings */
6270  SCIP_STAT* stat /**< problem statistics */
6271  )
6272 {
6273  SCIP_Real inf;
6274  SCIP_Real activity;
6275  SCIP_COL* col;
6276  int c;
6277 
6278  assert( row != NULL );
6279  assert( stat != NULL );
6280 
6281  activity = row->constant;
6282  for (c = 0; c < row->nlpcols; ++c)
6283  {
6284  col = row->cols[c];
6285  assert( col != NULL );
6286  assert( col->lppos >= 0 );
6287  assert( col->var != NULL );
6288  assert( row->linkpos[c] >= 0 );
6289  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6290  }
6291 
6292  if ( row->nunlinked > 0 )
6293  {
6294  for (c = row->nlpcols; c < row->len; ++c)
6295  {
6296  col = row->cols[c];
6297  assert( col != NULL );
6298  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6299  if ( col->lppos >= 0 )
6300  {
6301  assert( col->var != NULL );
6302  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6303  }
6304  }
6305  }
6306 #ifndef NDEBUG
6307  else
6308  {
6309  for (c = row->nlpcols; c < row->len; ++c)
6310  {
6311  col = row->cols[c];
6312  assert( col != NULL );
6313  assert( col->lppos == -1 );
6314  assert( row->linkpos[c] >= 0 );
6315  }
6316  }
6317 #endif
6318  inf = SCIPsetInfinity(set);
6319  activity = MAX(activity, -inf);
6320  activity = MIN(activity, +inf);
6321 
6322  return MIN(row->rhs - activity, activity - row->lhs);
6323 }
6324 
6325 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6326  *
6327  * @todo Implement calculation of activities similar to LPs.
6328  */
6330  SCIP_ROW* row, /**< LP row */
6331  SCIP_SET* set, /**< global SCIP settings */
6332  SCIP_STAT* stat /**< problem statistics */
6333  )
6334 {
6335  SCIP_Real inf;
6336  SCIP_Real activity;
6337  SCIP_COL* col;
6338  int c;
6339 
6340  assert( row != NULL );
6341  assert( stat != NULL );
6342 
6343  activity = row->constant;
6344  for (c = 0; c < row->nlpcols; ++c)
6345  {
6346  col = row->cols[c];
6347  assert( col != NULL );
6348  assert( col->lppos >= 0 );
6349  assert( col->var != NULL );
6350  assert( row->linkpos[c] >= 0 );
6351  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6352  }
6353 
6354  if ( row->nunlinked > 0 )
6355  {
6356  for (c = row->nlpcols; c < row->len; ++c)
6357  {
6358  col = row->cols[c];
6359  assert( col != NULL );
6360  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6361  if ( col->lppos >= 0 )
6362  {
6363  assert( col->var != NULL );
6364  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6365  }
6366  }
6367  }
6368 #ifndef NDEBUG
6369  else
6370  {
6371  for (c = row->nlpcols; c < row->len; ++c)
6372  {
6373  col = row->cols[c];
6374  assert( col != NULL );
6375  assert( col->lppos == -1 );
6376  assert( row->linkpos[c] >= 0 );
6377  }
6378  }
6379 #endif
6380  inf = SCIPsetInfinity(set);
6381  activity = MAX(activity, -inf);
6382  activity = MIN(activity, +inf);
6383 
6384  return MIN(row->rhs - activity, activity - row->lhs);
6385 }
6386 
6387 /** calculates the current pseudo activity of a row */
6389  SCIP_ROW* row, /**< row data */
6390  SCIP_STAT* stat /**< problem statistics */
6391  )
6392 {
6393  SCIP_COL* col;
6394  int i;
6395 
6396  assert(row != NULL);
6397  assert(stat != NULL);
6398 
6399  row->pseudoactivity = row->constant;
6400  for( i = 0; i < row->len; ++i )
6401  {
6402  col = row->cols[i];
6403  assert(col != NULL);
6404  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6405  assert(col->var != NULL);
6406  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6407 
6408  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6409  }
6410  row->validpsactivitydomchg = stat->domchgcount;
6411  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6412 }
6413 
6414 /** returns the pseudo activity of a row in the current pseudo solution */
6416  SCIP_ROW* row, /**< LP row */
6417  SCIP_SET* set, /**< global SCIP settings */
6418  SCIP_STAT* stat /**< problem statistics */
6419  )
6420 {
6421  SCIP_Real inf;
6422  SCIP_Real activity;
6423 
6424  assert(row != NULL);
6425  assert(stat != NULL);
6426  assert(row->validpsactivitydomchg <= stat->domchgcount);
6427 
6428  /* check, if pseudo activity has to be calculated */
6429  if( row->validpsactivitydomchg != stat->domchgcount )
6430  SCIProwRecalcPseudoActivity(row, stat);
6431  assert(row->validpsactivitydomchg == stat->domchgcount);
6432  assert(row->pseudoactivity < SCIP_INVALID);
6433 
6434  activity = row->pseudoactivity;
6435  inf = SCIPsetInfinity(set);
6436  activity = MAX(activity, -inf);
6437  activity = MIN(activity, +inf);
6438 
6439  return activity;
6440 }
6441 
6442 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6444  SCIP_ROW* row, /**< LP row */
6445  SCIP_SET* set, /**< global SCIP settings */
6446  SCIP_STAT* stat /**< problem statistics */
6447  )
6448 {
6449  SCIP_Real pseudoactivity;
6450 
6451  assert(row != NULL);
6452 
6453  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6454 
6455  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6456 }
6457 
6458 /** returns the activity of a row for a given solution */
6460  SCIP_ROW* row, /**< LP row */
6461  SCIP_SET* set, /**< global SCIP settings */
6462  SCIP_STAT* stat, /**< problem statistics data */
6463  SCIP_SOL* sol /**< primal CIP solution */
6464  )
6465 {
6466  SCIP_COL* col;
6467  SCIP_Real inf;
6468  SCIP_Real activity;
6469  SCIP_Real solval;
6470  int i;
6471 
6472  assert(row != NULL);
6473 
6474  activity = row->constant;
6475  for( i = 0; i < row->len; ++i )
6476  {
6477  col = row->cols[i];
6478  assert(col != NULL);
6479  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6480  solval = SCIPsolGetVal(sol, set, stat, col->var);
6481  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6482  {
6483  if( SCIPsetIsInfinity(set, -row->lhs) )
6484  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6485  else if( SCIPsetIsInfinity(set, row->rhs) )
6486  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6487  else
6488  solval = (col->lb + col->ub)/2.0;
6489  }
6490  activity += row->vals[i] * solval;
6491  }
6492 
6493  inf = SCIPsetInfinity(set);
6494  activity = MAX(activity, -inf);
6495  activity = MIN(activity, +inf);
6496 
6497  return activity;
6498 }
6499 
6500 /** returns the feasibility of a row for the given solution */
6502  SCIP_ROW* row, /**< LP row */
6503  SCIP_SET* set, /**< global SCIP settings */
6504  SCIP_STAT* stat, /**< problem statistics data */
6505  SCIP_SOL* sol /**< primal CIP solution */
6506  )
6507 {
6508  SCIP_Real activity;
6509 
6510  assert(row != NULL);
6511 
6512  activity = SCIProwGetSolActivity(row, set, stat, sol);
6513 
6514  return MIN(row->rhs - activity, activity - row->lhs);
6515 }
6516 
6517 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6518 static
6520  SCIP_ROW* row, /**< row data */
6521  SCIP_SET* set, /**< global SCIP settings */
6522  SCIP_STAT* stat /**< problem statistics data */
6523  )
6524 {
6525  SCIP_COL* col;
6526  SCIP_Real val;
6527  SCIP_Bool mininfinite;
6528  SCIP_Bool maxinfinite;
6529  int i;
6530 
6531  assert(row != NULL);
6532  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6533  assert(stat != NULL);
6534 
6535  /* calculate activity bounds */
6536  mininfinite = FALSE;
6537  maxinfinite = FALSE;
6538  row->minactivity = row->constant;
6539  row->maxactivity = row->constant;
6540  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6541  {
6542  col = row->cols[i];
6543  assert(col != NULL);
6544  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6545  val = row->vals[i];
6546  if( val >= 0.0 )
6547  {
6548  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6549  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6550  if( !mininfinite )
6551  row->minactivity += val * col->lb;
6552  if( !maxinfinite )
6553  row->maxactivity += val * col->ub;
6554  }
6555  else
6556  {
6557  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6558  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6559  if( !mininfinite )
6560  row->minactivity += val * col->ub;
6561  if( !maxinfinite )
6562  row->maxactivity += val * col->lb;
6563  }
6564  }
6565 
6566  if( mininfinite )
6567  row->minactivity = -SCIPsetInfinity(set);
6568  if( maxinfinite )
6569  row->maxactivity = SCIPsetInfinity(set);
6570  row->validactivitybdsdomchg = stat->domchgcount;
6571 
6572 #ifndef NDEBUG
6573  {
6574  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6575 
6576  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6577  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6578  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6579  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6580  * tolerance as a proxy to account for the accumulation effect
6581  */
6582  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6583  || EPSISINT(row->minactivity - row->constant, inttol));
6584  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6585  || EPSISINT(row->maxactivity - row->constant, inttol));
6586  }
6587 #endif
6588 }
6589 
6590 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6592  SCIP_ROW* row, /**< LP row */
6593  SCIP_SET* set, /**< global SCIP settings */
6594  SCIP_STAT* stat /**< problem statistics data */
6595  )
6596 {
6597  assert(row != NULL);
6598  assert(stat != NULL);
6599  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6600 
6601  /* check, if activity bounds has to be calculated */
6602  if( row->validactivitybdsdomchg != stat->domchgcount )
6603  rowCalcActivityBounds(row, set, stat);
6604  assert(row->validactivitybdsdomchg == stat->domchgcount);
6605  assert(row->minactivity < SCIP_INVALID);
6606  assert(row->maxactivity < SCIP_INVALID);
6607 
6608  return row->minactivity;
6609 }
6610 
6611 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6613  SCIP_ROW* row, /**< LP row */
6614  SCIP_SET* set, /**< global SCIP settings */
6615  SCIP_STAT* stat /**< problem statistics data */
6616  )
6617 {
6618  assert(row != NULL);
6619  assert(stat != NULL);
6620  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6621 
6622  /* check, if activity bounds has to be calculated */
6623  if( row->validactivitybdsdomchg != stat->domchgcount )
6624  rowCalcActivityBounds(row, set, stat);
6625  assert(row->validactivitybdsdomchg == stat->domchgcount);
6626  assert(row->minactivity < SCIP_INVALID);
6627  assert(row->maxactivity < SCIP_INVALID);
6628 
6629  return row->maxactivity;
6630 }
6631 
6632 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6634  SCIP_ROW* row, /**< LP row */
6635  SCIP_SET* set, /**< global SCIP settings */
6636  SCIP_STAT* stat /**< problem statistics data */
6637  )
6638 {
6639  assert(row != NULL);
6640 
6641  if( row->modifiable )
6642  return FALSE;
6643  if( !SCIPsetIsInfinity(set, -row->lhs) )
6644  {
6645  SCIP_Real minactivity;
6646 
6647  minactivity = SCIProwGetMinActivity(row, set, stat);
6648  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6649  return FALSE;
6650  }
6651  if( !SCIPsetIsInfinity(set, row->rhs) )
6652  {
6653  SCIP_Real maxactivity;
6654 
6655  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6656  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6657  return FALSE;
6658  }
6659 
6660  return TRUE;
6661 }
6662 
6663 /** gets maximal absolute value of row vector coefficients */
6665  SCIP_ROW* row, /**< LP row */
6666  SCIP_SET* set /**< global SCIP settings */
6667  )
6668 {
6669  assert(row != NULL);
6670 
6671  if( row->nummaxval == 0 )
6672  rowCalcIdxsAndVals(row, set);
6673  assert(row->nummaxval > 0);
6674  assert(row->maxval >= 0.0 || row->len == 0);
6675 
6676  return row->maxval;
6677 }
6678 
6679 /** gets minimal absolute value of row vector's non-zero coefficients */
6681  SCIP_ROW* row, /**< LP row */
6682  SCIP_SET* set /**< global SCIP settings */
6683  )
6684 {
6685  assert(row != NULL);
6686 
6687  if( row->numminval == 0 )
6688  rowCalcIdxsAndVals(row, set);
6689  assert(row->numminval > 0);
6690  assert(row->minval >= 0.0 || row->len == 0);
6691 
6692  return row->minval;
6693 }
6694 
6695 /** gets maximal column index of row entries */
6697  SCIP_ROW* row, /**< LP row */
6698  SCIP_SET* set /**< global SCIP settings */
6699  )
6700 {
6701  assert(row != NULL);
6702 
6703  if( row->validminmaxidx == 0 )
6704  rowCalcIdxsAndVals(row, set);
6705  assert(row->maxidx >= 0 || row->len == 0);
6706  assert(row->validminmaxidx);
6707 
6708  return row->maxidx;
6709 }
6710 
6711 /** gets minimal column index of row entries */
6713  SCIP_ROW* row, /**< LP row */
6714  SCIP_SET* set /**< global SCIP settings */
6715  )
6716 {
6717  assert(row != NULL);
6718 
6719  if( row->validminmaxidx == 0 )
6720  rowCalcIdxsAndVals(row, set);
6721  assert(row->minidx >= 0 || row->len == 0);
6722  assert(row->validminmaxidx);
6723 
6724  return row->minidx;
6725 }
6726 
6727 /** gets number of integral columns in row */
6729  SCIP_ROW* row, /**< LP row */
6730  SCIP_SET* set /**< global SCIP settings */
6731  )
6732 {
6733  assert(row != NULL);
6734 
6735  if( row->numintcols == -1 )
6736  rowCalcIdxsAndVals(row, set);
6737 
6738  assert(row->numintcols <= row->len && row->numintcols >= 0);
6739 
6740  return row->numintcols;
6741 }
6742 
6743 /** returns row's cutoff distance in the direction of the given primal solution */
6745  SCIP_ROW* row, /**< LP row */
6746  SCIP_SET* set, /**< global SCIP settings */
6747  SCIP_STAT* stat, /**< problem statistics data */
6748  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6749  SCIP_LP* lp /**< current LP data */
6750  )
6751 {
6752  SCIP_Real solcutoffdist;
6753  int k;
6754 
6755  assert(sol != NULL);
6756 
6757  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6758  {
6759  SCIP_Real scale = 0.0;
6760 
6761  lp->validsoldirlp = stat->lpcount;
6762  lp->validsoldirsol = sol;
6763 
6765 
6766  for( k = 0; k < lp->ncols; ++k )
6767  {
6768  assert(lp->cols[k]->lppos == k);
6769  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6770  scale += SQR(lp->soldirection[k]);
6771  }
6772 
6773  if( scale > 0.0 )
6774  {
6775  scale = 1.0 / SQRT(scale);
6776 
6777  for( k = 0; k < lp->ncols; ++k )
6778  lp->soldirection[k] *= scale;
6779  }
6780  }
6781 
6782  solcutoffdist = 0.0;
6783  for( k = 0; k < row->nlpcols; ++k )
6784  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6785 
6786  for( k = row->nlpcols; k < row->len; ++k )
6787  {
6788  if( row->cols[k]->lppos >= 0 )
6789  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6790  }
6791 
6792  if( SCIPsetIsSumZero(set, solcutoffdist) )
6793  solcutoffdist = set->num_sumepsilon;
6794 
6795  solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
6796 
6797  return solcutoffdist;
6798 }
6799 
6800 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6802  SCIP_ROW* row, /**< LP row */
6803  SCIP_SET* set, /**< global SCIP settings */
6804  SCIP_STAT* stat, /**< problem statistics data */
6805  SCIP_LP* lp /**< current LP data */
6806  )
6807 {
6808  SCIP_Real norm;
6809  SCIP_Real feasibility;
6810  SCIP_Real eps;
6811 
6812  assert(set != NULL);
6813 
6814  switch( set->sepa_efficacynorm )
6815  {
6816  case 'e':
6817  norm = SCIProwGetNorm(row);
6818  break;
6819  case 'm':
6820  norm = SCIProwGetMaxval(row, set);
6821  break;
6822  case 's':
6823  norm = SCIProwGetSumNorm(row);
6824  break;
6825  case 'd':
6826  norm = (row->len == 0 ? 0.0 : 1.0);
6827  break;
6828  default:
6829  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6830  SCIPABORT();
6831  norm = 0.0; /*lint !e527*/
6832  }
6833 
6834  eps = SCIPsetSumepsilon(set);
6835  norm = MAX(norm, eps);
6836  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6837 
6838  return -feasibility / norm;
6839 }
6840 
6841 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6843  SCIP_ROW* row, /**< LP row */
6844  SCIP_SET* set, /**< global SCIP settings */
6845  SCIP_STAT* stat, /**< problem statistics data */
6846  SCIP_LP* lp, /**< current LP data */
6847  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6848  )
6849 {
6850  SCIP_Real efficacy;
6851 
6852  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6853 
6854  return SCIPsetIsEfficacious(set, root, efficacy);
6855 }
6856 
6857 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6859  SCIP_ROW* row, /**< LP row */
6860  SCIP_SET* set, /**< global SCIP settings */
6861  SCIP_STAT* stat, /**< problem statistics data */
6862  SCIP_SOL* sol /**< primal CIP solution */
6863  )
6864 {
6865  SCIP_Real norm;
6866  SCIP_Real feasibility;
6867  SCIP_Real eps;
6868 
6869  assert(set != NULL);
6870 
6871  switch( set->sepa_efficacynorm )
6872  {
6873  case 'e':
6874  norm = SCIProwGetNorm(row);
6875  break;
6876  case 'm':
6877  norm = SCIProwGetMaxval(row, set);
6878  break;
6879  case 's':
6880  norm = SCIProwGetSumNorm(row);
6881  break;
6882  case 'd':
6883  norm = (row->len == 0 ? 0.0 : 1.0);
6884  break;
6885  default:
6886  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6887  SCIPABORT();
6888  norm = 0.0; /*lint !e527*/
6889  }
6890 
6891  eps = SCIPsetSumepsilon(set);
6892  norm = MAX(norm, eps);
6893  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6894 
6895  return -feasibility / norm;
6896 }
6897 
6898 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6899  * efficacy
6900  */
6902  SCIP_ROW* row, /**< LP row */
6903  SCIP_SET* set, /**< global SCIP settings */
6904  SCIP_STAT* stat, /**< problem statistics data */
6905  SCIP_SOL* sol, /**< primal CIP solution */
6906  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6907  )
6908 {
6909  SCIP_Real efficacy;
6910 
6911  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6912 
6913  return SCIPsetIsEfficacious(set, root, efficacy);
6914 }
6915 
6916 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6918  SCIP_ROW* row, /**< LP row */
6919  SCIP_SET* set, /**< global SCIP settings */
6920  SCIP_STAT* stat /**< problem statistics data */
6921  )
6922 {
6923  SCIP_Real norm;
6924  SCIP_Real feasibility;
6925  SCIP_Real eps;
6926 
6927  assert(set != NULL);
6928 
6929  switch( set->sepa_efficacynorm )
6930  {
6931  case 'e':
6932  norm = SCIProwGetNorm(row);
6933  break;
6934  case 'm':
6935  norm = SCIProwGetMaxval(row, set);
6936  break;
6937  case 's':
6938  norm = SCIProwGetSumNorm(row);
6939  break;
6940  case 'd':
6941  norm = (row->len == 0 ? 0.0 : 1.0);
6942  break;
6943  default:
6944  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6945  SCIPABORT();
6946  norm = 0.0; /*lint !e527*/
6947  }
6948 
6949  eps = SCIPsetSumepsilon(set);
6950  norm = MAX(norm, eps);
6951  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6952 
6953  return -feasibility / norm;
6954 }
6955 
6956 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6958  SCIP_ROW* row, /**< LP row */
6959  SCIP_SET* set, /**< global SCIP settings */
6960  SCIP_STAT* stat /**< problem statistics data */
6961  )
6962 {
6963  SCIP_Real norm;
6964  SCIP_Real feasibility;
6965  SCIP_Real eps;
6966 
6967  assert(set != NULL);
6968 
6969  switch( set->sepa_efficacynorm )
6970  {
6971  case 'e':
6972  norm = SCIProwGetNorm(row);
6973  break;
6974  case 'm':
6975  norm = SCIProwGetMaxval(row, set);
6976  break;
6977  case 's':
6978  norm = SCIProwGetSumNorm(row);
6979  break;
6980  case 'd':
6981  norm = (row->len == 0 ? 0.0 : 1.0);
6982  break;
6983  default:
6984  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6985  SCIPABORT();
6986  norm = 0.0; /*lint !e527*/
6987  }
6988 
6989  eps = SCIPsetSumepsilon(set);
6990  norm = MAX(norm, eps);
6991  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6992 
6993  return -feasibility / norm;
6994 }
6995 
6996 /** returns the scalar product of the coefficient vectors of the two given rows
6997  *
6998  * @note the scalar product is computed w.r.t. the current LP columns only
6999  * @todo also consider non-LP columns for the computation?
7000  */
7002  SCIP_ROW* row1, /**< first LP row */
7003  SCIP_ROW* row2 /**< second LP row */
7004  )
7005 {
7006  SCIP_Real scalarprod;
7007  int* row1colsidx;
7008  int* row2colsidx;
7009  int i1;
7010  int i2;
7011 
7012  assert(row1 != NULL);
7013  assert(row2 != NULL);
7014 
7015  /* Sort the column indices of both rows.
7016  *
7017  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7018  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7019  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7020  * for both or one of the non-LP columns for both.
7021  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7022  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7023  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7024  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7025  *
7026  * We distinguish the following cases:
7027  *
7028  * 1) both rows have no unlinked columns
7029  * -> we just check the LP partitions
7030  *
7031  * 2) exactly one row is completely unlinked, the other one is completely linked
7032  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7033  * (thus all common LP columns are regarded)
7034  *
7035  * 3) we have unlinked and LP columns in both rows
7036  * -> we need to compare four partitions at once
7037  *
7038  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7039  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7040  * other row
7041  *
7042  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7043  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7044  *
7045  * 5) both rows are completely unlinked
7046  * -> we need to compare two partitions: both complete rows
7047  */
7048  SCIProwSort(row1);
7049  assert(row1->lpcolssorted);
7050  assert(row1->nonlpcolssorted);
7051  SCIProwSort(row2);
7052  assert(row2->lpcolssorted);
7053  assert(row2->nonlpcolssorted);
7054 
7055  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7056  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7057 
7058  row1colsidx = row1->cols_index;
7059  row2colsidx = row2->cols_index;
7060 
7061 #ifndef NDEBUG
7062  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7063  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7064  {
7065  i1 = 0;
7066  i2 = row2->nlpcols;
7067  while( i1 < row1->nlpcols && i2 < row2->len )
7068  {
7069  assert(row1->cols[i1] != row2->cols[i2]);
7070  if( row1->cols[i1]->index < row2->cols[i2]->index )
7071  ++i1;
7072  else
7073  {
7074  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7075  ++i2;
7076  }
7077  }
7078  assert(i1 == row1->nlpcols || i2 == row2->len);
7079 
7080  i1 = row1->nlpcols;
7081  i2 = 0;
7082  while( i1 < row1->len && i2 < row2->nlpcols )
7083  {
7084  assert(row1->cols[i1] != row2->cols[i2]);
7085  if( row1->cols[i1]->index < row2->cols[i2]->index )
7086  ++i1;
7087  else
7088  {
7089  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7090  ++i2;
7091  }
7092  }
7093  assert(i1 == row1->len || i2 == row2->nlpcols);
7094  }
7095 #endif
7096 
7097  /* The "easy" cases 1) and 2) */
7098  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7099  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7100  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7101  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7102  {
7103  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7104  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7105 
7106  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7107  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7108  */
7109  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7110  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7111  scalarprod = 0.0;
7112 
7113  /* calculate the scalar product */
7114  while( i1 >= 0 && i2 >= 0 )
7115  {
7116  assert(row1->cols[i1]->index == row1colsidx[i1]);
7117  assert(row2->cols[i2]->index == row2colsidx[i2]);
7118  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7119  if( row1colsidx[i1] < row2colsidx[i2] )
7120  --i2;
7121  else if( row1colsidx[i1] > row2colsidx[i2] )
7122  --i1;
7123  else
7124  {
7125  scalarprod += row1->vals[i1] * row2->vals[i2];
7126  --i1;
7127  --i2;
7128  }
7129  }
7130  }
7131  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7132  else
7133  {
7134  SCIP_Bool lpcols;
7135  int ilp1;
7136  int inlp1;
7137  int ilp2;
7138  int inlp2;
7139  int end1;
7140  int end2;
7141 
7142  scalarprod = 0;
7143  ilp1 = 0;
7144  ilp2 = 0;
7145 
7146  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7147  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7148  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7149 
7150  /* handle the case of four partitions (case 3) until one partition is finished;
7151  * cases 4a), 4b), and 5) will fail the while-condition
7152  */
7153  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7154  {
7155  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7156  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7157  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7158  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7159  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7160  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7161  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7162  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7163 
7164  /* rows have the same linked LP columns */
7165  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7166  {
7167  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7168  ++ilp1;
7169  ++ilp2;
7170  }
7171  /* LP column of row1 is the same as unlinked column of row2 */
7172  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7173  {
7174  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7175  ++ilp1;
7176  ++inlp2;
7177  }
7178  /* unlinked column of row1 is the same as LP column of row2 */
7179  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7180  {
7181  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7182  ++inlp1;
7183  ++ilp2;
7184  }
7185  /* two unlinked LP columns are the same */
7186  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7187  {
7188  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7189  ++inlp1;
7190  ++inlp2;
7191  }
7192  /* increase smallest counter */
7193  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7194  {
7195  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7196  {
7197  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7198  ++ilp1;
7199  else
7200  ++ilp2;
7201  }
7202  else
7203  {
7204  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7205  ++ilp1;
7206  else
7207  ++inlp2;
7208  }
7209  }
7210  else
7211  {
7212  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7213  {
7214  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7215  ++inlp1;
7216  else
7217  ++ilp2;
7218  }
7219  else
7220  {
7221  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7222  ++inlp1;
7223  else
7224  ++inlp2;
7225  }
7226  }
7227  }
7228 
7229  /* One partition was completely handled, we just have to handle the three remaining partitions:
7230  * the remaining partition of this row and the two partitions of the other row.
7231  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7232  */
7233  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7234  {
7235  int tmpilp;
7236  int tmpinlp;
7237 
7238  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7239 
7240  SCIPswapPointers((void**) &row1, (void**) &row2);
7241  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7242  tmpilp = ilp1;
7243  tmpinlp = inlp1;
7244  ilp1 = ilp2;
7245  inlp1 = inlp2;
7246  ilp2 = tmpilp;
7247  inlp2 = tmpinlp;
7248  }
7249 
7250  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7251  * -> this merges cases 4a) and 4b)
7252  */
7253  if( ilp1 == row1->nlpcols )
7254  {
7255  i1 = inlp1;
7256  end1 = row1->len;
7257  lpcols = FALSE;
7258  }
7259  else
7260  {
7261  assert(inlp1 == row1->len);
7262 
7263  i1 = ilp1;
7264  end1 = row1->nlpcols;
7265  lpcols = TRUE;
7266  }
7267 
7268  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7269  * case 5) will fail the while-condition
7270  */
7271  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7272  {
7273  assert(row1->cols[i1]->index == row1colsidx[i1]);
7274  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7275  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7276  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7277  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7278 
7279  /* current column in row 1 is the same as the current LP column in row 2 */
7280  if( row1colsidx[i1] == row2colsidx[ilp2] )
7281  {
7282  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7283  ++i1;
7284  ++ilp2;
7285  }
7286  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7287  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7288  {
7289  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7290  ++i1;
7291  ++inlp2;
7292  }
7293  /* increase smallest counter */
7294  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7295  {
7296  if( row1colsidx[i1] < row2colsidx[ilp2] )
7297  ++i1;
7298  else
7299  ++ilp2;
7300  }
7301  else
7302  {
7303  if( row1colsidx[i1] < row2colsidx[inlp2] )
7304  ++i1;
7305  else
7306  ++inlp2;
7307  }
7308  }
7309 
7310  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7311  * the two rows
7312  */
7313  if( i1 < end1 )
7314  {
7315  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7316  if( ilp2 == row2->nlpcols )
7317  {
7318  i2 = inlp2;
7319  end2 = row2->len;
7320  lpcols = FALSE;
7321  }
7322  else
7323  {
7324  assert(inlp2 == row2->len);
7325 
7326  i2 = ilp2;
7327  end2 = row2->nlpcols;
7328  }
7329 
7330  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7331  while( i1 < end1 && i2 < end2 )
7332  {
7333  assert(row1->cols[i1]->index == row1colsidx[i1]);
7334  assert(row2->cols[i2]->index == row2colsidx[i2]);
7335  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7336 
7337  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7338  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7339  {
7340  scalarprod += row1->vals[i1] * row2->vals[i2];
7341  ++i1;
7342  ++i2;
7343  }
7344  /* increase smallest counter */
7345  else if( row1colsidx[i1] < row2colsidx[i2] )
7346  ++i1;
7347  else
7348  ++i2;
7349  }
7350  }
7351  }
7352 
7353  return scalarprod;
7354 }
7355 
7356 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7357 static
7359  SCIP_ROW* row1, /**< first LP row */
7360  SCIP_ROW* row2 /**< second LP row */
7361  )
7362 {
7363  int prod;
7364  int* row1colsidx;
7365  int* row2colsidx;
7366  int i1;
7367  int i2;
7368 
7369  assert(row1 != NULL);
7370  assert(row2 != NULL);
7371 
7372  /* Sort the column indices of both rows.
7373  *
7374  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7375  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7376  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7377  * for both or one of the non-LP columns for both.
7378  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7379  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7380  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7381  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7382  *
7383  * We distinguish the following cases:
7384  *
7385  * 1) both rows have no unlinked columns
7386  * -> we just check the LP partitions
7387  *
7388  * 2) exactly one row is completely unlinked, the other one is completely linked
7389  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7390  * (thus all common LP columns are regarded)
7391  *
7392  * 3) we have unlinked and LP columns in both rows
7393  * -> we need to compare four partitions at once
7394  *
7395  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7396  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7397  * other row
7398  *
7399  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7400  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7401  *
7402  * 5) both rows are completely unlinked
7403  * -> we need to compare two partitions: both complete rows
7404  */
7405  SCIProwSort(row1);
7406  assert(row1->lpcolssorted);
7407  assert(row1->nonlpcolssorted);
7408  SCIProwSort(row2);
7409  assert(row2->lpcolssorted);
7410  assert(row2->nonlpcolssorted);
7411 
7412  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7413  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7414 
7415  row1colsidx = row1->cols_index;
7416  row2colsidx = row2->cols_index;
7417 
7418 #ifndef NDEBUG
7419  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7420  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7421  {
7422  i1 = 0;
7423  i2 = row2->nlpcols;
7424  while( i1 < row1->nlpcols && i2 < row2->len )
7425  {
7426  assert(row1->cols[i1] != row2->cols[i2]);
7427  if( row1->cols[i1]->index < row2->cols[i2]->index )
7428  ++i1;
7429  else
7430  {
7431  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7432  ++i2;
7433  }
7434  }
7435  assert(i1 == row1->nlpcols || i2 == row2->len);
7436 
7437  i1 = row1->nlpcols;
7438  i2 = 0;
7439  while( i1 < row1->len && i2 < row2->nlpcols )
7440  {
7441  assert(row1->cols[i1] != row2->cols[i2]);
7442  if( row1->cols[i1]->index < row2->cols[i2]->index )
7443  ++i1;
7444  else
7445  {
7446  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7447  ++i2;
7448  }
7449  }
7450  assert(i1 == row1->len || i2 == row2->nlpcols);
7451  }
7452 #endif
7453 
7454  /* The "easy" cases 1) and 2) */
7455  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7456  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7457  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7458  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7459  {
7460  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7461  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7462 
7463  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7464  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7465  */
7466  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7467  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7468  prod = 0;
7469 
7470  /* calculate the scalar product */
7471  while( i1 >= 0 && i2 >= 0 )
7472  {
7473  assert(row1->cols[i1]->index == row1colsidx[i1]);
7474  assert(row2->cols[i2]->index == row2colsidx[i2]);
7475  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7476  if( row1colsidx[i1] < row2colsidx[i2] )
7477  --i2;
7478  else if( row1colsidx[i1] > row2colsidx[i2] )
7479  --i1;
7480  else
7481  {
7482  ++prod;
7483  --i1;
7484  --i2;
7485  }
7486  }
7487  }
7488  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7489  else
7490  {
7491  SCIP_Bool lpcols;
7492  int ilp1;
7493  int inlp1;
7494  int ilp2;
7495  int inlp2;
7496  int end1;
7497  int end2;
7498 
7499  prod = 0;
7500  ilp1 = 0;
7501  ilp2 = 0;
7502 
7503  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7504  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7505  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7506 
7507  /* handle the case of four partitions (case 3) until one partition is finished;
7508  * cases 4a), 4b), and 5) will fail the while-condition
7509  */
7510  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7511  {
7512  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7513  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7514  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7515  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7516  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7517  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7518  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7519  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7520 
7521  /* rows have the same linked LP columns */
7522  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7523  {
7524  ++prod;
7525  ++ilp1;
7526  ++ilp2;
7527  }
7528  /* LP column of row1 is the same as unlinked column of row2 */
7529  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7530  {
7531  ++prod;
7532  ++ilp1;
7533  ++inlp2;
7534  }
7535  /* unlinked column of row1 is the same as LP column of row2 */
7536  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7537  {
7538  ++prod;
7539  ++inlp1;
7540  ++ilp2;
7541  }
7542  /* two unlinked LP columns are the same */
7543  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7544  {
7545  ++prod;
7546  ++inlp1;
7547  ++inlp2;
7548  }
7549  /* increase smallest counter */
7550  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7551  {
7552  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7553  {
7554  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7555  ++ilp1;
7556  else
7557  ++ilp2;
7558  }
7559  else
7560  {
7561  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7562  ++ilp1;
7563  else
7564  ++inlp2;
7565  }
7566  }
7567  else
7568  {
7569  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7570  {
7571  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7572  ++inlp1;
7573  else
7574  ++ilp2;
7575  }
7576  else
7577  {
7578  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7579  ++inlp1;
7580  else
7581  ++inlp2;
7582  }
7583  }
7584  }
7585 
7586  /* One partition was completely handled, we just have to handle the three remaining partitions:
7587  * the remaining partition of this row and the two partitions of the other row.
7588  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7589  */
7590  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7591  {
7592  int tmpilp;
7593  int tmpinlp;
7594 
7595  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7596 
7597  SCIPswapPointers((void**) &row1, (void**) &row2);
7598  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7599  tmpilp = ilp1;
7600  tmpinlp = inlp1;
7601  ilp1 = ilp2;
7602  inlp1 = inlp2;
7603  ilp2 = tmpilp;
7604  inlp2 = tmpinlp;
7605  }
7606 
7607  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7608  * -> this merges cases 4a) and 4b)
7609  */
7610  if( ilp1 == row1->nlpcols )
7611  {
7612  i1 = inlp1;
7613  end1 = row1->len;
7614  lpcols = FALSE;
7615  }
7616  else
7617  {
7618  assert(inlp1 == row1->len);
7619 
7620  i1 = ilp1;
7621  end1 = row1->nlpcols;
7622  lpcols = TRUE;
7623  }
7624 
7625  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7626  * case 5) will fail the while-condition
7627  */
7628  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7629  {
7630  assert(row1->cols[i1]->index == row1colsidx[i1]);
7631  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7632  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7633  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7634  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7635 
7636  /* current column in row 1 is the same as the current LP column in row 2 */
7637  if( row1colsidx[i1] == row2colsidx[ilp2] )
7638  {
7639  ++prod;
7640  ++i1;
7641  ++ilp2;
7642  }
7643  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7644  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7645  {
7646  ++prod;
7647  ++i1;
7648  ++inlp2;
7649  }
7650  /* increase smallest counter */
7651  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7652  {
7653  if( row1colsidx[i1] < row2colsidx[ilp2] )
7654  ++i1;
7655  else
7656  ++ilp2;
7657  }
7658  else
7659  {
7660  if( row1colsidx[i1] < row2colsidx[inlp2] )
7661  ++i1;
7662  else
7663  ++inlp2;
7664  }
7665  }
7666 
7667  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7668  * the two rows
7669  */
7670  if( i1 < end1 )
7671  {
7672  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7673  if( ilp2 == row2->nlpcols )
7674  {
7675  i2 = inlp2;
7676  end2 = row2->len;
7677  lpcols = FALSE;
7678  }
7679  else
7680  {
7681  assert(inlp2 == row2->len);
7682 
7683  i2 = ilp2;
7684  end2 = row2->nlpcols;
7685  }
7686 
7687  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7688  while( i1 < end1 && i2 < end2 )
7689  {
7690  assert(row1->cols[i1]->index == row1colsidx[i1]);
7691  assert(row2->cols[i2]->index == row2colsidx[i2]);
7692  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7693 
7694  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7695  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7696  {
7697  ++prod;
7698  ++i1;
7699  ++i2;
7700  }
7701  /* increase smallest counter */
7702  else if( row1colsidx[i1] < row2colsidx[i2] )
7703  ++i1;
7704  else
7705  ++i2;
7706  }
7707  }
7708  }
7709 
7710  return prod;
7711 }
7712 
7713 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7714  * p = |v*w|/(|v|*|w|);
7715  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7716  */
7718  SCIP_ROW* row1, /**< first LP row */
7719  SCIP_ROW* row2, /**< second LP row */
7720  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7721  )
7722 {
7723  SCIP_Real parallelism;
7724  SCIP_Real scalarprod;
7725 
7726  switch( orthofunc )
7727  {
7728  case 'e':
7729  scalarprod = SCIProwGetScalarProduct(row1, row2);
7730  if( scalarprod == 0.0 )
7731  {
7732  parallelism = 0.0;
7733  break;
7734  }
7735 
7736  if( SCIProwGetNorm(row1) == 0.0 )
7737  {
7738  /* In theory, this should not happen if the scalarproduct is not zero
7739  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7740  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7741  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7742  */
7743  int i;
7744  for( i = 0; i < row1->len; ++i )
7745  if( row1->cols[i]->lppos >= 0 )
7746  row1->sqrnorm += SQR(row1->vals[i]);
7747  assert(SCIProwGetNorm(row1) != 0.0);
7748  }
7749 
7750  if( SCIProwGetNorm(row2) == 0.0 )
7751  {
7752  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7753  int i;
7754  for( i = 0; i < row2->len; ++i )
7755  if( row2->cols[i]->lppos >= 0 )
7756  row2->sqrnorm += SQR(row2->vals[i]);
7757  assert(SCIProwGetNorm(row2) != 0.0);
7758  }
7759 
7760  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7761  break;
7762 
7763  case 'd':
7764  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7765  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7766  break;
7767 
7768  default:
7769  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7770  SCIPABORT();
7771  parallelism = 0.0; /*lint !e527*/
7772  }
7773 
7774  return parallelism;
7775 }
7776 
7777 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7778  * o = 1 - |v*w|/(|v|*|w|);
7779  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7780  */
7782  SCIP_ROW* row1, /**< first LP row */
7783  SCIP_ROW* row2, /**< second LP row */
7784  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7785  )
7786 {
7787  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7788 }
7789 
7790 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7791  * function, if the value is 0, it is orthogonal to the objective function
7792  */
7794  SCIP_ROW* row, /**< LP row */
7795  SCIP_SET* set, /**< global SCIP settings */
7796  SCIP_LP* lp /**< current LP data */
7797  )
7798 {
7799  SCIP_Real prod;
7800  SCIP_Real parallelism;
7801 
7802  assert(row != NULL);
7803  assert(lp != NULL);
7804 
7805  if( lp->objsqrnormunreliable )
7806  SCIPlpRecalculateObjSqrNorm(set, lp);
7807 
7808  assert(!lp->objsqrnormunreliable);
7809  assert(lp->objsqrnorm >= 0.0);
7810 
7811  checkRowSqrnorm(row);
7812  checkRowObjprod(row);
7813 
7814  prod = row->sqrnorm * lp->objsqrnorm;
7815 
7816  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7817  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7818  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7819  parallelism = MIN(parallelism, 1.0);
7820  parallelism = MAX(parallelism, 0.0);
7821 
7822  return parallelism;
7823 }
7824 
7825 /** includes event handler with given data in row's event filter */
7827  SCIP_ROW* row, /**< row */
7828  BMS_BLKMEM* blkmem, /**< block memory */
7829  SCIP_SET* set, /**< global SCIP settings */
7830  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7831  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7832  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7833  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7834  )
7835 {
7836  assert(row != NULL);
7837  assert(row->eventfilter != NULL);
7838  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7839  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7840 
7841  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7842  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7843 
7844  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7845 
7846  return SCIP_OKAY;
7847 }
7848 
7849 /** deletes event handler with given data from row's event filter */
7851  SCIP_ROW* row, /**< row */
7852  BMS_BLKMEM* blkmem, /**< block memory */
7853  SCIP_SET* set, /**< global SCIP settings */
7854  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7855  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7856  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7857  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7858  )
7859 {
7860  assert(row != NULL);
7861  assert(row->eventfilter != NULL);
7862 
7863  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7864 
7865  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7866 
7867  return SCIP_OKAY;
7868 }
7869 
7870 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7872  SCIP_ROW* row, /**< LP row */
7873  SCIP_STAT* stat /**< problem statistics */
7874  )
7875 {
7876  assert(row != NULL);
7877  assert(stat != NULL);
7878  assert(stat->nnodes > 0);
7879 
7880  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7881  row->obsoletenode = stat->nnodes;
7882 }
7883 
7884 /*
7885  * LP solver data update
7886  */
7887 
7888 /** resets column data to represent a column not in the LP solver */
7889 static
7891  SCIP_COL* col /**< column to be marked deleted */
7892  )
7893 {
7894  assert(col != NULL);
7895 
7896  col->lpipos = -1;
7897  col->primsol = 0.0;
7898  col->redcost = SCIP_INVALID;
7899  col->farkascoef = SCIP_INVALID;
7900  col->sbdown = SCIP_INVALID;
7901  col->sbup = SCIP_INVALID;
7902  col->sbdownvalid = FALSE;
7903  col->sbupvalid = FALSE;
7904  col->validredcostlp = -1;
7905  col->validfarkaslp = -1;
7906  col->sbitlim = -1;
7907  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7908 }
7909 
7910 /** applies all cached column removals to the LP solver */
7911 static
7913  SCIP_LP* lp /**< current LP data */
7914  )
7915 {
7916  assert(lp != NULL);
7917  assert(lp->lpifirstchgcol <= lp->nlpicols);
7918  assert(lp->lpifirstchgcol <= lp->ncols);
7919 
7920  /* find the first column to change */
7921  while( lp->lpifirstchgcol < lp->nlpicols
7922  && lp->lpifirstchgcol < lp->ncols
7923  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7924  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7925  {
7926  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7927  lp->lpifirstchgcol++;
7928  }
7929 
7930  /* shrink LP to the part which didn't change */
7931  if( lp->lpifirstchgcol < lp->nlpicols )
7932  {
7933  int i;
7934 
7935  assert(!lp->diving);
7936  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7937  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7938  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7939  {
7940  markColDeleted(lp->lpicols[i]);
7941  }
7942  lp->nlpicols = lp->lpifirstchgcol;
7943  lp->flushdeletedcols = TRUE;
7944  lp->updateintegrality = TRUE;
7945 
7946  /* mark the LP unsolved */
7947  lp->solved = FALSE;
7948  lp->primalfeasible = FALSE;
7949  lp->primalchecked = FALSE;
7950  lp->lpobjval = SCIP_INVALID;
7952  }
7953  assert(lp->nlpicols == lp->lpifirstchgcol);
7954 
7955  return SCIP_OKAY;
7956 }
7957 
7958 /** computes for the given column the lower and upper bound that should be flushed into the LP
7959  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7960  * the bounds are explicitly added to the LP in any case
7961  */
7962 static
7964  SCIP_LP* lp, /**< current LP data */
7965  SCIP_SET* set, /**< global SCIP settings */
7966  SCIP_COL* col, /**< column to compute bounds for */
7967  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7968  SCIP_Real* lb, /**< pointer to store the new lower bound */
7969  SCIP_Real* ub /**< pointer to store the new upper bound */
7970  )
7971 {
7972  assert(lp != NULL);
7973  assert(set != NULL);
7974  assert(col != NULL);
7975  assert(lb != NULL);
7976  assert(ub != NULL);
7977 
7978  /* get the correct new lower bound:
7979  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7980  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7981  */
7982  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7983  (*lb) = -lpiinf;
7984  else
7985  (*lb) = col->lb;
7986  /* get the correct new upper bound:
7987  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7988  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7989  */
7990  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7991  (*ub) = lpiinf;
7992  else
7993  (*ub) = col->ub;
7994 }
7995 
7996 /** applies all cached column additions to the LP solver */
7997 static
7999  SCIP_LP* lp, /**< current LP data */
8000  BMS_BLKMEM* blkmem, /**< block memory */
8001  SCIP_SET* set, /**< global SCIP settings */
8002  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8003  )
8004 {
8005  SCIP_Real* obj;
8006  SCIP_Real* lb;
8007  SCIP_Real* ub;
8008  int* beg;
8009  int* ind;
8010  SCIP_Real* val;
8011  char** name;
8012  SCIP_COL* col;
8013  SCIP_Real lpiinf;
8014  int c;
8015  int pos;
8016  int nnonz;
8017  int naddcols;
8018  int naddcoefs;
8019  int i;
8020  int lpipos;
8021 
8022  assert(lp != NULL);
8023  assert(lp->lpifirstchgcol == lp->nlpicols);
8024  assert(blkmem != NULL);
8025  assert(set != NULL);
8026 
8027  /* if there are no columns to add, we are ready */
8028  if( lp->ncols == lp->nlpicols )
8029  return SCIP_OKAY;
8030 
8031  /* add the additional columns */
8032  assert(!lp->diving);
8033  assert(lp->ncols > lp->nlpicols);
8034  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8035 
8036  /* get the solver's infinity value */
8037  lpiinf = SCIPlpiInfinity(lp->lpi);
8038 
8039  /* count the (maximal) number of added coefficients, calculate the number of added columns */
8040  naddcols = lp->ncols - lp->nlpicols;
8041  naddcoefs = 0;
8042  for( c = lp->nlpicols; c < lp->ncols; ++c )
8043  naddcoefs += lp->cols[c]->len;
8044  assert(naddcols > 0);
8045 
8046  /* get temporary memory for changes */
8047  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8048  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8049  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8050  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8051  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8052  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8053  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8054 
8055  /* fill temporary memory with column data */
8056  nnonz = 0;
8057  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8058  {
8059  col = lp->cols[c];
8060  assert(col != NULL);
8061  assert(col->var != NULL);
8062  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8063  assert(SCIPvarGetCol(col->var) == col);
8064  assert(col->lppos == c);
8065  assert(nnonz + col->nlprows <= naddcoefs);
8066 
8067  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8068  debugColPrint(set, col);
8069 
8070  /* Because the column becomes a member of the LP solver, it now can take values
8071  * different from zero. That means, we have to include the column in the corresponding
8072  * row vectors.
8073  */
8074  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8075 
8076  lp->lpicols[c] = col;
8077  col->lpipos = c;
8078  col->primsol = SCIP_INVALID;
8079  col->redcost = SCIP_INVALID;
8080  col->farkascoef = SCIP_INVALID;
8081  col->sbdown = SCIP_INVALID;
8082  col->sbup = SCIP_INVALID;
8083  col->sbdownvalid = FALSE;
8084  col->sbupvalid = FALSE;
8085  col->validredcostlp = -1;
8086  col->validfarkaslp = -1;
8087  col->sbitlim = -1;
8088  col->objchanged = FALSE;
8089  col->lbchanged = FALSE;
8090  col->ubchanged = FALSE;
8091  col->coefchanged = FALSE;
8092  obj[pos] = col->obj;
8093 
8094  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8095  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8096 
8097  beg[pos] = nnonz;
8098  name[pos] = (char*)SCIPvarGetName(col->var);
8099 
8100  col->flushedobj = obj[pos];
8101  col->flushedlb = lb[pos];
8102  col->flushedub = ub[pos];
8103 
8104  for( i = 0; i < col->nlprows; ++i )
8105  {
8106  assert(col->rows[i] != NULL);
8107  lpipos = col->rows[i]->lpipos;
8108  if( lpipos >= 0 )
8109  {
8110  assert(lpipos < lp->nrows);
8111  assert(nnonz < naddcoefs);
8112  ind[nnonz] = lpipos;
8113  val[nnonz] = col->vals[i];
8114  nnonz++;
8115  }
8116  }
8117 #ifndef NDEBUG
8118  for( i = col->nlprows; i < col->len; ++i )
8119  {
8120  assert(col->rows[i] != NULL);
8121  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8122  }
8123 #endif
8124  }
8125 
8126  /* call LP interface */
8127  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8128  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8129  lp->nlpicols = lp->ncols;
8130  lp->lpifirstchgcol = lp->nlpicols;
8131 
8132  /* free temporary memory */
8133  SCIPsetFreeBufferArray(set, &name);
8134  SCIPsetFreeBufferArray(set, &val);
8135  SCIPsetFreeBufferArray(set, &ind);
8136  SCIPsetFreeBufferArray(set, &beg);
8137  SCIPsetFreeBufferArray(set, &ub);
8138  SCIPsetFreeBufferArray(set, &lb);
8139  SCIPsetFreeBufferArray(set, &obj);
8140 
8141  lp->flushaddedcols = TRUE;
8142  lp->updateintegrality = TRUE;
8143 
8144  /* mark the LP unsolved */
8145  lp->solved = FALSE;
8146  lp->dualfeasible = FALSE;
8147  lp->dualchecked = FALSE;
8148  lp->lpobjval = SCIP_INVALID;
8150 
8151  return SCIP_OKAY;
8152 }
8153 
8154 /** resets row data to represent a row not in the LP solver */
8155 static
8157  SCIP_ROW* row /**< row to be marked deleted */
8158  )
8159 {
8160  assert(row != NULL);
8161 
8162  row->lpipos = -1;
8163  row->dualsol = 0.0;
8164  row->activity = SCIP_INVALID;
8165  row->dualfarkas = 0.0;
8166  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8167  row->validactivitylp = -1;
8168 }
8169 
8170 /** applies all cached row removals to the LP solver */
8171 static
8173  SCIP_LP* lp, /**< current LP data */
8174  BMS_BLKMEM* blkmem, /**< block memory */
8175  SCIP_SET* set /**< global SCIP settings */
8176  )
8177 {
8178  assert(lp != NULL);
8179  assert(lp->lpifirstchgrow <= lp->nlpirows);
8180  assert(lp->lpifirstchgrow <= lp->nrows);
8181 
8182  /* find the first row to change */
8183  while( lp->lpifirstchgrow < lp->nlpirows
8184  && lp->lpifirstchgrow < lp->nrows
8185  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8186  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8187  {
8188  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8189  lp->lpifirstchgrow++;
8190  }
8191 
8192  /* shrink LP to the part which didn't change */
8193  if( lp->lpifirstchgrow < lp->nlpirows )
8194  {
8195  int i;
8196 
8197  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8198  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8199  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8200  {
8201  markRowDeleted(lp->lpirows[i]);
8202  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8203  }
8204  lp->nlpirows = lp->lpifirstchgrow;
8205  lp->flushdeletedrows = TRUE;
8206 
8207  /* mark the LP unsolved */
8208  lp->solved = FALSE;
8209  lp->dualfeasible = FALSE;
8210  lp->dualchecked = FALSE;
8211  lp->lpobjval = SCIP_INVALID;
8213  }
8214  assert(lp->nlpirows == lp->lpifirstchgrow);
8215 
8216  return SCIP_OKAY;
8217 }
8218 
8219 /** applies all cached row additions and removals to the LP solver */
8220 static
8222  SCIP_LP* lp, /**< current LP data */
8223  BMS_BLKMEM* blkmem, /**< block memory */
8224  SCIP_SET* set, /**< global SCIP settings */
8225  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8226  )
8227 {
8228  SCIP_Real* lhs;
8229  SCIP_Real* rhs;
8230  int* beg;
8231  int* ind;
8232  SCIP_Real* val;
8233  char** name;
8234  SCIP_ROW* row;
8235  SCIP_Real lpiinf;
8236  int r;
8237  int pos;
8238  int nnonz;
8239  int naddrows;
8240  int naddcoefs;
8241  int i;
8242  int lpipos;
8243 
8244  assert(lp != NULL);
8245  assert(lp->lpifirstchgrow == lp->nlpirows);
8246  assert(blkmem != NULL);
8247 
8248  /* if there are no rows to add, we are ready */
8249  if( lp->nrows == lp->nlpirows )
8250  return SCIP_OKAY;
8251 
8252  /* add the additional rows */
8253  assert(lp->nrows > lp->nlpirows);
8254  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8255 
8256  /* get the solver's infinity value */
8257  lpiinf = SCIPlpiInfinity(lp->lpi);
8258 
8259  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8260  naddrows = lp->nrows - lp->nlpirows;
8261  naddcoefs = 0;
8262  for( r = lp->nlpirows; r < lp->nrows; ++r )
8263  naddcoefs += lp->rows[r]->len;
8264  assert(naddrows > 0);
8265 
8266  /* get temporary memory for changes */
8267  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8268  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8269  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8270  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8271  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8272  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8273 
8274  /* fill temporary memory with row data */
8275  nnonz = 0;
8276  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8277  {
8278  row = lp->rows[r];
8279  assert(row != NULL);
8280  assert(row->lppos == r);
8281  assert(nnonz + row->nlpcols <= naddcoefs);
8282 
8283  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8284  debugRowPrint(set, row);
8285 
8286  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8287  * different from zero. That means, we have to include the row in the corresponding
8288  * column vectors.
8289  */
8290  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8291 
8292  SCIProwCapture(row);
8293  lp->lpirows[r] = row;
8294  row->lpipos = r;
8295  row->dualsol = SCIP_INVALID;
8296  row->activity = SCIP_INVALID;
8297  row->dualfarkas = SCIP_INVALID;
8298  row->validactivitylp = -1;
8299  row->lhschanged = FALSE;
8300  row->rhschanged = FALSE;
8301  row->coefchanged = FALSE;
8302  if( SCIPsetIsInfinity(set, -row->lhs) )
8303  lhs[pos] = -lpiinf;
8304  else
8305  lhs[pos] = row->lhs - row->constant;
8306  if( SCIPsetIsInfinity(set, row->rhs) )
8307  rhs[pos] = lpiinf;
8308  else
8309  rhs[pos] = row->rhs - row->constant;
8310  beg[pos] = nnonz;
8311  name[pos] = row->name;
8312 
8313  row->flushedlhs = lhs[pos];
8314  row->flushedrhs = rhs[pos];
8315 
8316  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8317  for( i = 0; i < row->nlpcols; ++i )
8318  {
8319  assert(row->cols[i] != NULL);
8320  lpipos = row->cols[i]->lpipos;
8321  if( lpipos >= 0 )
8322  {
8323  assert(lpipos < lp->ncols);
8324  assert(nnonz < naddcoefs);
8325  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8326  ind[nnonz] = lpipos;
8327  val[nnonz] = row->vals[i];
8328  nnonz++;
8329  }
8330  }
8331  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8332 #ifndef NDEBUG
8333  for( i = row->nlpcols; i < row->len; ++i )
8334  {
8335  assert(row->cols[i] != NULL);
8336  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8337  }
8338 #endif
8339  }
8340 
8341  /* call LP interface */
8342  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8343  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8344  lp->nlpirows = lp->nrows;
8345  lp->lpifirstchgrow = lp->nlpirows;
8346 
8347  /* free temporary memory */
8348  SCIPsetFreeBufferArray(set, &name);
8349  SCIPsetFreeBufferArray(set, &val);
8350  SCIPsetFreeBufferArray(set, &ind);
8351  SCIPsetFreeBufferArray(set, &beg);
8352  SCIPsetFreeBufferArray(set, &rhs);
8353  SCIPsetFreeBufferArray(set, &lhs);
8354 
8355  lp->flushaddedrows = TRUE;
8356 
8357  /* mark the LP unsolved */
8358  lp->solved = FALSE;
8359  lp->primalfeasible = FALSE;
8360  lp->primalchecked = FALSE;
8361  lp->lpobjval = SCIP_INVALID;
8363 
8364  return SCIP_OKAY;
8365 }
8366 
8367 /** applies all cached column bound and objective changes to the LP */
8368 static
8370  SCIP_LP* lp, /**< current LP data */
8371  SCIP_SET* set /**< global SCIP settings */
8372  )
8373 {
8374 #ifndef NDEBUG
8375  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8376 #endif
8377  SCIP_COL* col;
8378  int* objind;
8379  int* bdind;
8380  SCIP_Real* obj;
8381  SCIP_Real* lb;
8382  SCIP_Real* ub;
8383  SCIP_Real lpiinf;
8384  int nobjchg;
8385  int nbdchg;
8386  int i;
8387 
8388  assert(lp != NULL);
8389 
8390  if( lp->nchgcols == 0 )
8391  return SCIP_OKAY;
8392 
8393  /* get the solver's infinity value */
8394  lpiinf = SCIPlpiInfinity(lp->lpi);
8395 
8396  /* get temporary memory for changes */
8397  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8398  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8399  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8400  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8401  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8402 
8403  /* collect all cached bound and objective changes */
8404  nobjchg = 0;
8405  nbdchg = 0;
8406  for( i = 0; i < lp->nchgcols; ++i )
8407  {
8408  col = lp->chgcols[i];
8409  assert(col != NULL);
8410  assert(col->var != NULL);
8411  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8412  assert(SCIPvarGetCol(col->var) == col);
8413 
8414  if( col->lpipos >= 0 )
8415  {
8416 #ifndef NDEBUG
8417  /* do not check consistency of data with LPI in case of LPI=none */
8418  if( !lpinone )
8419  {
8420  SCIP_Real lpiobj;
8421  SCIP_Real lpilb;
8422  SCIP_Real lpiub;
8423 
8424  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8425  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8426  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8427  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8428  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8429  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8430  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8431  }
8432 #endif
8433 
8434  if( col->objchanged )
8435  {
8436  SCIP_Real newobj;
8437 
8438  newobj = col->obj;
8439  if( col->flushedobj != newobj ) /*lint !e777*/
8440  {
8441  assert(nobjchg < lp->ncols);
8442  objind[nobjchg] = col->lpipos;
8443  obj[nobjchg] = newobj;
8444  nobjchg++;
8445  col->flushedobj = newobj;
8446  }
8447  col->objchanged = FALSE;
8448  }
8449 
8450  if( col->lbchanged || col->ubchanged )
8451  {
8452  SCIP_Real newlb;
8453  SCIP_Real newub;
8454 
8455  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8456  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8457 
8458  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8459  {
8460  assert(nbdchg < lp->ncols);
8461  bdind[nbdchg] = col->lpipos;
8462  lb[nbdchg] = newlb;
8463  ub[nbdchg] = newub;
8464  nbdchg++;
8465  col->flushedlb = newlb;
8466  col->flushedub = newub;
8467  }
8468  col->lbchanged = FALSE;
8469  col->ubchanged = FALSE;
8470  }
8471  }
8472  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8473  }
8474 
8475  /* change objective values in LP */
8476  if( nobjchg > 0 )
8477  {
8478  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8479  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8480 
8481  /* mark the LP unsolved */
8482  lp->solved = FALSE;
8483  lp->dualfeasible = FALSE;
8484  lp->dualchecked = FALSE;
8485  lp->lpobjval = SCIP_INVALID;
8487  }
8488 
8489  /* change bounds in LP */
8490  if( nbdchg > 0 )
8491  {
8492  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8493  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8494 
8495  /* mark the LP unsolved */
8496  lp->solved = FALSE;
8497  lp->primalfeasible = FALSE;
8498  lp->primalchecked = FALSE;
8499  lp->lpobjval = SCIP_INVALID;
8501  }
8502 
8503  lp->nchgcols = 0;
8504 
8505  /* free temporary memory */
8506  SCIPsetFreeBufferArray(set, &ub);
8507  SCIPsetFreeBufferArray(set, &lb);
8508  SCIPsetFreeBufferArray(set, &bdind);
8509  SCIPsetFreeBufferArray(set, &obj);
8510  SCIPsetFreeBufferArray(set, &objind);
8511 
8512  return SCIP_OKAY;
8513 }
8514 
8515 /** applies all cached row side changes to the LP */
8516 static
8518  SCIP_LP* lp, /**< current LP data */
8519  SCIP_SET* set /**< global SCIP settings */
8520  )
8521 {
8522 #ifndef NDEBUG
8523  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8524 #endif
8525  SCIP_ROW* row;
8526  int* ind;
8527  SCIP_Real* lhs;
8528  SCIP_Real* rhs;
8529  SCIP_Real lpiinf;
8530  int i;
8531  int nchg;
8532 
8533  assert(lp != NULL);
8534 
8535  if( lp->nchgrows == 0 )
8536  return SCIP_OKAY;
8537 
8538  /* get the solver's infinity value */
8539  lpiinf = SCIPlpiInfinity(lp->lpi);
8540 
8541  /* get temporary memory for changes */
8542  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8543  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8544  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8545 
8546  /* collect all cached left and right hand side changes */
8547  nchg = 0;
8548  for( i = 0; i < lp->nchgrows; ++i )
8549  {
8550  row = lp->chgrows[i];
8551  assert(row != NULL);
8552 
8553  if( row->lpipos >= 0 )
8554  {
8555 #ifndef NDEBUG
8556  /* do not check consistency of data with LPI in case of LPI=none */
8557  if( !lpinone )
8558  {
8559  SCIP_Real lpilhs;
8560  SCIP_Real lpirhs;
8561 
8562  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8563  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8564  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8565  }
8566 #endif
8567  if( row->lhschanged || row->rhschanged )
8568  {
8569  SCIP_Real newlhs;
8570  SCIP_Real newrhs;
8571 
8572  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8573  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8574  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8575  {
8576  assert(nchg < lp->nrows);
8577  ind[nchg] = row->lpipos;
8578  lhs[nchg] = newlhs;
8579  rhs[nchg] = newrhs;
8580  nchg++;
8581  row->flushedlhs = newlhs;
8582  row->flushedrhs = newrhs;
8583  }
8584  row->lhschanged = FALSE;
8585  row->rhschanged = FALSE;
8586  }
8587  }
8588  }
8589 
8590  /* change left and right hand sides in LP */
8591  if( nchg > 0 )
8592  {
8593  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8594  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8595 
8596  /* mark the LP unsolved */
8597  lp->solved = FALSE;
8598  lp->primalfeasible = FALSE;
8599  lp->primalchecked = FALSE;
8600  lp->lpobjval = SCIP_INVALID;
8602  }
8603 
8604  lp->nchgrows = 0;
8605 
8606  /* free temporary memory */
8607  SCIPsetFreeBufferArray(set, &rhs);
8608  SCIPsetFreeBufferArray(set, &lhs);
8609  SCIPsetFreeBufferArray(set, &ind);
8610 
8611  return SCIP_OKAY;
8612 }
8613 
8614 /** copy integrality information to the LP */
8615 static
8617  SCIP_LP* lp, /**< current LP data */
8618  SCIP_SET* set /**< global SCIP settings */
8619  )
8620 {
8621  int i;
8622  int nintegers;
8623  int* integerInfo;
8624  SCIP_VAR* var;
8625 
8626  assert(lp != NULL);
8627 
8628  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8629 
8630  /* count total number of integralities */
8631  nintegers = 0;
8632 
8633  for( i = 0; i < lp->ncols; ++i )
8634  {
8635  var = SCIPcolGetVar(lp->cols[i]);
8636  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8637  {
8638  integerInfo[i] = 1;
8639  ++nintegers;
8640  }
8641  else
8642  integerInfo[i] = 0;
8643  }
8644 
8645  /* only pass integrality information if integer variables are present */
8646  if( nintegers > 0 )
8647  {
8648  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8649  }
8650  else
8651  {
8653  }
8654 
8655  SCIPsetFreeBufferArray(set, &integerInfo);
8656 
8657  /* mark integralities to be updated */
8658  lp->updateintegrality = FALSE;
8659 
8660  return SCIP_OKAY;
8661 }
8662 
8663 /** applies all cached changes to the LP solver */
8665  SCIP_LP* lp, /**< current LP data */
8666  BMS_BLKMEM* blkmem, /**< block memory */
8667  SCIP_SET* set, /**< global SCIP settings */
8668  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8669  )
8670 {
8671  assert(lp != NULL);
8672  assert(blkmem != NULL);
8673 
8674  SCIPsetDebugMsg(set, "flushing LP changes: old (%d cols, %d rows), nchgcols=%d, nchgrows=%d, firstchgcol=%d, firstchgrow=%d, new (%d cols, %d rows), flushed=%u\n",
8675  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8676 
8677  if( !lp->flushed )
8678  {
8679  lp->flushdeletedcols = FALSE;
8680  lp->flushaddedcols = FALSE;
8681  lp->flushdeletedrows = FALSE;
8682  lp->flushaddedrows = FALSE;
8683 
8684  SCIP_CALL( lpFlushDelCols(lp) );
8685  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8686  SCIP_CALL( lpFlushChgCols(lp, set) );
8687  SCIP_CALL( lpFlushChgRows(lp, set) );
8688  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8689  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8690 
8691  lp->flushed = TRUE;
8692 
8693  checkLinks(lp);
8694  }
8695 
8696  /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8697  * we want to re-optimize the LP even if nothing else has changed */
8698  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 && ! lpCutoffDisabled(set) ) /*lint !e777*/
8699  {
8700  lp->solved = FALSE;
8702  }
8703 
8704  assert(lp->nlpicols == lp->ncols);
8705  assert(lp->lpifirstchgcol == lp->nlpicols);
8706  assert(lp->nlpirows == lp->nrows);
8707  assert(lp->lpifirstchgrow == lp->nlpirows);
8708  assert(lp->nchgcols == 0);
8709  assert(lp->nchgrows == 0);
8710 #ifndef NDEBUG
8711  {
8712  int ncols;
8713  int nrows;
8714 
8715  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8716  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8717  assert(ncols == lp->ncols);
8718  assert(nrows == lp->nrows);
8719  }
8720 #endif
8721 
8722  return SCIP_OKAY;
8723 }
8724 
8725 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8727  SCIP_LP* lp, /**< current LP data */
8728  SCIP_SET* set /**< global SCIP settings */
8729  )
8730 {
8731 #ifndef NDEBUG
8732  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8733 #endif
8734  int i;
8735 
8736  assert(lp != NULL);
8737 
8738 #ifndef NDEBUG
8739  /* check, if there are really no column or row deletions or coefficient changes left */
8740  while( lp->lpifirstchgcol < lp->nlpicols
8741  && lp->lpifirstchgcol < lp->ncols
8742  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8743  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8744  {
8745  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8746  lp->lpifirstchgcol++;
8747  }
8748  assert(lp->nlpicols == lp->lpifirstchgcol);
8749 
8750  while( lp->lpifirstchgrow < lp->nlpirows
8751  && lp->lpifirstchgrow < lp->nrows
8752  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8753  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8754  {
8755  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8756  lp->lpifirstchgrow++;
8757  }
8758  assert(lp->nlpirows == lp->lpifirstchgrow);
8759 #endif
8760 
8761  lp->lpifirstchgcol = lp->nlpicols;
8762  lp->lpifirstchgrow = lp->nlpirows;
8763 
8764  /* check, if there are really no column or row additions left */
8765  assert(lp->ncols == lp->nlpicols);
8766  assert(lp->nrows == lp->nlpirows);
8767 
8768  /* mark the changed columns to be unchanged, and check, if this is really correct */
8769  for( i = 0; i < lp->nchgcols; ++i )
8770  {
8771  SCIP_COL* col;
8772 
8773  col = lp->chgcols[i];
8774  assert(col != NULL);
8775  assert(col->var != NULL);
8776  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8777  assert(SCIPvarGetCol(col->var) == col);
8778 
8779  if( col->lpipos >= 0 )
8780  {
8781 #ifndef NDEBUG
8782  /* do not check consistency of data with LPI in case of LPI=none */
8783  if( !lpinone )
8784  {
8785  SCIP_Real lpiobj;
8786  SCIP_Real lpilb;
8787  SCIP_Real lpiub;
8788 
8789  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8790  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8791  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8792  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8793  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8794  assert(col->flushedobj == col->obj); /*lint !e777*/
8795  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8796  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8797  }
8798 #endif
8799  col->objchanged = FALSE;
8800  col->lbchanged = FALSE;
8801  col->ubchanged = FALSE;
8802  }
8803  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8804  }
8805  lp->nchgcols = 0;
8806 
8807  /* mark the changed rows to be unchanged, and check, if this is really correct */
8808  for( i = 0; i < lp->nchgrows; ++i )
8809  {
8810  SCIP_ROW* row;
8811 
8812  row = lp->chgrows[i];
8813  assert(row != NULL);
8814 
8815  if( row->lpipos >= 0 )
8816  {
8817 #ifndef NDEBUG
8818  /* do not check consistency of data with LPI in case of LPI=none */
8819  if( !lpinone )
8820  {
8821  SCIP_Real lpilhs;
8822  SCIP_Real lpirhs;
8823 
8824  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8825  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8826  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8827  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8828  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8829  }
8830 #endif
8831  row->lhschanged = FALSE;
8832  row->rhschanged = FALSE;
8833  }
8834  }
8835  lp->nchgrows = 0;
8836 
8837  /* mark the LP to be flushed */
8838  lp->flushed = TRUE;
8839 
8840  checkLinks(lp);
8841 
8842  return SCIP_OKAY;
8843 }
8844 
8845 
8846 
8847 
8848 /*
8849  * LP methods
8850  */
8851 
8852 /** updates link data after addition of column */
8853 static
8855  SCIP_COL* col, /**< LP column */
8856  SCIP_SET* set /**< global SCIP settings */
8857  )
8858 {
8859  SCIP_ROW* row;
8860  int i;
8861  int pos;
8862 
8863  assert(col != NULL);
8864  assert(col->lppos >= 0);
8865 
8866  /* update column arrays of all linked rows */
8867  for( i = 0; i < col->len; ++i )
8868  {
8869  pos = col->linkpos[i];
8870  if( pos >= 0 )
8871  {
8872  row = col->rows[i];
8873  assert(row != NULL);
8874  assert(row->linkpos[pos] == i);
8875  assert(row->cols[pos] == col);
8876  assert(row->nlpcols <= pos && pos < row->len);
8877 
8878  row->nlpcols++;
8879  rowSwapCoefs(row, pos, row->nlpcols-1);
8880  assert(row->cols[row->nlpcols-1] == col);
8881 
8882  /* if no swap was necessary, mark lpcols to be unsorted */
8883  if( pos == row->nlpcols-1 )
8884  row->lpcolssorted = FALSE;
8885 
8886  /* update norms */
8887  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8888  }
8889  }
8890 }
8891 
8892 /** updates link data after addition of row */
8893 static
8895  SCIP_ROW* row /**< LP row */
8896  )
8897 {
8898  SCIP_COL* col;
8899  int i;
8900  int pos;
8901 
8902  assert(row != NULL);
8903  assert(row->lppos >= 0);
8904 
8905  /* update row arrays of all linked columns */
8906  for( i = 0; i < row->len; ++i )
8907  {
8908  pos = row->linkpos[i];
8909  if( pos >= 0 )
8910  {
8911  col = row->cols[i];
8912  assert(col != NULL);
8913  assert(col->linkpos[pos] == i);
8914  assert(col->rows[pos] == row);
8915  assert(col->nlprows <= pos && pos < col->len);
8916 
8917  col->nlprows++;
8918  colSwapCoefs(col, pos, col->nlprows-1);
8919 
8920  /* if no swap was necessary, mark lprows to be unsorted */
8921  if( pos == col->nlprows-1 )
8922  col->lprowssorted = FALSE;
8923  }
8924  }
8925 }
8926 
8927 /** updates link data after removal of column */
8928 static
8930  SCIP_COL* col, /**< LP column */
8931  SCIP_SET* set /**< global SCIP settings */
8932  )
8933 {
8934  SCIP_ROW* row;
8935  int i;
8936  int pos;
8937 
8938  assert(col != NULL);
8939  assert(col->lppos == -1);
8940 
8941  /* update column arrays of all linked rows */
8942  for( i = 0; i < col->len; ++i )
8943  {
8944  pos = col->linkpos[i];
8945  if( pos >= 0 )
8946  {
8947  row = col->rows[i];
8948  assert(row != NULL);
8949  assert(row->linkpos[pos] == i);
8950  assert(row->cols[pos] == col);
8951  assert(0 <= pos && pos < row->nlpcols);
8952 
8953  /* update norms */
8954  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8955 
8956  row->nlpcols--;
8957  rowSwapCoefs(row, pos, row->nlpcols);
8958 
8959  /* if no swap was necessary, mark nonlpcols to be unsorted */
8960  if( pos == row->nlpcols )
8961  row->nonlpcolssorted = FALSE;
8962  }
8963  }
8964 }
8965 
8966 /** updates link data after removal of row */
8967 static
8969  SCIP_ROW* row /**< LP row */
8970  )
8971 {
8972  SCIP_COL* col;
8973  int i;
8974  int pos;
8975 
8976  assert(row != NULL);
8977  assert(row->lppos == -1);
8978 
8979  /* update row arrays of all linked columns */
8980  for( i = 0; i < row->len; ++i )
8981  {
8982  pos = row->linkpos[i];
8983  if( pos >= 0 )
8984  {
8985  col = row->cols[i];
8986  assert(col != NULL);
8987  assert(0 <= pos && pos < col->nlprows);
8988  assert(col->linkpos[pos] == i);
8989  assert(col->rows[pos] == row);
8990 
8991  col->nlprows--;
8992  colSwapCoefs(col, pos, col->nlprows);
8993 
8994  /* if no swap was necessary, mark lprows to be unsorted */
8995  if( pos == col->nlprows )
8996  col->nonlprowssorted = FALSE;
8997  }
8998  }
8999 }
9000 
9001 static
9003  SCIP_LP* lp, /**< LP data object */
9004  int initsize /**< initial size of the arrays */
9005  )
9006 {
9007  assert(lp != NULL);
9008  assert(lp->divechgsides == NULL);
9009  assert(lp->divechgsidetypes == NULL);
9010  assert(lp->divechgrows == NULL);
9011  assert(lp->ndivechgsides == 0);
9012  assert(lp->divechgsidessize == 0);
9013  assert(initsize > 0);
9014 
9015  lp->divechgsidessize = initsize;
9019 
9020  return SCIP_OKAY;
9021 }
9022 
9023 static
9025  SCIP_LP* lp, /**< LP data object */
9026  int minsize, /**< minimal number of elements */
9027  SCIP_Real growfact /**< growing factor */
9028  )
9029 {
9030  assert(lp != NULL);
9031  assert(lp->divechgsides != NULL);
9032  assert(lp->divechgsidetypes != NULL);
9033  assert(lp->divechgrows != NULL);
9034  assert(lp->ndivechgsides > 0);
9035  assert(lp->divechgsidessize > 0);
9036  assert(minsize > 0);
9037 
9038  if( minsize <= lp->divechgsidessize )
9039  return SCIP_OKAY;
9040 
9041  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9045 
9046  return SCIP_OKAY;
9047 }
9048 
9049 static
9051  SCIP_LP* lp /**< LP data object */
9052  )
9053 {
9054  assert(lp != NULL);
9055  assert(lp->divechgsides != NULL);
9056  assert(lp->divechgsidetypes != NULL);
9057  assert(lp->divechgrows != NULL);
9058  assert(lp->ndivechgsides == 0);
9059  assert(lp->divechgsidessize > 0);
9060 
9064  lp->divechgsidessize = 0;
9065 }
9066 
9067 #define DIVESTACKINITSIZE 100
9068 
9069 /** creates empty LP data object */
9071  SCIP_LP** lp, /**< pointer to LP data object */
9072  SCIP_SET* set, /**< global SCIP settings */
9073  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9074  SCIP_STAT* stat, /**< problem statistics */
9075  const char* name /**< problem name */
9076  )
9077 {
9078  SCIP_Bool success;
9079 
9080  assert(lp != NULL);
9081  assert(set != NULL);
9082  assert(stat != NULL);
9083  assert(name != NULL);
9084 
9085  SCIP_ALLOC( BMSallocMemory(lp) );
9086 
9087  /* open LP Solver interface */
9088  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9089 
9090  (*lp)->lpicols = NULL;
9091  (*lp)->lpirows = NULL;
9092  (*lp)->chgcols = NULL;
9093  (*lp)->chgrows = NULL;
9094  (*lp)->cols = NULL;
9095  (*lp)->soldirection = NULL;
9096  (*lp)->lazycols = NULL;
9097  (*lp)->rows = NULL;
9098  (*lp)->lpobjval = 0.0;
9099  (*lp)->glbpseudoobjval = 0.0;
9100  (*lp)->relglbpseudoobjval = 0.0;
9101  (*lp)->glbpseudoobjvalid = TRUE;
9102  (*lp)->glbpseudoobjvalinf = 0;
9103  (*lp)->pseudoobjval = 0.0;
9104  (*lp)->relpseudoobjval = 0.0;
9105  (*lp)->pseudoobjvalid = TRUE;
9106  (*lp)->pseudoobjvalinf = 0;
9107  (*lp)->looseobjval = 0.0;
9108  (*lp)->rellooseobjval = 0.0;
9109  (*lp)->looseobjvalid = TRUE;
9110  (*lp)->looseobjvalinf = 0;
9111  (*lp)->nloosevars = 0;
9112  (*lp)->rootlpobjval = SCIP_INVALID;
9113  (*lp)->rootlooseobjval = SCIP_INVALID;
9114  (*lp)->cutoffbound = SCIPsetInfinity(set);
9115  (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9116  SCIPlpResetFeastol(*lp, set);
9117  (*lp)->validdegeneracylp = -1;
9118  (*lp)->objsqrnorm = 0.0;
9119  (*lp)->objsumnorm = 0.0;
9120  (*lp)->lpicolssize = 0;
9121  (*lp)->nlpicols = 0;
9122  (*lp)->lpirowssize = 0;
9123  (*lp)->nlpirows = 0;
9124  (*lp)->lpifirstchgcol = 0;
9125  (*lp)->lpifirstchgrow = 0;
9126  (*lp)->colssize = 0;
9127  (*lp)->soldirectionsize = 0;
9128  (*lp)->ncols = 0;
9129  (*lp)->lazycolssize = 0;
9130  (*lp)->nlazycols = 0;
9131  (*lp)->rowssize = 0;
9132  (*lp)->nrows = 0;
9133  (*lp)->chgcolssize = 0;
9134  (*lp)->nchgcols = 0;
9135  (*lp)->chgrowssize = 0;
9136  (*lp)->nchgrows = 0;
9137  (*lp)->firstnewcol = 0;
9138  (*lp)->firstnewrow = 0;
9139  (*lp)->nremovablecols = 0;
9140  (*lp)->nremovablerows = 0;
9141  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9142  (*lp)->validfarkaslp = -1;
9143  (*lp)->validsoldirlp = -1;
9144  (*lp)->validsoldirsol = NULL;
9145  (*lp)->objsqrnormunreliable = FALSE;
9146  (*lp)->flushdeletedcols = FALSE;
9147  (*lp)->flushaddedcols = FALSE;
9148  (*lp)->flushdeletedrows = FALSE;
9149  (*lp)->flushaddedrows = FALSE;
9150  (*lp)->updateintegrality = TRUE;
9151  (*lp)->flushed = TRUE;
9152  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9153  (*lp)->solved = TRUE;
9154  (*lp)->primalfeasible = TRUE;
9155  (*lp)->primalchecked = TRUE;
9156  (*lp)->dualfeasible = TRUE;
9157  (*lp)->dualchecked = TRUE;
9158  (*lp)->solisbasic = FALSE;
9159  (*lp)->rootlpisrelax = TRUE;
9160  (*lp)->isrelax = TRUE;
9161  (*lp)->installing = FALSE;
9162  (*lp)->strongbranching = FALSE;
9163  (*lp)->strongbranchprobing = FALSE;
9164  (*lp)->probing = FALSE;
9165  (*lp)->diving = FALSE;
9166  (*lp)->divingobjchg = FALSE;
9167  (*lp)->divinglazyapplied = FALSE;
9168  (*lp)->divelpistate = NULL;
9169  (*lp)->divelpwasprimfeas = TRUE;
9170  (*lp)->divelpwasprimchecked = TRUE;
9171  (*lp)->divelpwasdualfeas = TRUE;
9172  (*lp)->divelpwasdualchecked = TRUE;
9173  (*lp)->divechgsides = NULL;
9174  (*lp)->divechgsidetypes = NULL;
9175  (*lp)->divechgrows = NULL;
9176  (*lp)->ndivechgsides = 0;
9177  (*lp)->divechgsidessize = 0;
9178  (*lp)->ndivingrows = 0;
9179  (*lp)->divinglpiitlim = INT_MAX;
9180  (*lp)->resolvelperror = FALSE;
9181  (*lp)->divenolddomchgs = 0;
9182  (*lp)->adjustlpval = FALSE;
9183  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9184  (*lp)->lpifeastol = (*lp)->feastol;
9185  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9186  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9187  (*lp)->lpifromscratch = FALSE;
9188  (*lp)->lpifastmip = set->lp_fastmip;
9189  (*lp)->lpiscaling = set->lp_scaling;
9190  (*lp)->lpipresolving = set->lp_presolving;
9191  (*lp)->lpilpinfo = set->disp_lpinfo;
9192  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9193  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9194  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9195  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9196  (*lp)->lpimarkowitz = set->lp_markowitz;
9197  (*lp)->lpiitlim = INT_MAX;
9198  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9199  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9200  (*lp)->lpithreads = set->lp_threads;
9201  (*lp)->lpitiming = (int) set->time_clocktype;
9202  (*lp)->lpirandomseed = set->random_randomseed;
9203  (*lp)->storedsolvals = NULL;
9204 
9205  /* allocate arrays for diving */
9207 
9208  /* set default parameters in LP solver */
9209  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9210  if( !success )
9211  {
9212  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9213  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9215  }
9216  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9217  (*lp)->lpihasfeastol = success;
9218  if( !success )
9219  {
9220  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9221  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9223  }
9224  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9225  (*lp)->lpihasdualfeastol = success;
9226  if( !success )
9227  {
9228  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9229  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9231  }
9232  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9233  (*lp)->lpihasbarrierconvtol = success;
9234  if( !success )
9235  {
9236  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9237  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9239  }
9240  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9241  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9242  (*lp)->lpihasfastmip = success;
9243  if( !success )
9244  {
9245  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9246  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9248  }
9249  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9250  (*lp)->lpihasscaling = success;
9251  if( !success )
9252  {
9253  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9254  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9256  }
9257  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9258  (*lp)->lpihaspresolving = success;
9259  if( !success )
9260  {
9261  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9262  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9264  }
9265  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9266  if( !success )
9267  {
9268  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9269  "LP Solver <%s>: clock type cannot be set\n",
9271  }
9272  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9273  if( !success )
9274  {
9275  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9276  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9278  }
9279  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9280  if( !success )
9281  {
9282  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9283  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9285  }
9286  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9287  if( !success )
9288  {
9289  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9290  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9292  }
9293  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9294  (*lp)->lpihasrowrep = success;
9295  if( !success )
9296  {
9297  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9298  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9300  }
9301  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9302  (*lp)->lpihaspolishing = success;
9303  if( !success )
9304  {
9305  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9306  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9308  }
9309  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9310  (*lp)->lpihasrefactor = success;
9311  if( !success )
9312  {
9313  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9314  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9316  }
9317  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9318  if( !success )
9319  {
9320  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9321  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9323  }
9324  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9325  if( !success )
9326  {
9327  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9328  "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9330  }
9331  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9332  if( !success )
9333  {
9334  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9335  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9337  }
9338  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9339  if( (*lp)->lpirandomseed != 0 )
9340  {
9341  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9342  if( !success )
9343  {
9344  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9345  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9347  }
9348  }
9349 
9350  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9351  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9352  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9353  {
9354  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9355  return SCIP_PARAMETERWRONGVAL;
9356  }
9357 
9358  return SCIP_OKAY;
9359 }
9360 
9361 /** frees LP data object */
9363  SCIP_LP** lp, /**< pointer to LP data object */
9364  BMS_BLKMEM* blkmem, /**< block memory */
9365  SCIP_SET* set, /**< global SCIP settings */
9366  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9367  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9368  )
9369 {
9370  int i;
9371 
9372  assert(lp != NULL);
9373  assert(*lp != NULL);
9374 
9375  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9376 
9377  freeDiveChgSideArrays(*lp);
9378 
9379  /* release LPI rows */
9380  for( i = 0; i < (*lp)->nlpirows; ++i )
9381  {
9382  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9383  }
9384 
9385  if( (*lp)->lpi != NULL )
9386  {
9387  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9388  }
9389 
9390  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9391  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9392  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9393  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9394  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9395  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9396  BMSfreeMemoryArrayNull(&(*lp)->cols);
9397  BMSfreeMemoryArrayNull(&(*lp)->rows);
9398  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9399  BMSfreeMemory(lp);
9400 
9401  return SCIP_OKAY;
9402 }
9403 
9404 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9405  * changes to the LP solver
9406  */
9408  SCIP_LP* lp, /**< LP data */
9409  BMS_BLKMEM* blkmem, /**< block memory */
9410  SCIP_SET* set, /**< global SCIP settings */
9411  SCIP_STAT* stat, /**< problem statistics */
9412  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9413  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9414  )
9415 {
9416  assert(stat != NULL);
9417 
9418  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9419  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9420 
9421  /* mark the empty LP to be solved */
9423  lp->lpobjval = 0.0;
9424  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9425  lp->validfarkaslp = -1;
9426  lp->validdegeneracylp = -1;
9427  lp->validsoldirlp = -1;
9428  lp->validsoldirsol = NULL;
9429  lp->solved = TRUE;
9430  lp->primalfeasible = TRUE;
9431  lp->primalchecked = TRUE;
9432  lp->dualfeasible = TRUE;
9433  lp->dualchecked = TRUE;
9434  lp->solisbasic = FALSE;
9436 
9437  return SCIP_OKAY;
9438 }
9439 
9440 /** adds a column to the LP */
9442  SCIP_LP* lp, /**< LP data */
9443  SCIP_SET* set, /**< global SCIP settings */
9444  SCIP_COL* col, /**< LP column */
9445  int depth /**< depth in the tree where the column addition is performed */
9446  )
9447 {
9448  assert(lp != NULL);
9449  assert(!lp->diving);
9450  assert(col != NULL);
9451  assert(col->len == 0 || col->rows != NULL);
9452  assert(col->lppos == -1);
9453  assert(col->var != NULL);
9454  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9455  assert(SCIPvarGetCol(col->var) == col);
9456  assert(SCIPvarIsIntegral(col->var) == col->integral);
9457 
9458  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9459 #ifdef SCIP_DEBUG
9460  {
9461  int i;
9462  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9463  for( i = 0; i < col->len; ++i )
9464  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9465  SCIPsetDebugMsgPrint(set, "\n");
9466  }
9467 #endif
9468 
9469  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9470  lp->cols[lp->ncols] = col;
9471  col->lppos = lp->ncols;
9472  col->lpdepth = depth;
9473  col->age = 0;
9474  lp->ncols++;
9475  if( col->removable )
9476  lp->nremovablecols++;
9477 
9478  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9479  {
9480  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9481  lp->lazycols[lp->nlazycols] = col;
9482  lp->nlazycols++;
9483  }
9484 
9485  /* mark the current LP unflushed */
9486  lp->flushed = FALSE;
9487 
9488  /* update column arrays of all linked rows */
9489  colUpdateAddLP(col, set);
9490 
9491  /* update the objective function vector norms */
9492  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9493 
9494  checkLinks(lp);
9495 
9496  return SCIP_OKAY;
9497 }
9498 
9499 /** adds a row to the LP and captures it */
9501  SCIP_LP* lp, /**< LP data */
9502  BMS_BLKMEM* blkmem, /**< block memory buffers */
9503  SCIP_SET* set, /**< global SCIP settings */
9504  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9505  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9506  SCIP_ROW* row, /**< LP row */
9507  int depth /**< depth in the tree where the row addition is performed */
9508  )
9509 {
9510  assert(lp != NULL);
9511  assert(row != NULL);
9512  assert(row->len == 0 || row->cols != NULL);
9513  assert(row->lppos == -1);
9514 
9515  SCIProwCapture(row);
9516  SCIProwLock(row);
9517 
9518  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9519 #ifdef SCIP_DEBUG
9520  {
9521  int i;
9522  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9523  for( i = 0; i < row->len; ++i )
9524  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9525  if( !SCIPsetIsZero(set, row->constant) )
9526  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9527  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9528  }
9529 #endif
9530 
9531  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9532  lp->rows[lp->nrows] = row;
9533  row->lppos = lp->nrows;
9534  row->lpdepth = depth;
9535  row->age = 0;
9536  lp->nrows++;
9537  if( row->removable )
9538  lp->nremovablerows++;
9539 
9540  /* mark the current LP unflushed */
9541  lp->flushed = FALSE;
9542 
9543  /* update row arrays of all linked columns */
9544  rowUpdateAddLP(row);
9545 
9546  checkLinks(lp);
9547 
9548  rowCalcNorms(row, set);
9549 
9550  /* check, if row addition to LP events are tracked
9551  * if so, issue ROWADDEDLP event
9552  */
9553  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9554  {
9555  SCIP_EVENT* event;
9556 
9557  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9558  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9559  }
9560 
9561  return SCIP_OKAY;
9562 }
9563 
9564 
9565 #ifndef NDEBUG
9566 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9567  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9568  * the lazycols array
9569  */
9570 static
9572  SCIP_LP* lp, /**< LP data */
9573  SCIP_SET* set /**< global SCIP settings */
9574  )
9575 {
9576  SCIP_Bool contained;
9577  int c;
9578  int i;
9579 
9580  assert(lp != NULL);
9581 
9582  /* check if each column in the lazy column array has a counter part in the column array */
9583  for( i = 0; i < lp->nlazycols; ++i )
9584  {
9585  /* check if each lazy column has at least on lazy bound */
9586  assert(lp->lazycols[i] != NULL);
9587  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9588 
9589  contained = FALSE;
9590  for( c = 0; c < lp->ncols; ++c )
9591  {
9592  if( lp->lazycols[i] == lp->cols[c] )
9593  {
9594  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9595  contained = TRUE;
9596  }
9597  }
9598  assert(contained);
9599  }
9600 
9601  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9602  * array */
9603  for( c = 0; c < lp->ncols; ++c )
9604  {
9605  contained = FALSE;
9606  assert(lp->cols[c] != NULL);
9607 
9608  for( i = 0; i < lp->nlazycols; ++i )
9609  {
9610  if( lp->lazycols[i] == lp->cols[c] )
9611  {
9612  contained = TRUE;
9613  }
9614  }
9615 
9616  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9617  }
9618 }
9619 #else
9620 #define checkLazyColArray(lp, set) /**/
9621 #endif
9622 
9623 /** removes all columns after the given number of cols from the LP */
9625  SCIP_LP* lp, /**< LP data */
9626  SCIP_SET* set, /**< global SCIP settings */
9627  int newncols /**< new number of columns in the LP */
9628  )
9629 {
9630  SCIP_COL* col;
9631  int c;
9632 
9633  assert(lp != NULL);
9634 
9635  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9636  assert(0 <= newncols);
9637  assert(newncols <= lp->ncols);
9638 
9639  if( newncols < lp->ncols )
9640  {
9641  assert(!lp->diving);
9642 
9643  for( c = lp->ncols-1; c >= newncols; --c )
9644  {
9645  col = lp->cols[c];
9646  assert(col != NULL);
9647  assert(col->len == 0 || col->rows != NULL);
9648  assert(col->var != NULL);
9649  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9650  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9651  assert(col->lppos == c);
9652 
9653  /* mark column to be removed from the LP */
9654  col->lppos = -1;
9655  col->lpdepth = -1;
9656  lp->ncols--;
9657 
9658  /* count removable columns */
9659  if( col->removable )
9660  lp->nremovablecols--;
9661 
9662  /* update column arrays of all linked rows */
9663  colUpdateDelLP(col, set);
9664 
9665  /* update the objective function vector norms */
9666  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9667  }
9668  assert(lp->ncols == newncols);
9669  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9670 
9671  /* remove columns which are deleted from the lazy column array */
9672  c = 0;
9673  while( c < lp->nlazycols )
9674  {
9675  if( lp->lazycols[c]->lppos < 0 )
9676  {
9677  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9678  lp->nlazycols--;
9679  }
9680  else
9681  c++;
9682  }
9683 
9684  /* mark the current LP unflushed */
9685  lp->flushed = FALSE;
9686 
9687  checkLazyColArray(lp, set);
9688  checkLinks(lp);
9689  }
9690  assert(lp->nremovablecols <= lp->ncols);
9691 
9692  return SCIP_OKAY;
9693 }
9694 
9695 /** removes and releases all rows after the given number of rows from the LP */
9697  SCIP_LP* lp, /**< LP data */
9698  BMS_BLKMEM* blkmem, /**< block memory */
9699  SCIP_SET* set, /**< global SCIP settings */
9700  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9701  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9702  int newnrows /**< new number of rows in the LP */
9703  )
9704 {
9705  SCIP_ROW* row;
9706  int r;
9707 
9708  assert(lp != NULL);
9709  assert(0 <= newnrows && newnrows <= lp->nrows);
9710 
9711  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9712  if( newnrows < lp->nrows )
9713  {
9714  for( r = lp->nrows-1; r >= newnrows; --r )
9715  {
9716  row = lp->rows[r];
9717  assert(row != NULL);
9718  assert(row->len == 0 || row->cols != NULL);
9719  assert(row->lppos == r);
9720 
9721  /* mark row to be removed from the LP */
9722  row->lppos = -1;
9723  row->lpdepth = -1;
9724  lp->nrows--;
9725 
9726  /* count removable rows */
9727  if( row->removable )
9728  lp->nremovablerows--;
9729 
9730  /* update row arrays of all linked columns */
9731  rowUpdateDelLP(row);
9732 
9733  SCIProwUnlock(lp->rows[r]);
9734 
9735  /* check, if row deletion events are tracked
9736  * if so, issue ROWDELETEDLP event
9737  */
9738  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9739  {
9740  SCIP_EVENT* event;
9741 
9742  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9743  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9744  }
9745 
9746  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9747  }
9748  assert(lp->nrows == newnrows);
9749  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9750 
9751  /* mark the current LP unflushed */
9752  lp->flushed = FALSE;
9753 
9754  checkLinks(lp);
9755  }
9756  assert(lp->nremovablerows <= lp->nrows);
9757 
9758  return SCIP_OKAY;
9759 }
9760 
9761 /** removes all columns and rows from LP, releases all rows */
9763  SCIP_LP* lp, /**< LP data */
9764  BMS_BLKMEM* blkmem, /**< block memory */
9765  SCIP_SET* set, /**< global SCIP settings */
9766  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9767  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9768  )
9769 {
9770  assert(lp != NULL);
9771  assert(!lp->diving);
9772 
9773  SCIPsetDebugMsg(set, "clearing LP\n");
9774  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9775  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9776 
9777  return SCIP_OKAY;
9778 }
9779 
9780 /** remembers number of columns and rows to track the newly added ones */
9782  SCIP_LP* lp /**< current LP data */
9783  )
9784 {
9785  assert(lp != NULL);
9786  assert(!lp->diving);
9787 
9788  lp->firstnewrow = lp->nrows;
9789  lp->firstnewcol = lp->ncols;
9790 }
9791 
9792 /** sets the remembered number of columns and rows to the given values */
9794  SCIP_LP* lp, /**< current LP data */
9795  int nrows, /**< number of rows to set the size marker to */
9796  int ncols /**< number of columns to set the size marker to */
9797  )
9798 {
9799  assert(lp != NULL);
9800  assert(!lp->diving);
9801 
9802  lp->firstnewrow = nrows;
9803  lp->firstnewcol = ncols;
9804 }
9805 
9806 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9808  SCIP_LP* lp, /**< LP data */
9809  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9810  )
9811 {
9812  assert(lp != NULL);
9813  assert(lp->flushed);
9814  assert(lp->solved);
9815  assert(lp->solisbasic);
9816  assert(basisind != NULL);
9817 
9818  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9819 
9820  return SCIP_OKAY;
9821 }
9822 
9823 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9825  SCIP_LP* lp, /**< LP data */
9826  int* cstat, /**< array to store column basis status, or NULL */
9827  int* rstat /**< array to store row basis status, or NULL */
9828  )
9829 {
9830  assert(lp != NULL);
9831  assert(lp->flushed);
9832  assert(lp->solved);
9833  assert(lp->solisbasic);
9834 
9835  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9836 
9837  return SCIP_OKAY;
9838 }
9839 
9840 /** gets a row from the inverse basis matrix B^-1 */
9842  SCIP_LP* lp, /**< LP data */
9843  int r, /**< row number */
9844  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9845  int* inds, /**< array to store the non-zero indices, or NULL */
9846  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9847  * (-1: if we do not store sparsity informations) */
9848  )
9849 {
9850  assert(lp != NULL);
9851  assert(lp->flushed);
9852  assert(lp->solved);
9853  assert(lp->solisbasic);
9854  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9855  assert(coef != NULL);
9856 
9857  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9858 
9859  return SCIP_OKAY;
9860 }
9861 
9862 /** gets a column from the inverse basis matrix B^-1 */
9864  SCIP_LP* lp, /**< LP data */
9865  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9866  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9867  * to get the array which links the B^-1 column numbers to the row and
9868  * column numbers of the LP! c must be between 0 and nrows-1, since the
9869  * basis has the size nrows * nrows */
9870  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9871  int* inds, /**< array to store the non-zero indices, or NULL */
9872  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9873  * (-1: if we do not store sparsity informations) */
9874  )
9875 {
9876  assert(lp != NULL);
9877  assert(lp->flushed);
9878  assert(lp->solved);
9879  assert(lp->solisbasic);
9880  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9881  assert(coef != NULL);
9882 
9883  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9884 
9885  return SCIP_OKAY;
9886 }
9887 
9888 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9890  SCIP_LP* lp, /**< LP data */
9891  int r, /**< row number */
9892  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9893  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9894  int* inds, /**< array to store the non-zero indices, or NULL */
9895  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9896  * (-1: if we do not store sparsity informations) */
9897  )
9898 {
9899  assert(lp != NULL);
9900  assert(lp->flushed);
9901  assert(lp->solved);
9902  assert(lp->solisbasic);
9903  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9904  assert(coef != NULL);
9905 
9906  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9907 
9908  return SCIP_OKAY;
9909 }
9910 
9911 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9912  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9913  */
9915  SCIP_LP* lp, /**< LP data */
9916  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9917  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9918  int* inds, /**< array to store the non-zero indices, or NULL */
9919  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9920  * (-1: if we do not store sparsity informations) */
9921  )
9922 {
9923  assert(lp != NULL);
9924  assert(lp->flushed);
9925  assert(lp->solved);
9926  assert(lp->solisbasic);
9927  assert(0 <= c && c < lp->ncols);
9928  assert(coef != NULL);
9929 
9930  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9931 
9932  return SCIP_OKAY;
9933 }
9934 
9935 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9936  * LP row are swapped in the summation
9937  */
9939  SCIP_LP* lp, /**< LP data */
9940  SCIP_SET* set, /**< global SCIP settings */
9941  SCIP_PROB* prob, /**< problem data */
9942  SCIP_Real* weights, /**< row weights in row summation */
9943  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9944  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9945  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9946  )
9947 {
9948  SCIP_ROW* row;
9949  int r;
9950  int i;
9951  int idx;
9952  SCIP_Bool lhsinfinite;
9953  SCIP_Bool rhsinfinite;
9954 
9955  assert(lp != NULL);
9956  assert(prob != NULL);
9957  assert(weights != NULL);
9958  assert(sumcoef != NULL);
9959  assert(sumlhs != NULL);
9960  assert(sumrhs != NULL);
9961 
9962  /**@todo test, if a column based summation is faster */
9963 
9964  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9965  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9966  *sumlhs = 0.0;
9967  *sumrhs = 0.0;
9968  lhsinfinite = FALSE;
9969  rhsinfinite = FALSE;
9970  for( r = 0; r < lp->nrows; ++r )
9971  {
9972  if( !SCIPsetIsZero(set, weights[r]) )
9973  {
9974  row = lp->rows[r];
9975  assert(row != NULL);
9976  assert(row->len == 0 || row->cols != NULL);
9977  assert(row->len == 0 || row->cols_index != NULL);
9978  assert(row->len == 0 || row->vals != NULL);
9979 
9980  /* add the row coefficients to the sum */
9981  for( i = 0; i < row->len; ++i )
9982  {
9983  assert(row->cols[i] != NULL);
9984  assert(row->cols[i]->var != NULL);
9985  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9986  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9987  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9988  idx = row->cols[i]->var_probindex;
9989  assert(0 <= idx && idx < prob->nvars);
9990  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9991  }
9992 
9993  /* add the row sides to the sum, depending on the sign of the weight */
9994  if( weights[r] > 0.0 )
9995  {
9996  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9997  if( !lhsinfinite )
9998  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9999  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10000  if( !rhsinfinite )
10001  (*sumrhs) += weights[r] * (row->rhs - row->constant);
10002  }
10003  else
10004  {
10005  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10006  if( !lhsinfinite )
10007  (*sumlhs) += weights[r] * (row->rhs - row->constant);
10008  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10009  if( !rhsinfinite )
10010  (*sumrhs) += weights[r] * (row->lhs - row->constant);
10011  }
10012  }
10013  }
10014 
10015  if( lhsinfinite )
10016  *sumlhs = -SCIPsetInfinity(set);
10017  if( rhsinfinite )
10018  *sumrhs = SCIPsetInfinity(set);
10019 
10020  return SCIP_OKAY;
10021 }
10022 
10023 /** stores LP state (like basis information) into LP state object */
10025  SCIP_LP* lp, /**< LP data */
10026  BMS_BLKMEM* blkmem, /**< block memory */
10027  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10028  )
10029 {
10030  assert(lp != NULL);
10031  assert(lp->flushed);
10032  assert(lp->solved);
10033  assert(blkmem != NULL);
10034  assert(lpistate != NULL);
10035 
10036  /* check whether there is no lp */
10037  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10038  *lpistate = NULL;
10039  else
10040  {
10041  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10042  }
10043 
10044  return SCIP_OKAY;
10045 }
10046 
10047 /** loads LP state (like basis information) into solver */
10049  SCIP_LP* lp, /**< LP data */
10050  BMS_BLKMEM* blkmem, /**< block memory */
10051  SCIP_SET* set, /**< global SCIP settings */
10052  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10053  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10054  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10055  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10056  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10057  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10058  )
10059 {
10060  assert(lp != NULL);
10061  assert(blkmem != NULL);
10062 
10063  /* flush changes to the LP solver */
10064  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
10065  assert(lp->flushed);
10066 
10067  if( lp->solved && lp->solisbasic )
10068  return SCIP_OKAY;
10069 
10070  /* set LPI state in the LP solver */
10071  if( lpistate == NULL )
10072  lp->solisbasic = FALSE;
10073  else
10074  {
10075  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10076  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10077  }
10078  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10079  * flushed and solved, also, e.g., when we hit the iteration limit
10080  */
10081  lp->primalfeasible = wasprimfeas;
10082  lp->primalchecked = wasprimchecked;
10083  lp->dualfeasible = wasdualfeas;
10084  lp->dualchecked = wasdualchecked;
10085 
10086  return SCIP_OKAY;
10087 }
10088 
10089 /** frees LP state information */
10091  SCIP_LP* lp, /**< LP data */
10092  BMS_BLKMEM* blkmem, /**< block memory */
10093  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10094  )
10095 {
10096  assert(lp != NULL);
10097 
10098  if( *lpistate != NULL )
10099  {
10100  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10101  }
10102 
10103  return SCIP_OKAY;
10104 }
10105 
10106 /** interrupts the currently ongoing lp solve, or disables the interrupt */
10108  SCIP_LP* lp, /**< LP data */
10109  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
10110  )
10111 {
10112  assert(lp != NULL);
10113 
10114  if( lp->lpi == NULL )
10115  return SCIP_OKAY;
10116 
10117  SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
10118 
10119  return SCIP_OKAY;
10120 }
10121 
10122 /** stores pricing norms into LP norms object */
10124  SCIP_LP* lp, /**< LP data */
10125  BMS_BLKMEM* blkmem, /**< block memory */
10126  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10127  )
10128 {
10129  assert(lp != NULL);
10130  assert(lp->flushed);
10131  assert(lp->solved);
10132  assert(blkmem != NULL);
10133  assert(lpinorms != NULL);
10134 
10135  /* check whether there is no lp */
10136  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10137  *lpinorms = NULL;
10138  else
10139  {
10140  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10141  }
10142 
10143  return SCIP_OKAY;
10144 }
10145 
10146 /** loads pricing norms from LP norms object into solver */
10148  SCIP_LP* lp, /**< LP data */
10149  BMS_BLKMEM* blkmem, /**< block memory */
10150  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10151  )
10152 {
10153  assert(lp != NULL);
10154  assert(blkmem != NULL);
10155  assert(lp->flushed);
10156 
10157  /* set LPI norms in the LP solver */
10158  if( lpinorms != NULL )
10159  {
10160  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10161  }
10162 
10163  return SCIP_OKAY;
10164 }
10165 
10166 /** frees pricing norms information */
10168  SCIP_LP* lp, /**< LP data */
10169  BMS_BLKMEM* blkmem, /**< block memory */
10170  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10171  )
10172 {
10173  assert(lp != NULL);
10174 
10175  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10176 
10177  return SCIP_OKAY;
10178 }
10179 
10180 /** return the current cutoff bound of the lp */
10182  SCIP_LP* lp /**< current LP data */
10183  )
10184 {
10185  assert(lp != NULL);
10186 
10187  return lp->cutoffbound;
10188 }
10189 
10190 /** sets the upper objective limit of the LP solver */
10192  SCIP_LP* lp, /**< current LP data */
10193  SCIP_SET* set, /**< global SCIP settings */
10194  SCIP_PROB* prob, /**< problem data */
10195  SCIP_Real cutoffbound /**< new upper objective limit */
10196  )
10197 {
10198  assert(lp != NULL);
10199 
10200  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10201 
10202  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10203  * in SCIPendDive())
10204  */
10205  if( SCIPlpDivingObjChanged(lp) )
10206  {
10207  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10208  return SCIP_OKAY;
10209  }
10210 
10211  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10212  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10213  {
10214  /* mark the current solution invalid */
10215  lp->solved = FALSE;
10216  lp->lpobjval = SCIP_INVALID;
10218  }
10219  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10220  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10221  */
10223  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10224  {
10225  assert(lp->flushed);
10226  assert(lp->solved);
10228  }
10229 
10230  lp->cutoffbound = cutoffbound;
10231 
10232  return SCIP_OKAY;
10233 }
10234 
10235 /** gets current primal feasibility tolerance of LP solver */
10237  SCIP_LP* lp /**< current LP data */
10238  )
10239 {
10240  assert(lp != NULL);
10241 
10242  return lp->feastol;
10243 }
10244 
10245 /** sets primal feasibility tolerance of LP solver */
10247  SCIP_LP* lp, /**< current LP data */
10248  SCIP_SET* set, /**< global SCIP settings */
10249  SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10250  )
10251 {
10252  assert(lp != NULL);
10253  assert(newfeastol > 0.0);
10254 
10255  SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10256 
10257  /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10258  if( newfeastol < lp->feastol )
10259  {
10260  lp->solved = FALSE;
10262  }
10263 
10264  lp->feastol = newfeastol;
10265 }
10266 
10267 /** resets primal feasibility tolerance of LP solver
10268  *
10269  * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10270  */
10272  SCIP_LP* lp, /**< current LP data */
10273  SCIP_SET* set /**< global SCIP settings */
10274  )
10275 {
10276  assert(lp != NULL);
10277 
10278  SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10279 
10280  if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10281  SCIPlpSetFeastol(lp, set, MIN(SCIPsetRelaxfeastol(set), SCIPsetLPFeastolFactor(set) * SCIPsetFeastol(set))); /*lint !e666*/
10282  else
10284 }
10285 
10286 /** returns the name of the given LP algorithm */
10287 static
10288 const char* lpalgoName(
10289  SCIP_LPALGO lpalgo /**< LP algorithm */
10290  )
10291 {
10292  switch( lpalgo )
10293  {
10295  return "primal simplex";
10297  return "dual simplex";
10298  case SCIP_LPALGO_BARRIER:
10299  return "barrier";
10301  return "barrier/crossover";
10302  default:
10303  SCIPerrorMessage("invalid LP algorithm\n");
10304  SCIPABORT();
10305  return "invalid"; /*lint !e527*/
10306  }
10307 }
10308 
10309 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10310 static
10312  SCIP_LP* lp, /**< current LP data */
10313  SCIP_SET* set, /**< global SCIP settings */
10314  SCIP_STAT* stat, /**< problem statistics */
10315  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10316  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10317  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10318  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10319  )
10320 {
10321  SCIP_Real timedelta;
10322  SCIP_RETCODE retcode;
10323  int iterations;
10324 
10325  assert(lp != NULL);
10326  assert(lp->flushed);
10327  assert(set != NULL);
10328  assert(stat != NULL);
10329  assert(lperror != NULL);
10330 
10331  SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10332  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10333 
10334  *lperror = FALSE;
10335 
10336 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10337  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10338  {
10339  char fname[SCIP_MAXSTRLEN];
10340  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10341  SCIP_CALL( SCIPlpWrite(lp, fname) );
10342  SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10343  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10344  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10345  }
10346 #endif
10347 
10348  /* start timing */
10349  if( lp->diving || lp->probing )
10350  {
10351  if( lp->strongbranchprobing )
10352  SCIPclockStart(stat->strongbranchtime, set);
10353  else
10354  SCIPclockStart(stat->divinglptime, set);
10355 
10356  timedelta = 0.0; /* unused for diving or probing */
10357  }
10358  else
10359  {
10360  SCIPclockStart(stat->primallptime, set);
10361  timedelta = -SCIPclockGetTime(stat->primallptime);
10362  }
10363 
10364  /* if this is a call to resolve an instable LP, collect time */
10365  if( instable )
10366  {
10368  }
10369 
10370  /* call primal simplex */
10371  retcode = SCIPlpiSolvePrimal(lp->lpi);
10372  if( retcode == SCIP_LPERROR )
10373  {
10374  *lperror = TRUE;
10375  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10376  }
10377  else
10378  {
10379  SCIP_CALL( retcode );
10380  }
10382  lp->solisbasic = TRUE;
10383 
10384  /* stop timing */
10385  if( lp->diving || lp->probing )
10386  {
10387  if( lp->strongbranchprobing )
10388  SCIPclockStop(stat->strongbranchtime, set);
10389  else
10390  SCIPclockStop(stat->divinglptime, set);
10391  }
10392  else
10393  {
10394  timedelta += SCIPclockGetTime(stat->primallptime);
10395  SCIPclockStop(stat->primallptime, set);
10396  }
10397 
10398  if ( instable )
10399  {
10401  }
10402 
10403  /* count number of iterations */
10404  SCIPstatIncrement(stat, set, lpcount);
10405  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10406  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10407  {
10408  if( !lp->strongbranchprobing )
10409  {
10410  SCIPstatIncrement(stat, set, nlps);
10411  SCIPstatAdd( stat, set, nlpiterations, iterations );
10412  }
10413  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10414  {
10415  SCIPstatIncrement(stat, set, nprimalresolvelps );
10416  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10417  }
10418  if ( instable )
10419  {
10420  SCIPstatIncrement(stat, set, nresolveinstablelps);
10421  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10422  }
10423  if( lp->diving || lp->probing )
10424  {
10425  if( lp->strongbranchprobing )
10426  {
10427  SCIPstatIncrement(stat, set, nsbdivinglps);
10428  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10429  }
10430  else
10431  {
10432  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10433  SCIPstatIncrement(stat, set, ndivinglps);
10434  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10435  }
10436  }
10437  else
10438  {
10439  SCIPstatIncrement(stat, set, nprimallps);
10440  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10441  }
10442  }
10443  else
10444  {
10445  if ( ! lp->diving && ! lp->probing )
10446  {
10447  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10448  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10449  }
10450 
10451  if ( keepsol && !(*lperror) )
10452  {
10453  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10454  if( lp->validsollp == stat->lpcount-1 )
10455  lp->validsollp = stat->lpcount;
10456  if( lp->validfarkaslp == stat->lpcount-1 )
10457  lp->validfarkaslp = stat->lpcount;
10458  }
10459  }
10460 
10461  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10462  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10463 
10464  return SCIP_OKAY;
10465 }
10466 
10467 /** calls LPI to perform dual simplex, measures time and counts iterations */
10468 static
10470  SCIP_LP* lp, /**< current LP data */
10471  SCIP_SET* set, /**< global SCIP settings */
10472  SCIP_STAT* stat, /**< problem statistics */
10473  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10474  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10475  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10476  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10477  )
10478 {
10479  SCIP_Real timedelta;
10480  SCIP_RETCODE retcode;
10481  int iterations;
10482 
10483  assert(lp != NULL);
10484  assert(lp->flushed);
10485  assert(set != NULL);
10486  assert(stat != NULL);
10487  assert(lperror != NULL);
10488 
10489  SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10490  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10491 
10492  *lperror = FALSE;
10493 
10494 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10495  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10496  {
10497  char fname[SCIP_MAXSTRLEN];
10498  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10499  SCIP_CALL( SCIPlpWrite(lp, fname) );
10500  SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10501  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10502  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10503  }
10504 #endif
10505 
10506  /* start timing */
10507  if( lp->diving || lp->probing )
10508  {
10509  if( lp->strongbranchprobing )
10510  SCIPclockStart(stat->strongbranchtime, set);
10511  else
10512  SCIPclockStart(stat->divinglptime, set);
10513 
10514  timedelta = 0.0; /* unused for diving or probing */
10515  }
10516  else
10517  {
10518  SCIPclockStart(stat->duallptime, set);
10519  timedelta = -SCIPclockGetTime(stat->duallptime);
10520  }
10521 
10522  /* if this is a call to resolve an instable LP, collect time */
10523  if ( instable )
10524  {
10526  }
10527 
10528  /* call dual simplex */
10529  retcode = SCIPlpiSolveDual(lp->lpi);
10530  if( retcode == SCIP_LPERROR )
10531  {
10532  *lperror = TRUE;
10533  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10534  }
10535  else
10536  {
10537  SCIP_CALL( retcode );
10538  }
10540  lp->solisbasic = TRUE;
10541 
10542  /* stop timing */
10543  if( lp->diving || lp->probing )
10544  {
10545  if( lp->strongbranchprobing )
10546  SCIPclockStop(stat->strongbranchtime, set);
10547  else
10548  SCIPclockStop(stat->divinglptime, set);
10549  }
10550  else
10551  {
10552  timedelta += SCIPclockGetTime(stat->duallptime);
10553  SCIPclockStop(stat->duallptime, set);
10554  }
10555 
10556  if ( instable )
10557  {
10559  }
10560 
10561  /* count number of iterations */
10562  SCIPstatIncrement(stat, set, lpcount);
10563  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10564  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10565  {
10566  if( !lp->strongbranchprobing )
10567  {
10568  SCIPstatIncrement(stat, set, nlps);
10569  SCIPstatAdd(stat, set, nlpiterations, iterations);
10570  }
10571  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10572  {
10573  SCIPstatIncrement(stat, set, ndualresolvelps);
10574  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10575  }
10576  if ( instable )
10577  {
10578  SCIPstatIncrement(stat, set, nresolveinstablelps);
10579  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10580  }
10581  if( lp->diving || lp->probing )
10582  {
10583  if( lp->strongbranchprobing )
10584  {
10585  SCIPstatIncrement(stat, set, nsbdivinglps);
10586  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10587  }
10588  else
10589  {
10590  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10591  SCIPstatIncrement(stat, set, ndivinglps);
10592  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10593  }
10594  }
10595  else
10596  {
10597  SCIPstatIncrement(stat, set, nduallps);
10598  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10599  }
10600  }
10601  else
10602  {
10603  if ( ! lp->diving && ! lp->probing )
10604  {
10605  SCIPstatIncrement(stat, set, ndualzeroitlps);
10606  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10607  }
10608 
10609  if( keepsol && !(*lperror) )
10610  {
10611  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10612  if( lp->validsollp == stat->lpcount-1 )
10613  lp->validsollp = stat->lpcount;
10614  if( lp->validfarkaslp == stat->lpcount-1 )
10615  lp->validfarkaslp = stat->lpcount;
10616  }
10617  }
10618 
10619  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10620  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10621 
10622  return SCIP_OKAY;
10623 }
10624 
10625 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10626  *
10627  * We follow the approach of the following paper to find a lexicographically minimal optimal
10628  * solution:
10629  *
10630  * Zanette, Fischetti, Balas@n
10631  * Can pure cutting plane algorithms work?@n
10632  * IPCO 2008, Bertinoro, Italy.
10633  *
10634  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10635  * heuristic, i.e., we limit the number of components which are minimized.
10636  *
10637  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10638  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10639  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10640  * pivots that will not change the objective are allowed afterwards.
10641  *
10642  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10643  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10644  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10645  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10646  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10647  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10648  * reduced cost. We then choose the next variable and iterate.
10649  *
10650  * We stop the process once we do not find candidates or have performed a maximum number of
10651  * iterations.
10652  *
10653  * @todo Does this really produce a lexicographically minimal solution?
10654  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10655  * guarantee that these variables will not be changed in later stages? We can fix these variables
10656  * to their lower bound, but this destroys the basis.
10657  * @todo Should we use lexicographical minimization in diving/probing or not?
10658  */
10659 static
10661  SCIP_LP* lp, /**< current LP data */
10662  SCIP_SET* set, /**< global SCIP settings */
10663  SCIP_STAT* stat, /**< problem statistics */
10664  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10665  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10666  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10667  )
10668 {
10669  SCIP_Real timedelta;
10670  SCIP_RETCODE retcode;
10671  int totalIterations;
10672  int lexIterations;
10673  int iterations;
10674  int rounds;
10675 
10676  assert(lp != NULL);
10677  assert(lp->flushed);
10678  assert(set != NULL);
10679  assert(stat != NULL);
10680  assert(lperror != NULL);
10681 
10682  SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10683  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10684 
10685  *lperror = FALSE;
10686 
10687  /* start timing */
10688  if( lp->diving || lp->probing )
10689  {
10690  if( lp->strongbranchprobing )
10691  SCIPclockStart(stat->strongbranchtime, set);
10692  else
10693  SCIPclockStart(stat->divinglptime, set);
10694 
10695  timedelta = 0.0; /* unused for diving or probing */
10696  }
10697  else
10698  {
10699  SCIPclockStart(stat->duallptime, set);
10700  timedelta = -SCIPclockGetTime(stat->duallptime);
10701  }
10702 
10703  /* call dual simplex for first lp */
10704  retcode = SCIPlpiSolveDual(lp->lpi);
10705  if( retcode == SCIP_LPERROR )
10706  {
10707  *lperror = TRUE;
10708  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10709  }
10710  else
10711  {
10712  SCIP_CALL( retcode );
10713  }
10714  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10715  totalIterations = iterations;
10716 
10717  /* stop timing */
10718  if( lp->diving || lp->probing )
10719  {
10720  if( lp->strongbranchprobing )
10721  SCIPclockStop(stat->strongbranchtime, set);
10722  else
10723  SCIPclockStop(stat->divinglptime, set);
10724  }
10725  else
10726  {
10727  timedelta += SCIPclockGetTime(stat->duallptime);
10728  SCIPclockStop(stat->duallptime, set);
10729  }
10730 
10731  /* count number of iterations */
10732  SCIPstatIncrement(stat, set, lpcount);
10733  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10734  {
10735  if( lp->strongbranchprobing )
10736  {
10737  SCIPstatAdd(stat, set, nlpiterations, iterations);
10738  }
10739  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10740  {
10741  SCIPstatIncrement(stat, set, ndualresolvelps);
10742  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10743  }
10744  if( lp->diving || lp->probing )
10745  {
10746  if( lp->strongbranchprobing )
10747  {
10748  SCIPstatIncrement(stat, set, nsbdivinglps);
10749  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10750  }
10751  else
10752  {
10753  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10754  SCIPstatIncrement(stat, set, ndivinglps);
10755  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10756  }
10757  }
10758  else
10759  {
10760  SCIPstatIncrement(stat, set, nduallps);
10761  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10762  }
10763  }
10764  else
10765  {
10766  if ( ! lp->diving && ! lp->probing )
10767  {
10768  SCIPstatIncrement(stat, set, ndualzeroitlps);
10769  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10770  }
10771  }
10772  lexIterations = 0;
10773 
10774  /* search for lexicographically minimal optimal solution */
10775  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10776  {
10777  SCIP_Bool chooseBasic;
10778  SCIP_Real* primsol;
10779  SCIP_Real* dualsol;
10780  SCIP_Real* redcost;
10781  int* cstat;
10782  int* rstat;
10783  SCIP_Real* newobj;
10784  SCIP_Real* newlb;
10785  SCIP_Real* newub;
10786  SCIP_Real* newlhs;
10787  SCIP_Real* newrhs;
10788  SCIP_Real* oldlb;
10789  SCIP_Real* oldub;
10790  SCIP_Real* oldlhs;
10791  SCIP_Real* oldrhs;
10792  SCIP_Real* oldobj;
10793  SCIP_Bool* fixedc;
10794  SCIP_Bool* fixedr;
10795  int* indcol;
10796  int* indrow;
10797  int* indallcol;
10798  int* indallrow;
10799  int nDualDeg;
10800  int r, c;
10801  int cntcol;
10802  int cntrow;
10803  int nruns;
10804  int pos;
10805 
10806  chooseBasic = set->lp_lexdualbasic;
10807 
10808  /* start timing */
10809  SCIPclockStart(stat->lexduallptime, set);
10810 
10811  /* get all solution information */
10812  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10813  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10814  if( chooseBasic )
10815  {
10816  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10817  }
10818  else
10819  primsol = NULL;
10820 
10821  /* get basic and nonbasic information */
10822  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10823  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10824 
10825  /* save bounds, lhs/rhs, and objective */
10826  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10827  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10828  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10829  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10830  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10831  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10832  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10833  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10834 
10835  /* get storage for several arrays */
10836  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10837  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10838  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10839 
10840  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10841  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10842  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10843 
10844  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10845  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10846 
10847  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10848  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10849 
10850  /* initialize: set objective to 0, get fixed variables */
10851  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10852  for( c = 0; c < lp->nlpicols; ++c )
10853  {
10854  newobj[c] = 0.0;
10855  indallcol[c] = c;
10856  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10857  fixedc[c] = TRUE;
10858  else
10859  fixedc[c] = FALSE;
10860  }
10861 
10862  /* initialize: get fixed slack variables */
10863  for( r = 0; r < lp->nlpirows; ++r )
10864  {
10865  indallrow[r] = r;
10866  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10867  fixedr[r] = TRUE;
10868  else
10869  fixedr[r] = FALSE;
10870  }
10871 
10872 #ifdef DEBUG_LEXDUAL
10873  {
10874  int j;
10875 
10876  if( !chooseBasic )
10877  {
10878  assert(primsol == NULL);
10879  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10880  }
10881  assert(primsol != NULL);
10882  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10883  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10884 
10885  for( j = 0; j < lp->nlpicols; ++j )
10886  {
10887  if( fixedc[j] )
10888  {
10889  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10890  }
10891  else
10892  {
10893  char type;
10894  switch( (SCIP_BASESTAT) cstat[j] )
10895  {
10896  case SCIP_BASESTAT_LOWER:
10897  type = 'l';
10898  break;
10899  case SCIP_BASESTAT_UPPER:
10900  type = 'u';
10901  break;
10902  case SCIP_BASESTAT_ZERO:
10903  type = 'z';
10904  break;
10905  case SCIP_BASESTAT_BASIC:
10906  type = 'b';
10907  break;
10908  default:
10909  type = '?';
10910  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10911  SCIPABORT();
10912  }
10913  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10914  }
10915  }
10916  SCIPsetDebugMsg(set, "\n\n");
10917 
10918  if( !chooseBasic )
10919  {
10920  SCIPsetFreeBufferArray(set, &primsol);
10921  assert(primsol == NULL);
10922  }
10923  }
10924 #endif
10925 
10926  /* perform lexicographic rounds */
10927  pos = -1;
10928  nruns = 0;
10929  rounds = 0;
10930  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10931  do
10932  {
10933  int oldpos;
10934 
10935  /* get current solution */
10936  if( chooseBasic )
10937  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10938  else
10939  {
10940  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10941  assert(primsol == NULL);
10942  }
10943 
10944  /* get current basis */
10945  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10946 
10947  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10948  nDualDeg = 0;
10949  cntcol = 0;
10950  oldpos = pos;
10951  pos = -1;
10952  for( c = 0; c < lp->nlpicols; ++c )
10953  {
10954  if( !fixedc[c] )
10955  {
10956  /* check whether variable is in basis */
10957  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10958  {
10959  /* store first candidate */
10960  if( pos == -1 && c > oldpos )
10961  {
10962  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10963  pos = c;
10964  }
10965  }
10966  else
10967  {
10968  /* reduced cost == 0 -> possible candidate */
10969  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10970  {
10971  ++nDualDeg;
10972  /* only if we have not yet found a candidate */
10973  if( pos == -1 && c > oldpos )
10974  {
10975  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10976  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10977  {
10978  newlb[cntcol] = oldlb[c];
10979  newub[cntcol] = oldlb[c];
10980  indcol[cntcol++] = c;
10981  fixedc[c] = TRUE;
10982  }
10983  else /* found a non-fixed candidate */
10984  {
10985  if( !chooseBasic )
10986  pos = c;
10987  }
10988  }
10989  }
10990  else
10991  {
10992  /* nonzero reduced cost -> variable can be fixed */
10993  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10994  {
10995  newlb[cntcol] = oldlb[c];
10996  newub[cntcol] = oldlb[c];
10997  }
10998  else
10999  {
11000  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
11001  {
11002  newlb[cntcol] = oldub[c];
11003  newub[cntcol] = oldub[c];
11004  }
11005  else
11006  {
11007  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
11008  newlb[cntcol] = 0.0;
11009  newub[cntcol] = 0.0;
11010  }
11011  }
11012  indcol[cntcol++] = c;
11013  fixedc[c] = TRUE;
11014  }
11015  }
11016  }
11017  }
11018 
11019  /* check rows */
11020  cntrow = 0;
11021  for( r = 0; r < lp->nlpirows; ++r )
11022  {
11023  if( !fixedr[r] )
11024  {
11025  /* consider only nonbasic rows */
11026  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11027  {
11028  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
11029  if( SCIPsetIsFeasZero(set, dualsol[r]) )
11030  ++nDualDeg;
11031  else
11032  {
11033  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11034  {
11035  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11036  newlhs[cntrow] = oldlhs[r];
11037  newrhs[cntrow] = oldlhs[r];
11038  }
11039  else
11040  {
11041  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11042  newlhs[cntrow] = oldrhs[r];
11043  newrhs[cntrow] = oldrhs[r];
11044  }
11045  indrow[cntrow++] = r;
11046  fixedr[r] = TRUE;
11047  }
11048  }
11049  }
11050  }
11051 
11052  if( nDualDeg > 0 && pos >= 0 )
11053  {
11054  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11055 
11056  /* change objective */
11057  if( nruns == 0 )
11058  {
11059  /* set objective to appropriate unit vector for first run */
11060  newobj[pos] = 1.0;
11061  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11062  }
11063  else
11064  {
11065  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11066  SCIP_Real obj = 1.0;
11067  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11068  }
11069 
11070  /* fix variables */
11071  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11072  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11073 
11074  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11075  retcode = SCIPlpiSolvePrimal(lp->lpi);
11076  if( retcode == SCIP_LPERROR )
11077  {
11078  *lperror = TRUE;
11079  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11080  }
11081  else
11082  {
11083  SCIP_CALL( retcode );
11084  }
11085  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11086  lexIterations += iterations;
11087 
11088 #ifdef DEBUG_LEXDUAL
11089  if( iterations > 0 )
11090  {
11091  int j;
11092 
11093  if( !chooseBasic )
11094  {
11095  assert(primsol == NULL);
11096  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
11097  }
11098  assert(primsol != NULL);
11099  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
11100 
11101  for( j = 0; j < lp->nlpicols; ++j )
11102  {
11103  if( fixedc[j] )
11104  {
11105  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11106  }
11107  else
11108  {
11109  char cstart = '[';
11110  char cend = ']';
11111  char type;
11112 
11113  if(j == pos)
11114  {
11115  cstart = '*';
11116  cend = '*';
11117  }
11118 
11119  switch( (SCIP_BASESTAT) cstat[j] )
11120  {
11121  case SCIP_BASESTAT_LOWER:
11122  type = 'l';
11123  break;
11124  case SCIP_BASESTAT_UPPER:
11125  type = 'u';
11126  break;
11127  case SCIP_BASESTAT_ZERO:
11128  type = 'z';
11129  break;
11130  case SCIP_BASESTAT_BASIC:
11131  type = 'b';
11132  break;
11133  default:
11134  type = '?';
11135  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11136  SCIPABORT();
11137  }
11138  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11139  }
11140  }
11141  SCIPsetDebugMsg(set, "\n\n");
11142 
11143  if( !chooseBasic )
11144  {
11145  SCIPsetFreeBufferArray(set, &primsol);
11146  assert(primsol == NULL);
11147  }
11148  }
11149 #endif
11150 
11151  /* count only as round if iterations have been performed */
11152  if( iterations > 0 )
11153  ++rounds;
11154  ++nruns;
11155  }
11156  }
11157  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11158 
11159  /* reset bounds, lhs/rhs, and obj */
11160  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11161  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11162  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11163 
11164  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
11165  retcode = SCIPlpiSolveDual(lp->lpi);
11166  if( retcode == SCIP_LPERROR )
11167  {
11168  *lperror = TRUE;
11169  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11170  }
11171  else
11172  {
11173  SCIP_CALL( retcode );
11174  }
11175  assert(SCIPlpiIsOptimal(lp->lpi));
11176  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11177  lexIterations += iterations;
11178 
11179  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11180 
11181  /* count number of iterations */
11182  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11183  SCIPstatIncrement(stat, set, nlps);
11184 
11185  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11186  {
11187  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11188  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11189  {
11190  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11191  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11192  }
11193  SCIPstatIncrement(stat, set, nlexduallps);
11194  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11195 
11196  totalIterations += lexIterations;
11197  }
11198 
11199  /* free space */
11200  SCIPsetFreeBufferArray(set, &newobj);
11201 
11202  SCIPsetFreeBufferArray(set, &fixedr);
11203  SCIPsetFreeBufferArray(set, &fixedc);
11204 
11205  SCIPsetFreeBufferArray(set, &indallrow);
11206  SCIPsetFreeBufferArray(set, &indallcol);
11207 
11208  SCIPsetFreeBufferArray(set, &indrow);
11209  SCIPsetFreeBufferArray(set, &newrhs);
11210  SCIPsetFreeBufferArray(set, &newlhs);
11211 
11212  SCIPsetFreeBufferArray(set, &indcol);
11213  SCIPsetFreeBufferArray(set, &newub);
11214  SCIPsetFreeBufferArray(set, &newlb);
11215 
11216  SCIPsetFreeBufferArray(set, &oldobj);
11217  SCIPsetFreeBufferArray(set, &oldrhs);
11218  SCIPsetFreeBufferArray(set, &oldlhs);
11219  SCIPsetFreeBufferArray(set, &oldub);
11220  SCIPsetFreeBufferArray(set, &oldlb);
11221 
11222  SCIPsetFreeBufferArray(set, &rstat);
11223  SCIPsetFreeBufferArray(set, &cstat);
11224 
11225  SCIPsetFreeBufferArray(set, &redcost);
11226  SCIPsetFreeBufferArray(set, &dualsol);
11227  if( chooseBasic )
11228  SCIPsetFreeBufferArray(set, &primsol);
11229 
11230  /* stop timing */
11231  SCIPclockStop(stat->lexduallptime, set);
11232 
11233  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11234  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11235  }
11237  lp->solisbasic = TRUE;
11238 
11239  if( totalIterations > 0 && !lp->strongbranchprobing )
11240  SCIPstatIncrement(stat, set, nlps);
11241  else
11242  {
11243  if( keepsol && !(*lperror) )
11244  {
11245  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11246  if( lp->validsollp == stat->lpcount-1 )
11247  lp->validsollp = stat->lpcount;
11248  if( lp->validfarkaslp == stat->lpcount-1 )
11249  lp->validfarkaslp = stat->lpcount;
11250  }
11251  }
11252 
11253  return SCIP_OKAY;
11254 }
11255 
11256 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11257 static
11259  SCIP_LP* lp, /**< current LP data */
11260  SCIP_SET* set, /**< global SCIP settings */
11261  SCIP_STAT* stat, /**< problem statistics */
11262  SCIP_Bool crossover, /**< should crossover be performed? */
11263  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11264  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11265  )
11266 {
11267  SCIP_Real timedelta;
11268  SCIP_RETCODE retcode;
11269  int iterations;
11270 
11271  assert(lp != NULL);
11272  assert(lp->flushed);
11273  assert(set != NULL);
11274  assert(stat != NULL);
11275  assert(lperror != NULL);
11276 
11277  SCIPsetDebugMsg(set, "solving LP %" SCIP_LONGINT_FORMAT " (%d cols, %d rows) with barrier%s (diving=%d, nbarrierlps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11278  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11279  stat->nbarrierlps, stat->ndivinglps);
11280 
11281  *lperror = FALSE;
11282 
11283 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11284  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11285  {
11286  char fname[SCIP_MAXSTRLEN];
11287  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11288  SCIP_CALL( SCIPlpWrite(lp, fname) );
11289  SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11290  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11291  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11292  }
11293 #endif
11294 
11295  /* start timing */
11296  if( lp->diving || lp->probing )
11297  {
11298  if( lp->strongbranchprobing )
11299  SCIPclockStart(stat->strongbranchtime, set);
11300  else
11301  SCIPclockStart(stat->divinglptime, set);
11302 
11303  timedelta = 0.0; /* unused for diving or probing */
11304  }
11305  else
11306  {
11307  SCIPclockStart(stat->barrierlptime, set);
11308  timedelta = -SCIPclockGetTime(stat->barrierlptime);
11309  }
11310 
11311  /* call barrier algorithm */
11312  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11313  if( retcode == SCIP_LPERROR )
11314  {
11315  *lperror = TRUE;
11316  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11317  }
11318  else
11319  {
11320  SCIP_CALL( retcode );
11321  }
11323  lp->solisbasic = crossover;
11324 
11325  /* stop timing */
11326  if( lp->diving || lp->probing )
11327  {
11328  if( lp->strongbranchprobing )
11329  SCIPclockStop(stat->strongbranchtime, set);
11330  else
11331  SCIPclockStop(stat->divinglptime, set);
11332  }
11333  else
11334  {
11335  SCIPclockStop(stat->barrierlptime, set);
11336  timedelta += SCIPclockGetTime(stat->barrierlptime);
11337  }
11338 
11339  /* count number of iterations */
11340  SCIPstatIncrement(stat, set, lpcount);
11341  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11342  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11343  {
11344  if( !lp->strongbranchprobing )
11345  {
11346  SCIPstatIncrement(stat, set, nlps);
11347  SCIPstatAdd(stat, set, nlpiterations, iterations);
11348  }
11349  if( lp->diving || lp->probing )
11350  {
11351  if( lp->strongbranchprobing )
11352  {
11353  SCIPstatIncrement(stat, set, nsbdivinglps);
11354  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11355  }
11356  else
11357  {
11358  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11359  SCIPstatIncrement(stat, set, ndivinglps);
11360  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11361  }
11362  }
11363  else
11364  {
11365  SCIPstatIncrement(stat, set, nbarrierlps);
11366  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11367  }
11368  }
11369  else
11370  {
11371  if ( ! lp->diving && ! lp->probing )
11372  {
11373  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11374  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11375  }
11376 
11377  if( keepsol && !(*lperror) )
11378  {
11379  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11380  if( lp->validsollp == stat->lpcount-1 )
11381  lp->validsollp = stat->lpcount;
11382  if( lp->validfarkaslp == stat->lpcount-1 )
11383  lp->validfarkaslp = stat->lpcount;
11384  }
11385  }
11386 
11387  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11388  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11389 
11390  return SCIP_OKAY;
11391 }
11392 
11393 /** solves the LP with the given algorithm */
11394 static
11396  SCIP_LP* lp, /**< current LP data */
11397  SCIP_SET* set, /**< global SCIP settings */
11398  SCIP_STAT* stat, /**< problem statistics */
11399  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11400  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11401  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11402  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11403  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11404  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11405  )
11406 {
11407  SCIP_Real lptimelimit;
11408  SCIP_Bool success;
11409 
11410  assert(lp != NULL);
11411  assert(lp->flushed);
11412  assert(lperror != NULL);
11413 
11414  /* check if a time limit is set, and set time limit for LP solver accordingly */
11415  lptimelimit = SCIPlpiInfinity(lp->lpi);
11416  if( set->istimelimitfinite )
11417  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11418 
11419  success = FALSE;
11420  if( lptimelimit > 0.0 )
11421  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11422 
11423  if( lptimelimit <= 0.0 || !success )
11424  {
11425  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11426  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11427  *timelimit = TRUE;
11428  return SCIP_OKAY;
11429  }
11430  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11431 
11432  /* call appropriate LP algorithm */
11433  switch( lpalgo )
11434  {
11436  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11437  break;
11438 
11440  /* run dual lexicographic simplex if required */
11441  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11442  {
11443  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11444  }
11445  else
11446  {
11447  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11448  }
11449  break;
11450 
11451  case SCIP_LPALGO_BARRIER:
11452  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11453  break;
11454 
11456  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11457  break;
11458 
11459  default:
11460  SCIPerrorMessage("invalid LP algorithm\n");
11461  return SCIP_INVALIDDATA;
11462  }
11463 
11464  if( !(*lperror) )
11465  {
11466  /* check for primal and dual feasibility */
11468 
11469  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11470  }
11471 
11472  return SCIP_OKAY;
11473 }
11474 
11475 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11476  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11477  */
11478 #define MAXNUMTROUBLELPMSGS 10
11479 
11480 /** prints message about numerical trouble
11481  *
11482  * If message has verblevel at most high and display/verblevel is not full,
11483  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11484  * were printed before in the current run.
11485  */
11486 static
11488  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11489  SCIP_SET* set, /**< global SCIP settings */
11490  SCIP_STAT* stat, /**< problem statistics */
11491  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11492  const char* formatstr, /**< message format string */
11493  ... /**< arguments to format string */
11494  )
11495 {
11496  va_list ap;
11497 
11498  assert(verblevel > SCIP_VERBLEVEL_NONE);
11499  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11500  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11501 
11502  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11503  {
11504  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11505  {
11506  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11508  return;
11509 
11510  /* increase count on messages with verblevel high */
11511  ++stat->nnumtroublelpmsgs ;
11512  }
11513 
11514  /* if messages wouldn't be printed, then return already */
11515  if( verblevel > set->disp_verblevel )
11516  return;
11517  }
11518 
11519  /* print common begin of message */
11520  SCIPmessagePrintInfo(messagehdlr,
11521  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11522  stat->nnodes, stat->nlps);
11523 
11524  /* print individual part of message */
11525  va_start(ap, formatstr); /*lint !e838*/
11526  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11527  va_end(ap);
11528 
11529  /* warn that further messages will be suppressed */
11530  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11531  {
11532  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11533  }
11534 
11535  /* print closing new-line */
11536  SCIPmessagePrintInfo(messagehdlr, "\n");
11537 }
11538 
11539 static
11541  SCIP_LP* lp, /**< current LP data */
11542  SCIP_SET* set, /**< global SCIP settings */
11543  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11544  SCIP_STAT* stat, /**< problem statistics */
11545  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11546  SCIP_Bool* success /**< was instability successfully ignored */
11547  )
11548 {
11549  assert(lp != NULL);
11550  assert(set != NULL);
11551 
11552  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11553 
11554  if( *success )
11555  {
11556  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11557  if( !set->lp_checkdualfeas )
11558  lp->dualfeasible = TRUE;
11559  if( !set->lp_checkprimfeas )
11560  lp->primalchecked = TRUE;
11561  }
11562 
11563  return SCIP_OKAY;
11564 }
11565 
11566 #define FEASTOLTIGHTFAC 0.001
11567 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11568 static
11570  SCIP_LP* lp, /**< current LP data */
11571  SCIP_SET* set, /**< global SCIP settings */
11572  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11573  SCIP_STAT* stat, /**< problem statistics */
11574  SCIP_PROB* prob, /**< problem data */
11575  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11576  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11577  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11578  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11579  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11580  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11581  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11582  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11583  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11584  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11585  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11586  )
11587 {
11588  SCIP_Bool success;
11589  SCIP_Bool success2;
11590  SCIP_Bool success3;
11591  SCIP_Bool simplex;
11592  SCIP_Bool itlimishard;
11593  SCIP_Bool usepolishing;
11594 
11595  assert(lp != NULL);
11596  assert(lp->flushed);
11597  assert(set != NULL);
11598  assert(stat != NULL);
11599  assert(lperror != NULL);
11600  assert(timelimit != NULL);
11601 
11602  *lperror = FALSE;
11603 
11604  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11605  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11606  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11607  * SCIP_LP such that we can return a primal ray
11608  */
11609  if( lp->looseobjvalinf > 0 )
11610  {
11611  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11612  return SCIP_ERROR;
11613  }
11614 
11615  /* check, whether we solve with a simplex algorithm */
11616  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11617 
11618  /* check whether the iteration limit is a hard one */
11619  itlimishard = (itlim == harditlim);
11620 
11621  /* check whether solution polishing should be used */
11622  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11623  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11624  {
11625  usepolishing = TRUE;
11626  if( lp->updateintegrality )
11627  {
11628  SCIP_CALL( lpCopyIntegrality(lp, set) );
11629  }
11630  }
11631  else
11632  usepolishing = FALSE;
11633 
11634  /* solve with given settings (usually fast but imprecise) */
11635  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11636  {
11637  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound, &success) );
11638  }
11639  else
11640  {
11641  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11642  }
11643  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11644  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11645  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11646  &success) );
11647  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11648  : SCIPsetBarrierconvtol(set), &success) );
11649  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11650  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11651  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11652  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11653  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11654  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11655  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11656  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11657  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11658  SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11659  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11660  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11661  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11662  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11663 
11664  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11665 
11666  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11667  * optimal without preforming scaling/change tolerances/presolving */
11668  resolve = FALSE;
11669 
11670  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11671  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11672  return SCIP_OKAY;
11673 
11674  if( !set->lp_checkstability )
11675  {
11676  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11677 
11678  if( success )
11679  return SCIP_OKAY;
11680  }
11681 
11682  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11683  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11684  */
11685 
11686  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11687  * do this only if the iteration limit was not exceeded in the last LP solving call
11688  */
11689  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11690  {
11691  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11692  if( success )
11693  {
11694  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11695  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11696 
11697  /* check for stability */
11698  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11699  return SCIP_OKAY;
11700 
11701  if( !set->lp_checkstability )
11702  {
11703  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11704 
11705  if( success )
11706  return SCIP_OKAY;
11707  }
11708  }
11709  }
11710 
11711  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11712  * and go directly to solving the LP from scratch
11713  */
11714  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11715  {
11716  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11717  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11718  if( success )
11719  {
11720  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11721  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11722  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11723 
11724  /* check for stability */
11725  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11726  return SCIP_OKAY;
11727 
11728  if( !set->lp_checkstability )
11729  {
11730  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11731 
11732  if( success )
11733  return SCIP_OKAY;
11734  }
11735 
11736  /* reset scaling */
11737  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11738  assert(success);
11739  }
11740  }
11741 
11742  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11743  * and go directly to solving the LP from scratch */
11744  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11745  {
11746  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11747  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11748  if( success )
11749  {
11750  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11751  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11752  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11753 
11754  /* check for stability */
11755  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11756  return SCIP_OKAY;
11757 
11758  if( !set->lp_checkstability )
11759  {
11760  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11761 
11762  if( success )
11763  return SCIP_OKAY;
11764  }
11765 
11766  /* reset presolving */
11767  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11768  assert(success);
11769  }
11770  }
11771 
11772  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11773  * do this only if the iteration limit was not exceeded in the last LP solving call
11774  */
11775  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11776  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11777  {
11778  success = FALSE;
11779  if( !tightprimfeastol )
11780  {
11781  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11782  }
11783 
11784  success2 = FALSE;
11785  if( !tightdualfeastol )
11786  {
11787  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11788  }
11789 
11790  success3 = FALSE;
11791  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11792  {
11793  SCIP_CALL( lpSetBarrierconvtol(lp, FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set), &success3) );
11794  }
11795 
11796  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11797  if( success || success2 || success3 )
11798  {
11799  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11800  lpalgoName(lpalgo));
11801  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11802 
11803  /* check for stability */
11804  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11805  return SCIP_OKAY;
11806 
11807  if( !set->lp_checkstability )
11808  {
11809  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11810 
11811  if( success )
11812  return SCIP_OKAY;
11813  }
11814 
11815  /* reset feasibility tolerance */
11816  if( !tightprimfeastol )
11817  {
11818  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11819  }
11820  if( !tightdualfeastol )
11821  {
11822  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11823  }
11824  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11825  {
11826  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11827  }
11828  }
11829  }
11830 
11831  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11832  * the given iteration limit might be a soft one to restrict resolving calls only */
11833  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11834 
11835  /* if not already done, solve again from scratch */
11836  if( !fromscratch && simplex )
11837  {
11838  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11839  if( success )
11840  {
11841  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11842  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11843 
11844  /* check for stability */
11845  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11846  return SCIP_OKAY;
11847 
11848  if( !set->lp_checkstability )
11849  {
11850  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11851 
11852  if( success )
11853  return SCIP_OKAY;
11854  }
11855  }
11856  }
11857 
11858  /* solve again, use other simplex this time */
11859  if( simplex )
11860  {
11862  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11863  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11864 
11865  /* check for stability */
11866  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11867  return SCIP_OKAY;
11868 
11869  if( !set->lp_checkstability )
11870  {
11871  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11872 
11873  if( success )
11874  return SCIP_OKAY;
11875  }
11876 
11877  /* solve again with opposite scaling and other simplex */
11878  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11879  if( success )
11880  {
11881  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11882  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11883  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11884 
11885  /* check for stability */
11886  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11887  return SCIP_OKAY;
11888 
11889  if( !set->lp_checkstability )
11890  {
11891  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11892 
11893  if( success )
11894  return SCIP_OKAY;
11895  }
11896 
11897  /* reset scaling */
11898  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11899  assert(success);
11900  }
11901 
11902  /* solve again with opposite presolving and other simplex */
11903  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11904  if( success )
11905  {
11906  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11907  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11908  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11909 
11910  /* check for stability */
11911  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11912  return SCIP_OKAY;
11913 
11914  if( !set->lp_checkstability )
11915  {
11916  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11917 
11918  if( success )
11919  return SCIP_OKAY;
11920  }
11921 
11922  /* reset presolving */
11923  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11924  assert(success);
11925  }
11926 
11927  /* solve again with tighter feasibility tolerance, use other simplex this time */
11928  if( !tightprimfeastol || !tightdualfeastol )
11929  {
11930  success = FALSE;
11931  if( !tightprimfeastol )
11932  {
11933  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11934  }
11935 
11936  success2 = FALSE;
11937  if( !tightdualfeastol )
11938  {
11939  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11940  }
11941 
11942  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11943  if( success || success2 )
11944  {
11945  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11946  lpalgoName(lpalgo));
11947  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11948 
11949  /* check for stability */
11950  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11951  return SCIP_OKAY;
11952 
11953  if( !set->lp_checkstability )
11954  {
11955  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11956 
11957  if( success )
11958  return SCIP_OKAY;
11959  }
11960 
11961  /* reset feasibility tolerance */
11962  if( !tightprimfeastol )
11963  {
11964  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11965  }
11966  if( !tightdualfeastol )
11967  {
11968  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11969  }
11970  SCIP_UNUSED(success);
11971  }
11972  }
11973  }
11974 
11975  /* nothing worked -- exit with an LPERROR */
11976  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11977  *lperror = TRUE;
11978 
11979  return SCIP_OKAY;
11980 }
11981 
11982 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11983 static
11985  SCIP_LP* lp, /**< current LP data */
11986  SCIP_SET* set, /**< global SCIP settings */
11987  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11988  )
11989 {
11990  assert(lp != NULL);
11991  assert(set != NULL);
11992 
11993  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11994  {
11995  if( !lp->adjustlpval && messagehdlr != NULL )
11996  {
11997  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11998  lp->adjustlpval = TRUE;
11999  }
12000  lp->lpobjval = SCIPsetInfinity(set);
12001  }
12002  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
12003  {
12004  if( !lp->adjustlpval && messagehdlr != NULL )
12005  {
12006  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
12007  lp->adjustlpval = TRUE;
12008  }
12009  lp->lpobjval = -SCIPsetInfinity(set);
12010  }
12011 }
12012 
12013 /** solves the LP with the given algorithm and evaluates return status */
12014 static
12016  SCIP_LP* lp, /**< current LP data */
12017  SCIP_SET* set, /**< global SCIP settings */
12018  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12019  SCIP_STAT* stat, /**< problem statistics */
12020  SCIP_PROB* prob, /**< problem data */
12021  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12022  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12023  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12024  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12025  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12026  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12027  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12028  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12029  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12030  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12031  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12032  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12033  )
12034 {
12035  SCIP_Bool solvedprimal;
12036  SCIP_Bool solveddual;
12037  SCIP_Bool timelimit;
12038  int itlim;
12039 
12040  assert(lp != NULL);
12041  assert(lp->flushed);
12042  assert(set != NULL);
12043  assert(stat != NULL);
12044  assert(lperror != NULL);
12045 
12046  checkLinks(lp);
12047 
12048  solvedprimal = FALSE;
12049  solveddual = FALSE;
12050  timelimit = FALSE;
12051 
12052  /* select the basic iteration limit depending on whether this is a resolving call or not */
12053  itlim = ( resolve ? resolveitlim : harditlim );
12054 
12055  SOLVEAGAIN:
12056  /* call simplex */
12057  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12058  keepsol, &timelimit, lperror) );
12059  resolve = FALSE; /* only the first solve should be counted as resolving call */
12060  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12061  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12062 
12063  /* check, if an error occurred */
12064  if( *lperror )
12065  {
12066  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12067  lp->solved = FALSE;
12069  return SCIP_OKAY;
12070  }
12071 
12072  /* check, if a time limit was exceeded */
12073  if( timelimit )
12074  {
12075  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12076  lp->solved = TRUE;
12078  lp->lpobjval = -SCIPsetInfinity(set);
12079  return SCIP_OKAY;
12080  }
12081 
12082  /* only one should return true */
12083  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
12085 
12086  /* evaluate solution status */
12087  if( SCIPlpiIsOptimal(lp->lpi) )
12088  {
12089  assert(lp->primalfeasible);
12090  assert(lp->dualfeasible);
12092  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12093  adjustLPobjval(lp, set, messagehdlr);
12094 
12095  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
12096  {
12097  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12098  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12100  lp->lpobjval = SCIPsetInfinity(set);
12101  }
12102  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12103  * reached if the LP objective value is greater than the cutoff bound
12104  */
12106  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12107  }
12108  else if( SCIPlpiIsObjlimExc(lp->lpi) )
12109  {
12110  assert(!lpCutoffDisabled(set));
12111 
12112 #ifndef NDEBUG
12113  /* the LP solution objective should exceed the limit in this case */
12114  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12115  assert(SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
12116 #endif
12117 
12119  lp->lpobjval = SCIPsetInfinity(set);
12120  }
12121  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12122  {
12123  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12124  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12125  {
12126  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12127  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12128  goto SOLVEAGAIN;
12129  }
12131  lp->lpobjval = SCIPsetInfinity(set);
12132  }
12133  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12134  {
12135  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12136  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12137  {
12138  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12139  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12140  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12141  goto SOLVEAGAIN;
12142  }
12144  lp->lpobjval = -SCIPsetInfinity(set);
12145  }
12146  else if( SCIPlpiIsIterlimExc(lp->lpi) )
12147  {
12148  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12149 
12150  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12151  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12152  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12153  adjustLPobjval(lp, set, NULL);
12154  else
12155  adjustLPobjval(lp, set, messagehdlr);
12156 
12158  }
12159  else if( SCIPlpiIsTimelimExc(lp->lpi) )
12160  {
12161  lp->lpobjval = -SCIPsetInfinity(set);
12163  }
12164  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12165  {
12166  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12167  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12168  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12169  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12170  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12171  goto SOLVEAGAIN;
12172  }
12173  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12174  {
12175  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12176  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12177  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12178  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12179  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12180  goto SOLVEAGAIN;
12181  }
12182  else
12183  {
12184  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12185  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12187  return SCIP_LPERROR;
12188  }
12189 
12190  lp->solved = TRUE;
12191 
12192  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12195 
12196  return SCIP_OKAY;
12197 }
12198 
12199 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12200 static
12202  SCIP_LP* lp, /**< current LP data */
12203  BMS_BLKMEM* blkmem, /**< block memory */
12204  SCIP_SET* set, /**< global SCIP settings */
12205  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12206  SCIP_STAT* stat, /**< problem statistics */
12207  SCIP_PROB* prob, /**< problem data */
12208  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12209  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12210  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12211  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12212  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12213  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12214  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12215  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12216  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12217  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12218  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12219  )
12220 {
12221  SCIP_Bool resolve;
12222  char algo;
12223 
12224  assert(lp != NULL);
12225  assert(set != NULL);
12226  assert(lperror != NULL);
12227 
12228  /* flush changes to the LP solver */
12229  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12230  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12231 
12232  /* select LP algorithm to apply */
12233  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12234  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12235 
12236  switch( algo )
12237  {
12238  case 's':
12239  /* select simplex method */
12240  if( lp->dualfeasible || !lp->primalfeasible )
12241  {
12242  SCIPsetDebugMsg(set, "solving dual LP\n");
12243  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12244  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12245  }
12246  else
12247  {
12248  SCIPsetDebugMsg(set, "solving primal LP\n");
12249  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12250  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12251  }
12252  break;
12253 
12254  case 'p':
12255  SCIPsetDebugMsg(set, "solving primal LP\n");
12256  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12257  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12258  break;
12259 
12260  case 'd':
12261  SCIPsetDebugMsg(set, "solving dual LP\n");
12262  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12263  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12264  break;
12265 
12266  case 'b':
12267  SCIPsetDebugMsg(set, "solving barrier LP\n");
12268  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12269  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12270  break;
12271 
12272  case 'c':
12273  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12274  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12275  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12276  break;
12277 
12278  default:
12279  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12280  return SCIP_PARAMETERWRONGVAL;
12281  }
12282  assert(!(*lperror) || !lp->solved);
12283 
12284  return SCIP_OKAY;
12285 }
12286 
12287 #ifndef NDEBUG
12288 /** checks if the lazy bounds are valid */
12289 static
12291  SCIP_LP* lp, /**< LP data */
12292  SCIP_SET* set /**< global SCIP settings */
12293  )
12294 {
12295  SCIP_COL* col;
12296  int c;
12297 
12298  assert(lp->flushed);
12299 
12300  for( c = 0; c < lp->nlazycols; ++c )
12301  {
12302  col = lp->lazycols[c];
12303 
12304  /* in case lazy bounds are given, check that the primal solution satisfies them */
12305  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12306  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12307  }
12308 }
12309 #else
12310 #define checkLazyBounds(lp, set) /**/
12311 #endif
12312 
12313 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12314  * diving
12315  */
12316 static
12318  SCIP_LP* lp, /**< LP data */
12319  SCIP_SET* set /**< global SCIP settings */
12320  )
12321 {
12322  SCIP_COL* col;
12323  int c;
12324 
12325  assert(lp->nlazycols > 0);
12326 
12327  /* return, if we are in diving, and bounds were already applied
12328  * or if we are not in diving and bounds were not applied
12329  */
12330  if( lp->diving == lp->divinglazyapplied )
12331  return SCIP_OKAY;
12332 
12333  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12334  lp->diving, lp->divinglazyapplied);
12335 
12336  for( c = 0; c < lp->nlazycols; ++c )
12337  {
12338  col = lp->lazycols[c];
12339 
12340  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12341  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12342  {
12343  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12344  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12345  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12346 
12347  /* insert column in the chgcols list (if not already there) */
12348  SCIP_CALL( insertColChgcols(col, set, lp) );
12349 
12350  /* mark bound change in the column */
12351  col->lbchanged = TRUE;
12352  }
12353 
12354  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12355  if( !SCIPsetIsInfinity(set, col->lazyub) )
12356  {
12357  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12358  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12359  || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12360 
12361  /* insert column in the chgcols list (if not already there) */
12362  SCIP_CALL( insertColChgcols(col, set, lp) );
12363 
12364  /* mark bound change in the column */
12365  col->ubchanged = TRUE;
12366  }
12367  }
12368 
12369  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12370  * if not, we just removed them
12371  */
12372  lp->divinglazyapplied = lp->diving;
12373 
12374  return SCIP_OKAY;
12375 }
12376 
12377 /** returns the iteration limit for an LP resolving call */
12378 static
12380  SCIP_SET* set, /**< global SCIP settings */
12381  SCIP_STAT* stat, /**< dynamic problem statistics */
12382  int itlim /**< hard iteration limit */
12383  )
12384 {
12385  /* no limit set or average not yet reliable */
12386  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12387  return itlim;
12388  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12389  if( itlim == -1 )
12390  itlim = INT_MAX;
12391  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12392  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12393  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12394 }
12395 
12396 
12397 
12398 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12400  SCIP_LP* lp, /**< LP data */
12401  SCIP_SET* set, /**< global SCIP settings */
12402  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12403  BMS_BLKMEM* blkmem, /**< block memory buffers */
12404  SCIP_STAT* stat, /**< problem statistics */
12405  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12406  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12407  SCIP_PROB* prob, /**< problem data */
12408  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12409  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12410  * (limit is computed within the method w.r.t. the average LP iterations) */
12411  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12412  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12413  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12414  )
12415 {
12416  SCIP_RETCODE retcode;
12417  SCIP_Bool needprimalray;
12418  SCIP_Bool needdualray;
12419  int harditlim;
12420  int resolveitlim;
12421 
12422  assert(lp != NULL);
12423  assert(prob != NULL);
12424  assert(prob->nvars >= lp->ncols);
12425  assert(lperror != NULL);
12426 
12427  retcode = SCIP_OKAY;
12428  *lperror = FALSE;
12429 
12430  if( lp->flushed && lp->solved )
12431  {
12432  SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
12433  return SCIP_OKAY;
12434  }
12435 
12436  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12437  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12438 
12439  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12440  needprimalray = TRUE;
12441  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12442  || (set->conf_enable && set->conf_useinflp != 'o'));
12443 
12444  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12445  harditlim = (int) MIN(itlim, INT_MAX);
12446  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12447  assert(harditlim == -1 || (resolveitlim <= harditlim));
12448 
12449  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12450  * or removed from the LP (diving was ended)
12451  */
12452  if( lp->nlazycols > 0 )
12453  {
12454  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12455  * first resolve LP?
12456  */
12457  SCIP_CALL( updateLazyBounds(lp, set) );
12458  assert(lp->diving == lp->divinglazyapplied);
12459  }
12460 
12461  /* flush changes to the LP solver */
12462  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12463  assert(lp->flushed);
12464 
12465  /* if the time limit was reached in the last call and the LP did not change, lp->solved is set to TRUE, but we want
12466  * to run again anyway, since there seems to be some time left / the time limit was increased
12467  */
12468  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12469  {
12470  SCIP_Bool* primalfeaspointer;
12471  SCIP_Bool* dualfeaspointer;
12472  SCIP_Bool primalfeasible;
12473  SCIP_Bool dualfeasible;
12474  SCIP_Bool farkasvalid;
12475  SCIP_Bool rayfeasible;
12476  SCIP_Bool tightprimfeastol;
12477  SCIP_Bool tightdualfeastol;
12478  SCIP_Bool fromscratch;
12479  SCIP_Bool wasfromscratch;
12480  SCIP_Longint oldnlps;
12481  int fastmip;
12482 
12483  /* set initial LP solver settings */
12484  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12485  tightprimfeastol = FALSE;
12486  tightdualfeastol = FALSE;
12487  fromscratch = FALSE;
12488  primalfeasible = FALSE;
12489  dualfeasible = FALSE;
12490  wasfromscratch = (stat->nlps == 0);
12491 
12492  SOLVEAGAIN:
12493  /* solve the LP */
12494  oldnlps = stat->nlps;
12495  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12496  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12497  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12498  assert(!(*lperror) || !lp->solved);
12499 
12500  /* check for error */
12501  if( *lperror )
12502  {
12503  retcode = SCIP_OKAY;
12504  goto TERMINATE;
12505  }
12506 
12507  /* evaluate solution status */
12508  switch( SCIPlpGetSolstat(lp) )
12509  {
12511  /* get LP solution and possibly check the solution's feasibility again */
12512  if( set->lp_checkprimfeas )
12513  {
12514  primalfeaspointer = &primalfeasible;
12515  lp->primalchecked = TRUE;
12516  }
12517  else
12518  {
12519  /* believe in the primal feasibility of the LP solution */
12520  primalfeasible = TRUE;
12521  primalfeaspointer = NULL;
12522  lp->primalchecked = FALSE;
12523  }
12524  if( set->lp_checkdualfeas )
12525  {
12526  dualfeaspointer = &dualfeasible;
12527  lp->dualchecked = TRUE;
12528  }
12529  else
12530  {
12531  /* believe in the dual feasibility of the LP solution */
12532  dualfeasible = TRUE;
12533  dualfeaspointer = NULL;
12534  lp->dualchecked = FALSE;
12535  }
12536 
12537  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12538 
12539  /* in debug mode, check that lazy bounds (if present) are not violated */
12540  checkLazyBounds(lp, set);
12541 
12542  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12543  {
12544  /* update ages and remove obsolete columns and rows from LP */
12545  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12546  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12547  {
12548  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12549  }
12550 
12551  if( !lp->solved )
12552  {
12553  /* resolve LP after removing obsolete columns and rows */
12554  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12555  aging = FALSE; /* to prevent infinite loops */
12556  goto SOLVEAGAIN;
12557  }
12558  }
12559  if( !primalfeasible || !dualfeasible )
12560  {
12562 
12563  if( (fastmip > 0) && simplex )
12564  {
12565  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12566  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12567  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
12568  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12569  fastmip = 0;
12570  goto SOLVEAGAIN;
12571  }
12572  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12573  {
12574  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12575  * tolerance
12576  */
12577  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12578  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
12579  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12580  tightprimfeastol = tightprimfeastol || !primalfeasible;
12581  tightdualfeastol = tightdualfeastol || !dualfeasible;
12582  goto SOLVEAGAIN;
12583  }
12584  else if( !fromscratch && !wasfromscratch && simplex )
12585  {
12586  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12587  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12588  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
12589  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12590  fromscratch = TRUE;
12591  goto SOLVEAGAIN;
12592  }
12593  else
12594  {
12595  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12596  lp->solved = FALSE;
12598  *lperror = TRUE;
12599  }
12600  }
12601  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12602  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12603  lp->lpsolstat, lp->cutoffbound);
12604  break;
12605 
12607  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12608  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12609  {
12610  if( SCIPlpiHasDualRay(lp->lpi) )
12611  {
12612  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12613  }
12614  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12615  * with the primal simplex due to numerical problems) - treat this case like an LP error
12616  */
12617  else
12618  {
12619  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12620  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12621  lp->solved = FALSE;
12623  farkasvalid = FALSE;
12624  *lperror = TRUE;
12625  }
12626  }
12627  else
12628  farkasvalid = TRUE;
12629 
12630  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12631  if( !farkasvalid && !(*lperror) )
12632  {
12634 
12635  if( (fastmip > 0) && simplex )
12636  {
12637  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12638  * without FASTMIP
12639  */
12640  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12641  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12642  stat->nnodes, stat->nlps);
12643  fastmip = 0;
12644  goto SOLVEAGAIN;
12645  }
12646  else if( !tightdualfeastol )
12647  {
12648  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12649  * solve again with tighter feasibility tolerance
12650  */
12651  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12652  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12653  stat->nnodes, stat->nlps);
12654  tightdualfeastol = TRUE;
12655  goto SOLVEAGAIN;
12656  }
12657  else if( !fromscratch && simplex )
12658  {
12659  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12660  * from scratch
12661  */
12662  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12663  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12664  stat->nnodes, stat->nlps);
12665  fromscratch = TRUE;
12666  goto SOLVEAGAIN;
12667  }
12668  else
12669  {
12670  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12671  * helped forget about the LP at this node and mark it to be unsolved
12672  */
12673  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12674  lp->solved = FALSE;
12676  *lperror = TRUE;
12677  }
12678  }
12679 
12680  break;
12681 
12683  if( set->lp_checkprimfeas )
12684  {
12685  /* get unbounded LP solution and check the solution's feasibility again */
12686  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12687 
12688  lp->primalchecked = TRUE;
12689  }
12690  else
12691  {
12692  /* get unbounded LP solution believing in the feasibility of the LP solution */
12693  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12694 
12695  primalfeasible = TRUE;
12696  rayfeasible = TRUE;
12697  lp->primalchecked = FALSE;
12698  }
12699 
12700  /* in debug mode, check that lazy bounds (if present) are not violated */
12701  checkLazyBounds(lp, set);
12702 
12703  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12704  primalfeasible, rayfeasible);
12705 
12706  if( !primalfeasible || !rayfeasible )
12707  {
12709 
12710  if( (fastmip > 0) && simplex )
12711  {
12712  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12713  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12714  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
12715  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12716  fastmip = 0;
12717  goto SOLVEAGAIN;
12718  }
12719  else if( !tightprimfeastol )
12720  {
12721  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12722  * tolerance
12723  */
12724  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12725  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again with tighter primal feasibility tolerance\n",
12726  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12727  tightprimfeastol = TRUE;
12728  goto SOLVEAGAIN;
12729  }
12730  else if( !fromscratch && simplex )
12731  {
12732  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12733  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12734  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
12735  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12736  fromscratch = TRUE;
12737  goto SOLVEAGAIN;
12738  }
12739  else
12740  {
12741  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12742  * forget about the LP at this node and mark it to be unsolved
12743  */
12744  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12745  lp->solved = FALSE;
12747  *lperror = TRUE;
12748  }
12749  }
12750 
12751  break;
12752 
12754  assert(!lpCutoffDisabled(set));
12755  /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
12756  * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
12757  * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
12758  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12759  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12760  * FASTMIP and solve again. */
12761  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12762  {
12763  SCIP_LPI* lpi;
12764  SCIP_Real objval;
12765 
12766  lpi = SCIPlpGetLPI(lp);
12767 
12768  assert(lpi != NULL);
12769  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12770  * the assert by using !SCIPsetIsFeasNegative()
12771  */
12772  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12773 
12774  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12775 
12776  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12777  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12778  {
12779  SCIP_Real tmpcutoff;
12780  char tmppricingchar;
12781  SCIP_LPSOLSTAT solstat;
12782 
12783  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12784 
12785  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12786  fromscratch = FALSE;
12787 
12788  /* temporarily disable cutoffbound, which also disables the objective limit */
12789  tmpcutoff = lp->cutoffbound;
12790  lp->cutoffbound = SCIPlpiInfinity(lpi);
12791 
12792  /* set lp pricing strategy to steepest edge */
12793  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12794  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12795 
12796  /* resolve LP with an iteration limit of 1 */
12797  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12798  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12799 
12800  /* reinstall old cutoff bound and lp pricing strategy */
12801  lp->cutoffbound = tmpcutoff;
12802  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12803 
12804  /* get objective value */
12805  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12806 
12807  /* get solution status for the lp */
12808  solstat = SCIPlpGetSolstat(lp);
12809  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12810 
12811  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12812  {
12813  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12814  }
12815 
12816  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12817  fastmip = 0;
12818 
12819  /* the solution is still not exceeding the objective limit and the solving process
12820  * was stopped due to time or iteration limit, solve again with fastmip turned off
12821  */
12822  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12823  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12824  {
12825  assert(!(*lperror));
12826 
12827  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12828  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12829 
12830  /* get objective value */
12831  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12832 
12833  /* get solution status for the lp */
12834  solstat = SCIPlpGetSolstat(lp);
12835 
12836  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12837  }
12838 
12839  /* check for lp errors */
12840  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12841  {
12842  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12843  lp->solved = FALSE;
12845 
12846  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12847  goto TERMINATE;
12848  }
12849 
12850  lp->solved = TRUE;
12851 
12852  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12853  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12854  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12855  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12856  {
12857  /* get LP solution and possibly check the solution's feasibility again */
12858  if( set->lp_checkprimfeas )
12859  {
12860  primalfeaspointer = &primalfeasible;
12861  lp->primalchecked = TRUE;
12862  }
12863  else
12864  {
12865  /* believe in the primal feasibility of the LP solution */
12866  primalfeasible = TRUE;
12867  primalfeaspointer = NULL;
12868  lp->primalchecked = FALSE;
12869  }
12870  if( set->lp_checkdualfeas )
12871  {
12872  dualfeaspointer = &dualfeasible;
12873  lp->dualchecked = TRUE;
12874  }
12875  else
12876  {
12877  /* believe in the dual feasibility of the LP solution */
12878  dualfeasible = TRUE;
12879  dualfeaspointer = NULL;
12880  lp->dualchecked = FALSE;
12881  }
12882 
12883  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12884 
12885  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12886  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12887  {
12888  checkLazyBounds(lp, set);
12889  }
12890 
12891  /* if objective value is larger than the cutoff bound, set solution status to objective
12892  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12893  * this was already done in the lpSolve() method
12894  */
12895  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12896  {
12898  lp->lpobjval = SCIPsetInfinity(set);
12899  }
12900 
12901  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12902  * the cutoffbound; mark the LP to be unsolved
12903  */
12904  if( !primalfeasible || !dualfeasible
12905  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12906  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12907  {
12908  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12909  lp->solved = FALSE;
12911  *lperror = TRUE;
12912  }
12913 
12914  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12915  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12916  lp->lpsolstat, lp->cutoffbound);
12917  }
12918  /* infeasible solution */
12919  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12920  {
12921  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12922 
12923  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12924  {
12925  if( SCIPlpiHasDualRay(lp->lpi) )
12926  {
12927  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12928  }
12929  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12930  * with the primal simplex due to numerical problems) - treat this case like an LP error
12931  */
12932  else
12933  {
12934  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12935  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12936  lp->solved = FALSE;
12938  farkasvalid = FALSE;
12939  *lperror = TRUE;
12940  }
12941  }
12942  else
12943  farkasvalid = TRUE;
12944 
12945  if( !farkasvalid )
12946  {
12948 
12949  if( !tightprimfeastol )
12950  {
12951  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12952  * solve again with tighter feasibility tolerance
12953  */
12954  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12955  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12956  stat->nnodes, stat->nlps);
12957  tightprimfeastol = TRUE;
12958  goto SOLVEAGAIN;
12959  }
12960  else if( simplex )
12961  {
12962  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12963  * from scratch
12964  */
12965  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12966  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12967  stat->nnodes, stat->nlps);
12968  fromscratch = TRUE;
12969  goto SOLVEAGAIN;
12970  }
12971  else
12972  {
12973  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12974  * helped forget about the LP at this node and mark it to be unsolved
12975  */
12976  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12977  lp->solved = FALSE;
12979  *lperror = TRUE;
12980  }
12981  }
12982  }
12983  /* unbounded solution */
12984  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12985  {
12986  if( set->lp_checkprimfeas )
12987  {
12988  /* get unbounded LP solution and check the solution's feasibility again */
12989  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12990 
12991  lp->primalchecked = TRUE;
12992  }
12993  else
12994  {
12995  /* get unbounded LP solution believing in its feasibility */
12996  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12997 
12998  primalfeasible = TRUE;
12999  rayfeasible = TRUE;
13000  lp->primalchecked = FALSE;
13001  }
13002 
13003  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
13004 
13005  /* in debug mode, check that lazy bounds (if present) are not violated */
13006  checkLazyBounds(lp, set);
13007 
13008  if( !primalfeasible || !rayfeasible )
13009  {
13010  /* unbounded solution is infeasible (this can happen due to numerical problems):
13011  * forget about the LP at this node and mark it to be unsolved
13012  *
13013  * @todo: like in the default LP solving evaluation, solve without fastmip,
13014  * with tighter feasibility tolerance and from scratch
13015  */
13016  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
13017  lp->solved = FALSE;
13019  *lperror = TRUE;
13020  }
13021  }
13022 
13023  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
13024  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
13026  }
13027  else
13028  {
13029  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
13030  }
13031  }
13032  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
13033  break;
13034 
13036  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13037  break;
13038 
13040  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13041 
13042  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13043  stat->nclockskipsleft = 0;
13044  if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
13045  {
13046  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13047  "you might consider switching the clock type of SCIP\n");
13048  stat->status = SCIP_STATUS_TIMELIMIT;
13049  }
13050  break;
13051 
13052  case SCIP_LPSOLSTAT_ERROR:
13054  SCIPerrorMessage("error in LP solver\n");
13055  retcode = SCIP_LPERROR;
13056  goto TERMINATE;
13057 
13058  default:
13059  SCIPerrorMessage("unknown LP solution status\n");
13060  retcode = SCIP_ERROR;
13061  goto TERMINATE;
13062  }
13063  }
13064  assert(!(*lperror) || !lp->solved);
13065 
13066  TERMINATE:
13067  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13068  * may happen that we continue to solve from scratch during strong branching */
13069  if( lp->lpifromscratch )
13070  {
13071  SCIP_Bool success;
13072  (void) lpSetFromscratch(lp, FALSE, &success);
13073  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13074  SCIP_UNUSED(success);
13075  }
13076 
13077  return retcode;
13078 }
13079 
13080 /** gets solution status of current LP */
13082  SCIP_LP* lp /**< current LP data */
13083  )
13084 {
13085  assert(lp != NULL);
13086  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
13087 
13088  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13089 }
13090 
13091 /** gets objective value of current LP
13092  *
13093  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13094  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13095  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13096  */
13098  SCIP_LP* lp, /**< current LP data */
13099  SCIP_SET* set, /**< global SCIP settings */
13100  SCIP_PROB* prob /**< problem data */
13101  )
13102 {
13103  assert(lp != NULL);
13104  assert(lp->solved);
13105  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13106  assert(set != NULL);
13107 
13108  if( !lp->flushed )
13109  return SCIP_INVALID;
13110  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
13111  return lp->lpobjval;
13112  else if( lp->looseobjvalinf > 0 )
13113  return -SCIPsetInfinity(set);
13114  else
13115  {
13116  /* recalculate the loose objective value, if needed */
13117  if( !lp->looseobjvalid )
13118  recomputeLooseObjectiveValue(lp, set, prob);
13119 
13120  return lp->lpobjval + lp->looseobjval;
13121  }
13122 }
13123 
13124 /** gets part of objective value of current LP that results from COLUMN variables only */
13126  SCIP_LP* lp /**< current LP data */
13127  )
13128 {
13129  assert(lp != NULL);
13130  assert(lp->solved);
13131 
13132  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13133 }
13134 
13135 /** gets part of objective value of current LP that results from LOOSE variables only */
13137  SCIP_LP* lp, /**< current LP data */
13138  SCIP_SET* set, /**< global SCIP settings */
13139  SCIP_PROB* prob /**< problem data */
13140  )
13141 {
13142  assert(lp != NULL);
13143  assert(lp->solved);
13144  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13145  assert(set != NULL);
13146 
13147  if( !lp->flushed )
13148  return SCIP_INVALID;
13149  else if( lp->looseobjvalinf > 0 )
13150  return -SCIPsetInfinity(set);
13151  else
13152  return getFiniteLooseObjval(lp, set, prob);
13153 }
13154 
13155 /** remembers the current LP objective value as root solution value */
13157  SCIP_LP* lp, /**< current LP data */
13158  SCIP_SET* set, /**< global SCIP settings */
13159  SCIP_PROB* prob /**< problem data */
13160  )
13161 {
13162  assert(lp != NULL);
13163 
13165  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13166 }
13167 
13168 /** invalidates the root LP solution value */
13170  SCIP_LP* lp /**< current LP data */
13171  )
13172 {
13173  assert(lp != NULL);
13174 
13175  lp->rootlpobjval = SCIP_INVALID;
13177 }
13178 
13179 /** recomputes local and global pseudo objective values */
13181  SCIP_LP* lp, /**< current LP data */
13182  SCIP_SET* set, /**< global SCIP settings */
13183  SCIP_PROB* prob /**< problem data */
13184  )
13185 {
13186  SCIP_VAR** vars;
13187  int nvars;
13188  int v;
13189 
13190  assert(lp != NULL);
13191  assert(set != NULL);
13192  assert(prob != NULL);
13193 
13194  vars = prob->vars;
13195  nvars = prob->nvars;
13196 
13197  lp->glbpseudoobjvalinf = 0;
13198  lp->glbpseudoobjval = 0.0;
13199 
13200  lp->pseudoobjvalinf = 0;
13201  lp->pseudoobjval = 0.0;
13202 
13203  for( v = 0; v < nvars; ++v )
13204  {
13205  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13206 
13207  if( SCIPsetIsPositive(set, obj) )
13208  {
13209  /* update the global pseudo objective value */
13210  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13211  ++(lp->glbpseudoobjvalinf);
13212  else
13213  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13214 
13215  /* update the local pseudo objective value */
13216  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13217  ++(lp->pseudoobjvalinf);
13218  else
13219  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13220  }
13221 
13222  if( SCIPsetIsNegative(set, obj) )
13223  {
13224  /* update the global pseudo objective value */
13225  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13226  ++(lp->glbpseudoobjvalinf);
13227  else
13228  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13229 
13230  /* update the local pseudo objective value */
13231  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13232  ++(lp->pseudoobjvalinf);
13233  else
13234  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13235  }
13236  }
13237 
13238  /* the recomputed values are reliable */
13240  lp->glbpseudoobjvalid = TRUE;
13241  lp->relpseudoobjval = lp->pseudoobjval;
13242  lp->pseudoobjvalid = TRUE;
13243 }
13244 
13245 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13246  * global bound
13247  */
13249  SCIP_LP* lp, /**< current LP data */
13250  SCIP_SET* set, /**< global SCIP settings */
13251  SCIP_PROB* prob /**< problem data */
13252  )
13253 {
13254  assert(lp != NULL);
13255  assert(lp->glbpseudoobjvalinf >= 0);
13256  assert(set != NULL);
13257 
13258  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13259  return -SCIPsetInfinity(set);
13260  else
13261  {
13262  /* recalculate the global pseudo solution value, if needed */
13263  if( !lp->glbpseudoobjvalid )
13264  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13265 
13266  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13267  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13268  return -SCIPsetInfinity(set);
13269 
13270  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13271  return SCIPsetInfinity(set);
13272 
13273  return lp->glbpseudoobjval;
13274  }
13275 }
13276 
13277 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13278  * objective function) local bound
13279  */
13281  SCIP_LP* lp, /**< current LP data */
13282  SCIP_SET* set, /**< global SCIP settings */
13283  SCIP_PROB* prob /**< problem data */
13284  )
13285 {
13286  assert(lp != NULL);
13287  assert(lp->pseudoobjvalinf >= 0);
13288  assert(set != NULL);
13289 
13290  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13291  return -SCIPsetInfinity(set);
13292  else
13293  {
13294  /* recalculate the pseudo solution value, if needed */
13295  if( !lp->pseudoobjvalid )
13296  recomputePseudoObjectiveValue(lp, set, prob);
13297 
13298  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13299  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13300  return -SCIPsetInfinity(set);
13301 
13302  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13303  return SCIPsetInfinity(set);
13304 
13305  return lp->pseudoobjval;
13306  }
13307 }
13308 
13309 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13311  SCIP_LP* lp, /**< current LP data */
13312  SCIP_SET* set, /**< global SCIP settings */
13313  SCIP_PROB* prob, /**< problem data */
13314  SCIP_VAR* var, /**< problem variable */
13315  SCIP_Real oldbound, /**< old value for bound */
13316  SCIP_Real newbound, /**< new value for bound */
13317  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13318  )
13319 {
13320  SCIP_Real pseudoobjval;
13321  int pseudoobjvalinf;
13322  SCIP_Real obj;
13323 
13324  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13325  pseudoobjvalinf = lp->pseudoobjvalinf;
13326  obj = SCIPvarGetObj(var);
13327  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13328  {
13329  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13330  pseudoobjvalinf--;
13331  else
13332  pseudoobjval -= oldbound * obj;
13333  assert(pseudoobjvalinf >= 0);
13334  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13335  pseudoobjvalinf++;
13336  else
13337  pseudoobjval += newbound * obj;
13338  }
13339  assert(pseudoobjvalinf >= 0);
13340 
13341  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13342  return -SCIPsetInfinity(set);
13343  else
13344  return pseudoobjval;
13345 }
13346 
13347 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13348  * perform calculations with interval arithmetic to get an exact lower bound
13349  */
13351  SCIP_LP* lp, /**< current LP data */
13352  SCIP_SET* set, /**< global SCIP settings */
13353  SCIP_VAR* var, /**< problem variable */
13354  SCIP_Real oldbound, /**< old value for bound */
13355  SCIP_Real newbound, /**< new value for bound */
13356  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13357  )
13358 {
13359  SCIP_Real pseudoobjval;
13360  int pseudoobjvalinf;
13361  SCIP_Real obj;
13362 
13363  assert(lp->pseudoobjvalid);
13364 
13365  pseudoobjval = lp->pseudoobjval;
13366  pseudoobjvalinf = lp->pseudoobjvalinf;
13367  obj = SCIPvarGetObj(var);
13368  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13369  {
13370  SCIP_INTERVAL objint;
13371  SCIP_INTERVAL bd;
13372  SCIP_INTERVAL prod;
13373  SCIP_INTERVAL psval;
13374 
13375  SCIPintervalSet(&psval, pseudoobjval);
13376  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13377 
13378  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13379  pseudoobjvalinf--;
13380  else
13381  {
13382  SCIPintervalSet(&bd, oldbound);
13383  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13384  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13385  }
13386  assert(pseudoobjvalinf >= 0);
13387  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13388  pseudoobjvalinf++;
13389  else
13390  {
13391  SCIPintervalSet(&bd, newbound);
13392  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13393  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13394  }
13395 
13396  pseudoobjval = SCIPintervalGetInf(psval);
13397  }
13398  assert(pseudoobjvalinf >= 0);
13399 
13400  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13401  return -SCIPsetInfinity(set);
13402  else
13403  return pseudoobjval;
13404 }
13405 
13406 /** compute the objective delta due the new objective coefficient */
13407 static
13409  SCIP_SET* set, /**< global SCIP settings */
13410  SCIP_Real oldobj, /**< old objective value of variable */
13411  SCIP_Real newobj, /**< new objective value of variable */
13412  SCIP_Real lb, /**< lower bound of variable */
13413  SCIP_Real ub, /**< upper bound of variable */
13414  SCIP_Real* deltaval, /**< pointer to store the delta value */
13415  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13416  )
13417 {
13418  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13419  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13420  assert(!SCIPsetIsInfinity(set, lb));
13421  assert(!SCIPsetIsInfinity(set, -ub));
13422  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13423 
13424  (*deltaval) = 0.0;
13425  (*deltainf) = 0;
13426 
13427  if( SCIPsetIsPositive(set, oldobj) )
13428  {
13429  /* sign of objective did not change */
13430  if( SCIPsetIsPositive(set, newobj) )
13431  {
13432  /* if the bound is finite, calculate the deltaval */
13433  if( !SCIPsetIsInfinity(set, -lb) )
13434  (*deltaval) = lb * (newobj - oldobj);
13435  }
13436  /* sign of objective did change, so the best bound does change */
13437  else if( SCIPsetIsNegative(set, newobj) )
13438  {
13439  if( SCIPsetIsInfinity(set, -lb) )
13440  {
13441  /* old best bound was infinite while new one is not */
13442  if( !SCIPsetIsInfinity(set, ub) )
13443  {
13444  (*deltainf) = -1;
13445  (*deltaval) = ub * newobj;
13446  }
13447  }
13448  else
13449  {
13450  /* new best bound is infinite while old one was not */
13451  if( SCIPsetIsInfinity(set, ub) )
13452  {
13453  (*deltainf) = 1;
13454  (*deltaval) = -lb * oldobj;
13455  }
13456  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13457  else
13458  {
13459  (*deltaval) = (ub * newobj) - (lb * oldobj);
13460  }
13461  }
13462  }
13463  /* new objective is 0.0 */
13464  else
13465  {
13466  if( SCIPsetIsInfinity(set, -lb) )
13467  (*deltainf) = -1;
13468  else
13469  (*deltaval) = -lb * oldobj;
13470  }
13471  }
13472  else if( SCIPsetIsNegative(set, oldobj) )
13473  {
13474  /* sign of objective did not change */
13475  if( SCIPsetIsNegative(set, newobj) )
13476  {
13477  /* if the bound is finite, calculate the deltaval */
13478  if( !SCIPsetIsInfinity(set, ub) )
13479  (*deltaval) = ub * (newobj - oldobj);
13480  }
13481  /* sign of objective did change, so the best bound does change */
13482  else if( SCIPsetIsPositive(set, newobj) )
13483  {
13484  if( SCIPsetIsInfinity(set, ub) )
13485  {
13486  /* old best bound was infinite while new one is not */
13487  if( !SCIPsetIsInfinity(set, -lb) )
13488  {
13489  (*deltainf) = -1;
13490  (*deltaval) = lb * newobj;
13491  }
13492  }
13493  else
13494  {
13495  /* new best bound is infinite while old one was not */
13496  if( SCIPsetIsInfinity(set, -lb) )
13497  {
13498  (*deltainf) = 1;
13499  (*deltaval) = -ub * oldobj;
13500  }
13501  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13502  else
13503  {
13504  (*deltaval) = (lb * newobj) - (ub * oldobj);
13505  }
13506  }
13507  }
13508  /* new objective is 0.0 */
13509  else
13510  {
13511  if( SCIPsetIsInfinity(set, ub) )
13512  (*deltainf) = -1;
13513  else
13514  (*deltaval) = -ub * oldobj;
13515  }
13516  }
13517  /* old objective was 0.0 */
13518  else
13519  {
13520  if( SCIPsetIsNegative(set, newobj) )
13521  {
13522  if( SCIPsetIsInfinity(set, ub) )
13523  (*deltainf) = 1;
13524  else
13525  (*deltaval) = ub * newobj;
13526  }
13527  else if( SCIPsetIsPositive(set, newobj) )
13528  {
13529  if( SCIPsetIsInfinity(set, -lb) )
13530  (*deltainf) = 1;
13531  else
13532  (*deltaval) = lb * newobj;
13533  }
13534  }
13535 }
13536 
13537 /** compute the objective delta due the new lower bound */
13538 static
13540  SCIP_SET* set, /**< global SCIP settings */
13541  SCIP_Real obj, /**< objective value of variable */
13542  SCIP_Real oldlb, /**< old lower bound of variable */
13543  SCIP_Real newlb, /**< new lower bound of variable */
13544  SCIP_Real* deltaval, /**< pointer to store the delta value */
13545  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13546  )
13547 {
13548  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13549  assert(!SCIPsetIsInfinity(set, oldlb));
13550  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13551  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13552 
13553  if( SCIPsetIsInfinity(set, -oldlb) )
13554  {
13555  if( !SCIPsetIsInfinity(set, newlb) )
13556  {
13557  (*deltainf) = -1;
13558  (*deltaval) = newlb * obj;
13559  }
13560  else
13561  {
13562  (*deltainf) = 0;
13563  (*deltaval) = 0.0;
13564  }
13565  }
13566  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13567  {
13568  (*deltainf) = 1;
13569  (*deltaval) = -oldlb * obj;
13570  }
13571  else
13572  {
13573  (*deltainf) = 0;
13574  (*deltaval) = obj * (newlb - oldlb);
13575  }
13576 }
13577 
13578 /** compute the objective delta due the new upper bound */
13579 static
13581  SCIP_SET* set, /**< global SCIP settings */
13582  SCIP_Real obj, /**< objective value of variable */
13583  SCIP_Real oldub, /**< old upper bound of variable */
13584  SCIP_Real newub, /**< new upper bound of variable */
13585  SCIP_Real* deltaval, /**< pointer to store the delta value */
13586  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13587  )
13588 {
13589  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13590  assert(!SCIPsetIsInfinity(set, -oldub));
13591  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13592  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13593 
13594  if( SCIPsetIsInfinity(set, oldub) )
13595  {
13596  if( !SCIPsetIsInfinity(set, -newub) )
13597  {
13598  (*deltainf) = -1;
13599  (*deltaval) = newub * obj;
13600  }
13601  else
13602  {
13603  (*deltainf) = 0;
13604  (*deltaval) = 0.0;
13605  }
13606  }
13607  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13608  {
13609  (*deltainf) = 1;
13610  (*deltaval) = -oldub * obj;
13611  }
13612  else
13613  {
13614  (*deltainf) = 0;
13615  (*deltaval) = obj * (newub - oldub);
13616  }
13617 }
13618 
13619 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13620 static
13622  SCIP_LP* lp, /**< current LP data */
13623  SCIP_SET* set, /**< global SCIP settings */
13624  SCIP_VAR* var, /**< problem variable that changed */
13625  SCIP_Real deltaval, /**< delta value in the objective function */
13626  int deltainf, /**< delta value for the number of variables with infinite best bound */
13627  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13628  SCIP_Bool loose, /**< should the loose objective value be updated? */
13629  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13630  )
13631 {
13632  assert(lp != NULL);
13633  assert(lp->looseobjvalinf >= 0);
13634  assert(lp->pseudoobjvalinf >= 0);
13635  assert(lp->glbpseudoobjvalinf >= 0);
13636 
13637  /* update the pseudo objective value */
13638  if( local )
13639  {
13640  lp->pseudoobjvalinf += deltainf;
13641  if( lp->pseudoobjvalid )
13642  {
13643  lp->pseudoobjval += deltaval;
13644 
13645  /* if the absolute value was increased, this is regarded as reliable,
13646  * otherwise, we check whether we can still trust the updated value
13647  */
13648  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13649  lp->relpseudoobjval = lp->pseudoobjval;
13650  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13651  lp->pseudoobjvalid = FALSE;
13652  }
13653 
13654  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13656  loose = TRUE;
13657  }
13658  /* update the loose objective value */
13659  if( loose )
13660  {
13661  lp->looseobjvalinf += deltainf;
13662 
13663  if( deltaval != 0.0 && lp->looseobjvalid )
13664  {
13665  lp->looseobjval += deltaval;
13666 
13667  /* if the absolute value was increased, this is regarded as reliable,
13668  * otherwise, we check whether we can still trust the updated value
13669  */
13670  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13671  lp->rellooseobjval = lp->looseobjval;
13672  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13673  lp->looseobjvalid = FALSE;
13674  }
13675  }
13676  /* update the root pseudo objective values */
13677  if( global )
13678  {
13679  lp->glbpseudoobjvalinf += deltainf;
13680  if( lp->glbpseudoobjvalid )
13681  {
13682  lp->glbpseudoobjval += deltaval;
13683 
13684  /* if the absolute value was increased, this is regarded as reliable,
13685  * otherwise, we check whether we can still trust the updated value
13686  */
13690  lp->glbpseudoobjvalid = FALSE;
13691  }
13692  }
13693 
13694  assert(lp->looseobjvalinf >= 0);
13695  assert(lp->pseudoobjvalinf >= 0);
13696  assert(lp->glbpseudoobjvalinf >= 0);
13697 }
13698 
13699 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13700  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13701  */
13702 static
13704  SCIP_LP* lp, /**< current LP data */
13705  SCIP_SET* set, /**< global SCIP settings */
13706  SCIP_VAR* var, /**< problem variable that changed */
13707  SCIP_Real oldobj, /**< old objective value of variable */
13708  SCIP_Real oldlb, /**< old objective value of variable */
13709  SCIP_Real oldub, /**< old objective value of variable */
13710  SCIP_Real newobj, /**< new objective value of variable */
13711  SCIP_Real newlb, /**< new objective value of variable */
13712  SCIP_Real newub /**< new objective value of variable */
13713  )
13714 {
13715  SCIP_INTERVAL deltaval;
13716  SCIP_INTERVAL bd;
13717  SCIP_INTERVAL obj;
13718  SCIP_INTERVAL prod;
13719  SCIP_INTERVAL psval;
13720  int deltainf;
13721 
13722  assert(lp != NULL);
13723  assert(lp->pseudoobjvalinf >= 0);
13724  assert(lp->looseobjvalinf >= 0);
13725  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13726  assert(!SCIPsetIsInfinity(set, oldlb));
13727  assert(!SCIPsetIsInfinity(set, -oldub));
13728  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13729  assert(!SCIPsetIsInfinity(set, newlb));
13730  assert(!SCIPsetIsInfinity(set, -newub));
13731  assert(var != NULL);
13732 
13734  {
13735  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13736  return SCIP_INVALIDDATA;
13737  }
13738 
13739  assert(SCIPvarGetProbindex(var) >= 0);
13740 
13741  SCIPintervalSet(&deltaval, 0.0);
13742  deltainf = 0;
13743 
13744  /* subtract old pseudo objective value */
13745  if( oldobj > 0.0 )
13746  {
13747  if( SCIPsetIsInfinity(set, -oldlb) )
13748  deltainf--;
13749  else
13750  {
13751  SCIPintervalSet(&bd, oldlb);
13752  SCIPintervalSet(&obj, oldobj);
13753  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13754  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13755  }
13756  }
13757  else if( oldobj < 0.0 )
13758  {
13759  if( SCIPsetIsInfinity(set, oldub) )
13760  deltainf--;
13761  else
13762  {
13763  SCIPintervalSet(&bd, oldub);
13764  SCIPintervalSet(&obj, oldobj);
13765  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13766  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13767  }
13768  }
13769 
13770  /* add new pseudo objective value */
13771  if( newobj > 0.0 )
13772  {
13773  if( SCIPsetIsInfinity(set, -newlb) )
13774  deltainf++;
13775  else
13776  {
13777  SCIPintervalSet(&bd, newlb);
13778  SCIPintervalSet(&obj, newobj);
13779  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13780  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13781  }
13782  }
13783  else if( newobj < 0.0 )
13784  {
13785  if( SCIPsetIsInfinity(set, newub) )
13786  deltainf++;
13787  else
13788  {
13789  SCIPintervalSet(&bd, newub);
13790  SCIPintervalSet(&obj, newobj);
13791  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13792  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13793  }
13794  }
13795 
13796  /* update the pseudo and loose objective values */
13797  SCIPintervalSet(&psval, lp->pseudoobjval);
13798  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13799  lp->pseudoobjval = SCIPintervalGetInf(psval);
13800  lp->pseudoobjvalinf += deltainf;
13802  {
13803  SCIPintervalSet(&psval, lp->looseobjval);
13804  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13805  lp->looseobjval = SCIPintervalGetInf(psval);
13806  lp->looseobjvalinf += deltainf;
13807  }
13808 
13809  assert(lp->pseudoobjvalinf >= 0);
13810  assert(lp->looseobjvalinf >= 0);
13811 
13812  return SCIP_OKAY;
13813 }
13814 
13815 /** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
13817  SCIP_LP* lp, /**< current LP data */
13818  SCIP_SET* set, /**< global SCIP settings */
13819  SCIP_VAR* var, /**< problem variable that changed */
13820  SCIP_Real oldobj, /**< old objective coefficient of variable */
13821  SCIP_Real newobj /**< new objective coefficient of variable */
13822  )
13823 {
13824  assert(set != NULL);
13825  assert(var != NULL);
13826 
13827  if( set->misc_exactsolve )
13828  {
13829  if( oldobj != newobj ) /*lint !e777*/
13830  {
13831  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13832  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13833  }
13834  }
13835  else
13836  {
13837  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13838  {
13839  SCIP_Real deltaval;
13840  int deltainf;
13841 
13843  assert(SCIPvarGetProbindex(var) >= 0);
13844 
13845  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13846  * domain of the variable are the same
13847  */
13848  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13849  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13850 
13851  /* compute the pseudo objective delta due the new objective coefficient */
13852  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13853 
13854  /* update the local pseudo objective value */
13855  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13856 
13857  /* compute the pseudo objective delta due the new objective coefficient */
13858  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13859 
13860  /* update the global pseudo objective value */
13861  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13862  }
13863  }
13864 
13865  return SCIP_OKAY;
13866 }
13867 
13868 
13869 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13871  SCIP_LP* lp, /**< current LP data */
13872  SCIP_SET* set, /**< global SCIP settings */
13873  SCIP_VAR* var, /**< problem variable that changed */
13874  SCIP_Real oldlb, /**< old lower bound of variable */
13875  SCIP_Real newlb /**< new lower bound of variable */
13876  )
13877 {
13878  assert(set != NULL);
13879  assert(var != NULL);
13880 
13881  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13882  {
13883  SCIP_Real deltaval;
13884  int deltainf;
13885 
13886  /* compute the pseudo objective delta due the new lower bound */
13887  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13888 
13889  /* update the root pseudo objective values */
13890  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13891  }
13892 
13893  return SCIP_OKAY;
13894 }
13895 
13896 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13898  SCIP_LP* lp, /**< current LP data */
13899  SCIP_SET* set, /**< global SCIP settings */
13900  SCIP_VAR* var, /**< problem variable that changed */
13901  SCIP_Real oldlb, /**< old lower bound of variable */
13902  SCIP_Real newlb /**< new lower bound of variable */
13903  )
13904 {
13905  assert(set != NULL);
13906  assert(var != NULL);
13907 
13908  if( set->misc_exactsolve )
13909  {
13910  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13911  {
13912  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13913  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13914  }
13915  }
13916  else
13917  {
13918  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13919  {
13920  SCIP_Real deltaval;
13921  int deltainf;
13922 
13924  assert(SCIPvarGetProbindex(var) >= 0);
13925 
13926  /* compute the pseudo objective delta due the new lower bound */
13927  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13928 
13929  /* update the pseudo and loose objective values */
13930  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13931  }
13932  }
13933 
13934  return SCIP_OKAY;
13935 }
13936 
13937 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13939  SCIP_LP* lp, /**< current LP data */
13940  SCIP_SET* set, /**< global SCIP settings */
13941  SCIP_VAR* var, /**< problem variable that changed */
13942  SCIP_Real oldub, /**< old upper bound of variable */
13943  SCIP_Real newub /**< new upper bound of variable */
13944  )
13945 {
13946  assert(set != NULL);
13947  assert(var != NULL);
13948 
13949  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13950  {
13951  SCIP_Real deltaval;
13952  int deltainf;
13953 
13954  /* compute the pseudo objective delta due the new upper bound */
13955  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13956 
13957  /* update the root pseudo objective values */
13958  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13959  }
13960 
13961  return SCIP_OKAY;
13962 }
13963 
13964 /** updates current pseudo objective value for a change in a variable's upper bound */
13966  SCIP_LP* lp, /**< current LP data */
13967  SCIP_SET* set, /**< global SCIP settings */
13968  SCIP_VAR* var, /**< problem variable that changed */
13969  SCIP_Real oldub, /**< old upper bound of variable */
13970  SCIP_Real newub /**< new upper bound of variable */
13971  )
13972 {
13973  assert(set != NULL);
13974  assert(var != NULL);
13975 
13976  if( set->misc_exactsolve )
13977  {
13978  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13979  {
13980  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13981  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13982  }
13983  }
13984  else
13985  {
13986  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13987  {
13988  SCIP_Real deltaval;
13989  int deltainf;
13990 
13992  assert(SCIPvarGetProbindex(var) >= 0);
13993 
13994  /* compute the pseudo objective delta due the new upper bound */
13995  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13996 
13997  /* update the pseudo and loose objective values */
13998  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13999  }
14000  }
14001 
14002  return SCIP_OKAY;
14003 }
14004 
14005 /** informs LP, that given variable was added to the problem */
14007  SCIP_LP* lp, /**< current LP data */
14008  SCIP_SET* set, /**< global SCIP settings */
14009  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
14010  )
14011 {
14012  assert(lp != NULL);
14014  assert(SCIPvarGetProbindex(var) >= 0);
14015 
14016  /* add the variable to the loose objective value sum */
14017  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
14018 
14019  /* update the loose variables counter */
14021  lp->nloosevars++;
14022 
14023  return SCIP_OKAY;
14024 }
14025 
14026 /** informs LP, that given variable is to be deleted from the problem */
14028  SCIP_LP* lp, /**< current LP data */
14029  SCIP_SET* set, /**< global SCIP settings */
14030  SCIP_VAR* var /**< variable that will be deleted from the problem */
14031  )
14032 {
14033  assert(lp != NULL);
14035  assert(SCIPvarGetProbindex(var) >= 0);
14036 
14037  /* subtract the variable from the loose objective value sum */
14038  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
14039 
14040  /* update the loose variables counter */
14042  {
14043  SCIPlpDecNLoosevars(lp);
14044  }
14045 
14046  return SCIP_OKAY;
14047 }
14048 
14049 /** informs LP, that given formerly loose problem variable is now a column variable */
14050 static
14052  SCIP_LP* lp, /**< current LP data */
14053  SCIP_SET* set, /**< global SCIP settings */
14054  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14055  )
14056 {
14057  SCIP_Real obj;
14058  SCIP_Real lb;
14059  SCIP_Real ub;
14060 
14061  assert(lp != NULL);
14062  assert(lp->nloosevars > 0);
14063  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14064  assert(SCIPvarGetProbindex(var) >= 0);
14065  assert(lp->looseobjvalinf >= 0);
14066 
14067  obj = SCIPvarGetObj(var);
14068 
14069  /* update loose objective value */
14070  if( SCIPsetIsPositive(set, obj) )
14071  {
14072  lb = SCIPvarGetLbLocal(var);
14073  if( SCIPsetIsInfinity(set, -lb) )
14074  lp->looseobjvalinf--;
14075  else
14076  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14077  }
14078  else if( SCIPsetIsNegative(set, obj) )
14079  {
14080  ub = SCIPvarGetUbLocal(var);
14081  if( SCIPsetIsInfinity(set, ub) )
14082  lp->looseobjvalinf--;
14083  else
14084  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14085  }
14086 
14087  SCIPlpDecNLoosevars(lp);
14088 
14089  assert(lp->looseobjvalinf >= 0);
14090 
14091  return SCIP_OKAY;
14092 }
14093 
14094 /** informs LP, that given formerly loose problem variable is now a column variable
14095  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14096  */
14097 static
14099  SCIP_LP* lp, /**< current LP data */
14100  SCIP_SET* set, /**< global SCIP settings */
14101  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14102  )
14103 {
14104  SCIP_INTERVAL bd;
14105  SCIP_INTERVAL ob;
14106  SCIP_INTERVAL prod;
14107  SCIP_INTERVAL loose;
14108  SCIP_Real obj;
14109  SCIP_Real lb;
14110  SCIP_Real ub;
14111 
14112  assert(lp != NULL);
14113  assert(lp->nloosevars > 0);
14114  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14115  assert(SCIPvarGetProbindex(var) >= 0);
14116 
14117  obj = SCIPvarGetObj(var);
14118 
14119  SCIPintervalSet(&loose, lp->looseobjval);
14120 
14121  /* update loose objective value corresponding to the deletion of variable */
14122  if( obj > 0.0 )
14123  {
14124  lb = SCIPvarGetLbLocal(var);
14125  if( SCIPsetIsInfinity(set, -lb) )
14126  lp->looseobjvalinf--;
14127  else
14128  {
14129  SCIPintervalSet(&bd, lb);
14130  SCIPintervalSet(&ob, obj);
14131  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14132  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14133  }
14134  }
14135  else if( SCIPsetIsNegative(set, obj) )
14136  {
14137  ub = SCIPvarGetUbLocal(var);
14138  if( SCIPsetIsInfinity(set, ub) )
14139  lp->looseobjvalinf--;
14140  else
14141  {
14142  SCIPintervalSet(&bd, ub);
14143  SCIPintervalSet(&ob, obj);
14144  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14145  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14146  }
14147  }
14148  lp->nloosevars--;
14149 
14150  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14151  if( lp->nloosevars == 0 )
14152  {
14153  assert(lp->looseobjvalinf == 0);
14154  lp->looseobjval = 0.0;
14155  }
14156  else
14157  lp->looseobjval = SCIPintervalGetInf(loose);
14158 
14159  return SCIP_OKAY;
14160 }
14161 
14162 /** informs LP, that given formerly loose problem variable is now a column variable */
14164  SCIP_LP* lp, /**< current LP data */
14165  SCIP_SET* set, /**< global SCIP settings */
14166  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14167  )
14168 {
14169  assert(set != NULL);
14170 
14171  if( set->misc_exactsolve )
14172  {
14173  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
14174  }
14175  else
14176  {
14177  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
14178  }
14179 
14180  return SCIP_OKAY;
14181 }
14182 
14183 /** informs LP, that given formerly column problem variable is now again a loose variable */
14184 static
14186  SCIP_LP* lp, /**< current LP data */
14187  SCIP_SET* set, /**< global SCIP settings */
14188  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14189  )
14190 {
14191  SCIP_Real obj;
14192  SCIP_Real lb;
14193  SCIP_Real ub;
14194 
14195  assert(lp != NULL);
14196  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14197  assert(SCIPvarGetProbindex(var) >= 0);
14198  assert(lp->looseobjvalinf >= 0);
14199 
14200  obj = SCIPvarGetObj(var);
14201 
14202  /* update loose objective value corresponding to the addition of variable */
14203  if( SCIPsetIsPositive(set, obj) )
14204  {
14205  lb = SCIPvarGetLbLocal(var);
14206  if( SCIPsetIsInfinity(set, -lb) )
14207  lp->looseobjvalinf++;
14208  else
14209  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14210  }
14211  else if( SCIPsetIsNegative(set, obj) )
14212  {
14213  ub = SCIPvarGetUbLocal(var);
14214  if( SCIPsetIsInfinity(set, ub) )
14215  lp->looseobjvalinf++;
14216  else
14217  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14218  }
14219  lp->nloosevars++;
14220 
14221  assert(lp->looseobjvalinf >= 0);
14222 
14223  return SCIP_OKAY;
14224 }
14225 
14226 /** informs LP, that given formerly column problem variable is now again a loose variable
14227  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14228  */
14229 static
14231  SCIP_LP* lp, /**< current LP data */
14232  SCIP_SET* set, /**< global SCIP settings */
14233  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14234  )
14235 {
14236  SCIP_INTERVAL bd;
14237  SCIP_INTERVAL ob;
14238  SCIP_INTERVAL prod;
14239  SCIP_INTERVAL loose;
14240  SCIP_Real obj;
14241  SCIP_Real lb;
14242  SCIP_Real ub;
14243 
14244  assert(lp != NULL);
14245  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14246  assert(SCIPvarGetProbindex(var) >= 0);
14247 
14248  obj = SCIPvarGetObj(var);
14249 
14250  SCIPintervalSet(&loose, lp->looseobjval);
14251 
14252  /* update loose objective value corresponding to the deletion of variable */
14253  if( obj > 0.0 )
14254  {
14255  lb = SCIPvarGetLbLocal(var);
14256  if( SCIPsetIsInfinity(set, -lb) )
14257  lp->looseobjvalinf++;
14258  else
14259  {
14260  SCIPintervalSet(&bd, lb);
14261  SCIPintervalSet(&ob, obj);
14262  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14263  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14264  }
14265  }
14266  else if( SCIPsetIsNegative(set, obj) )
14267  {
14268  ub = SCIPvarGetUbLocal(var);
14269  if( SCIPsetIsInfinity(set, ub) )
14270  lp->looseobjvalinf++;
14271  else
14272  {
14273  SCIPintervalSet(&bd, ub);
14274  SCIPintervalSet(&ob, obj);
14275  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14276  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14277  }
14278  }
14279  lp->nloosevars++;
14280 
14281  lp->looseobjval = SCIPintervalGetInf(loose);
14282 
14283  return SCIP_OKAY;
14284 }
14285 
14286 /** informs LP, that given formerly column problem variable is now again a loose variable */
14288  SCIP_LP* lp, /**< current LP data */
14289  SCIP_SET* set, /**< global SCIP settings */
14290  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14291  )
14292 {
14293  assert(set != NULL);
14294 
14295  if( set->misc_exactsolve )
14296  {
14297  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14298  }
14299  else
14300  {
14301  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14302  }
14303 
14304  return SCIP_OKAY;
14305 }
14306 
14307 /** decrease the number of loose variables by one */
14309  SCIP_LP* lp /**< current LP data */
14310  )
14311 {
14312  assert(lp != NULL);
14313  assert(lp->nloosevars > 0);
14314 
14315  lp->nloosevars--;
14316 
14317  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14318  if( lp->nloosevars == 0 )
14319  {
14320  assert(lp->looseobjvalinf == 0);
14321  lp->looseobjval = 0.0;
14322  }
14323 }
14324 
14325 /** stores the LP solution in the columns and rows */
14327  SCIP_LP* lp, /**< current LP data */
14328  SCIP_SET* set, /**< global SCIP settings */
14329  SCIP_STAT* stat, /**< problem statistics */
14330  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14331  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14332  )
14333 {
14334  SCIP_COL** lpicols;
14335  SCIP_ROW** lpirows;
14336  SCIP_Real* primsol;
14337  SCIP_Real* dualsol;
14338  SCIP_Real* activity = NULL;
14339  SCIP_Real* redcost;
14340  SCIP_Real primalbound;
14341  SCIP_Real dualbound;
14342  SCIP_Bool stillprimalfeasible;
14343  SCIP_Bool stilldualfeasible;
14344  int* cstat;
14345  int* rstat;
14346  SCIP_Longint lpcount;
14347  int nlpicols;
14348  int nlpirows;
14349  int c;
14350  int r;
14351 
14352  assert(lp != NULL);
14353  assert(lp->flushed);
14354  assert(lp->solved);
14355  assert(set != NULL);
14356  assert(stat != NULL);
14357  assert(lp->validsollp <= stat->lpcount);
14358 
14359  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14360  * corresponding flag immediately to FALSE to skip all checks
14361  */
14362  if( primalfeasible == NULL )
14363  stillprimalfeasible = FALSE;
14364  else
14365  {
14366  *primalfeasible = TRUE;
14367  stillprimalfeasible = TRUE;
14368  }
14369  if( dualfeasible == NULL )
14370  stilldualfeasible = FALSE;
14371  else
14372  {
14373  *dualfeasible = TRUE;
14374  stilldualfeasible = TRUE;
14375  }
14376 
14377  /* check if the values are already calculated */
14378  if( lp->validsollp == stat->lpcount )
14379  return SCIP_OKAY;
14380  lp->validsollp = stat->lpcount;
14381 
14382  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14383  stat->lpcount, SCIPlpGetSolstat(lp));
14384 
14385  lpicols = lp->lpicols;
14386  lpirows = lp->lpirows;
14387  nlpicols = lp->nlpicols;
14388  nlpirows = lp->nlpirows;
14389  lpcount = stat->lpcount;
14390 
14391  /* get temporary memory */
14392  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14393  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14394 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14395  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14396 #endif
14397  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14398  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14399  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14400 
14401  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14402  if( lp->solisbasic )
14403  {
14404  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14405  }
14406  else
14407  {
14408  BMSclearMemoryArray(cstat, nlpicols);
14409  BMSclearMemoryArray(rstat, nlpirows);
14410  }
14411 
14412  primalbound = 0.0;
14413  dualbound = 0.0;
14414 
14415  /* copy primal solution and reduced costs into columns */
14416  for( c = 0; c < nlpicols; ++c )
14417  {
14418  assert( 0 <= cstat[c] && cstat[c] < 4 );
14419  lpicols[c]->primsol = primsol[c];
14420  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14421  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14422  lpicols[c]->redcost = redcost[c];
14423  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14424  lpicols[c]->validredcostlp = lpcount;
14425  if( stillprimalfeasible )
14426  {
14427  stillprimalfeasible =
14428  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
14429  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
14430  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14431  }
14432  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14433  {
14434  double compslack;
14435 
14436  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14437  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14438  * variables, which would magnify even the tiniest violation in the dual multiplier
14439  */
14440  if( stilldualfeasible )
14441  {
14442  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14443  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14444  }
14445  if( stilldualfeasible )
14446  {
14447  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14448  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14449  }
14450 
14451  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14452  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14453  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14454  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14455  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14456  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14457  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14458  dualfeasible != NULL ? stilldualfeasible : TRUE);
14459  }
14460  else
14461  {
14462  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14463  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14464  {
14465  lpicols[c]->redcost = 0.0;
14466  }
14467 
14468  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14469  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14470  * bounds, its reduced cost must be zero
14471  */
14472  if( stilldualfeasible
14473  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
14474  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14475  if( stilldualfeasible
14476  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
14477  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14478 
14479  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14480  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14481  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14482  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14483  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14484  !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14485  !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14486  dualfeasible != NULL ? stilldualfeasible : TRUE);
14487  }
14488 
14489  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14490  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14491  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14492  */
14493  if( stilldualfeasible )
14494  {
14495  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14496  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14497  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14498  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14499  }
14500  }
14501 
14502  /* copy dual solution and activities into rows */
14503  for( r = 0; r < nlpirows; ++r )
14504  {
14505  assert( 0 <= rstat[r] && rstat[r] < 4 );
14506  lpirows[r]->dualsol = dualsol[r];
14507 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14508  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14509 #else
14510  /* calculate row activity if invalid */
14511  if( lpirows[r]->validactivitylp != stat->lpcount )
14512  SCIProwRecalcLPActivity(lpirows[r], stat);
14513 #endif
14514  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14515  lpirows[r]->validactivitylp = lpcount;
14516  if( stillprimalfeasible )
14517  {
14518  stillprimalfeasible =
14519  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14520  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14521  }
14522  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14523  {
14524  double compslack;
14525 
14526  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14527  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14528  * variables, which would magnify even the tiniest violation in the dual multiplier
14529  */
14530  if( stilldualfeasible )
14531  {
14532  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14533  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14534  }
14535  if( stilldualfeasible )
14536  {
14537  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14538  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14539  }
14540 
14541  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14542  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14543  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14544  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14545  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14546  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14547  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14548  dualfeasible != NULL ? stilldualfeasible : TRUE);
14549  }
14550  else
14551  {
14552  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14553  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14554  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14555  */
14556  if( stilldualfeasible &&
14557  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
14558  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14559  if( stilldualfeasible &&
14560  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
14561  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14562 
14563  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14564  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14565  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14566  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14567  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14568  !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14569  !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14570  dualfeasible != NULL ? stilldualfeasible : TRUE);
14571  }
14572 
14573  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14574  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14575  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14576  */
14577  if( stilldualfeasible )
14578  {
14579  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14580  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14581  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14582  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14583  }
14584  }
14585 
14586  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14587  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14588  * infinity
14589  */
14590  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14591  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14592  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14593  {
14594  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14595  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14596  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14597  }
14598 
14599  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14600  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14601  */
14602  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14603  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14604  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14605  {
14606  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14607  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14608  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14609  }
14610 
14611  if( primalfeasible != NULL )
14612  *primalfeasible = stillprimalfeasible;
14613  if( dualfeasible != NULL )
14614  *dualfeasible = stilldualfeasible;
14615 
14616  /* free temporary memory */
14617  SCIPsetFreeBufferArray(set, &rstat);
14618  SCIPsetFreeBufferArray(set, &cstat);
14619  SCIPsetFreeBufferArray(set, &redcost);
14620 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14621  SCIPsetFreeBufferArray(set, &activity);
14622 #endif
14623  SCIPsetFreeBufferArray(set, &dualsol);
14624  SCIPsetFreeBufferArray(set, &primsol);
14625 
14626  return SCIP_OKAY;
14627 }
14628 
14629 /** stores LP solution with infinite objective value in the columns and rows */
14631  SCIP_LP* lp, /**< current LP data */
14632  SCIP_SET* set, /**< global SCIP settings */
14633  SCIP_STAT* stat, /**< problem statistics */
14634  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14635  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14636  )
14637 {
14638  SCIP_COL** lpicols;
14639  SCIP_ROW** lpirows;
14640  SCIP_Real* primsol;
14641  SCIP_Real* activity;
14642  SCIP_Bool activityvalid = FALSE; /* whether some meaningful values are stored in activity */
14643  SCIP_Real* ray;
14644  SCIP_Real rayobjval;
14645  SCIP_Real rayscale;
14646  SCIP_Longint lpcount;
14647  SCIP_COL* col;
14648  int nlpicols;
14649  int nlpirows;
14650  int c;
14651  int r;
14652 
14653  assert(lp != NULL);
14654  assert(lp->flushed);
14655  assert(lp->solved);
14656  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14657  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14658  assert(set != NULL);
14659  assert(stat != NULL);
14660  assert(lp->validsollp <= stat->lpcount);
14661 
14662  if( primalfeasible != NULL )
14663  *primalfeasible = TRUE;
14664  if( rayfeasible != NULL )
14665  *rayfeasible = TRUE;
14666 
14667  /* check if the values are already calculated */
14668  if( lp->validsollp == stat->lpcount )
14669  return SCIP_OKAY;
14670 
14671  /* check if the LP solver is able to provide a primal unbounded ray */
14672  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14673  {
14674  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14675  return SCIP_LPERROR;
14676  }
14677 
14678  lp->validsollp = stat->lpcount;
14679 
14680  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14681 
14682  /* get temporary memory */
14683  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14684  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14685  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14686 
14687  /* get primal unbounded ray */
14688  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14689 
14690  lpicols = lp->lpicols;
14691  lpirows = lp->lpirows;
14692  nlpicols = lp->nlpicols;
14693  nlpirows = lp->nlpirows;
14694  lpcount = stat->lpcount;
14695 
14696  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14697  rayobjval = 0.0;
14698  for( c = 0; c < nlpicols; ++c )
14699  {
14700  assert(lpicols[c] != NULL);
14701  assert(lpicols[c]->var != NULL);
14702 
14703  col = lpicols[c];
14704 
14705  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14706  if( rayfeasible != NULL )
14707  {
14708  *rayfeasible = *rayfeasible
14709  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14710  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14711  }
14712 
14713  if( ! SCIPsetIsZero(set, ray[c]) )
14714  rayobjval += ray[c] * col->obj;
14715 
14716  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14717  * heuristically try to construct a primal solution.
14718  */
14719  primsol[c] = 0.0;
14720  if( SCIPsetIsFeasZero(set, ray[c]) )
14721  {
14722  /* if the ray component is 0, we try to satisfy as many rows as possible */
14723  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14724  primsol[c] = col->lb;
14725  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14726  primsol[c] = col->ub;
14727  }
14728 
14729  /* make sure we respect the bounds */
14730  primsol[c] = MAX(primsol[c], col->lb);
14731  primsol[c] = MIN(primsol[c], col->ub);
14732 
14733  assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
14734  }
14735 
14736  /* check feasibility of heuristic solution and compute activity */
14737  for( r = 0; r < nlpirows; ++r )
14738  {
14739  SCIP_Real act = 0.0;
14740  SCIP_ROW* row;
14741 
14742  row = lpirows[r];
14743  assert( row != NULL );
14744 
14745  for( c = 0; c < row->nlpcols; ++c )
14746  {
14747  col = row->cols[c];
14748 
14749  assert( col != NULL );
14750  assert( col->lppos >= 0 );
14751  assert( row->linkpos[c] >= 0 );
14752  assert( primsol[col->lppos] < SCIP_INVALID );
14753 
14754  act += row->vals[c] * primsol[col->lppos];
14755  }
14756 
14757  if( row->nunlinked > 0 )
14758  {
14759  for( c = row->nlpcols; c < row->len; ++c )
14760  {
14761  col = row->cols[c];
14762 
14763  assert( col != NULL );
14764 
14765  if( col->lppos >= 0 )
14766  act += row->vals[c] * primsol[col->lppos];
14767  }
14768  }
14769 
14770  /* check feasibility */
14771  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
14772  (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
14773  break;
14774 
14775  activity[r] = act;
14776  }
14777 
14778  /* if heuristic solution is not feasible, try to obtain solution from LPI */
14779  if( r < nlpirows )
14780  {
14781  /* get primal feasible point */
14782 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14783  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14784  activityvalid = TRUE;
14785 #else
14786  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
14787 #endif
14788 
14789  /* determine feasibility status */
14790  if( primalfeasible != NULL )
14791  {
14792  for( c = 0; c < nlpicols; ++c )
14793  {
14794  assert( lpicols[c] != NULL );
14795  assert( lpicols[c]->var != NULL );
14796 
14797  /* check primal feasibility of (finite) primal solution; note that we also ensure that the primal
14798  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14799  */
14800  *primalfeasible = *primalfeasible
14801  && !SCIPsetIsInfinity(set, REALABS(primsol[c]))
14802  && SCIPlpIsFeasGE(set, lp, primsol[c], lpicols[c]->lb)
14803  && SCIPlpIsFeasLE(set, lp, primsol[c], lpicols[c]->ub);
14804  }
14805  }
14806  }
14807  else
14808  {
14809  activityvalid = TRUE; /* previous for() loop computed activity for all rows */
14810  if( primalfeasible != NULL )
14811  *primalfeasible = TRUE;
14812  }
14813 
14814  if( primalfeasible != NULL && !(*primalfeasible) )
14815  {
14816  /* if the finite point is already infeasible, we do not have to add the ray */
14817  rayscale = 0.0;
14818  }
14819  else if( rayfeasible != NULL && !(*rayfeasible) )
14820  {
14821  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14822  rayscale = 0.0;
14823  }
14824  else if( !SCIPsetIsNegative(set, rayobjval) )
14825  {
14826  /* due to numerical problems, the objective of the ray might be nonnegative,
14827  *
14828  * @todo How to check for negative objective value here?
14829  */
14830  if( rayfeasible != NULL )
14831  {
14832  *rayfeasible = FALSE;
14833  }
14834 
14835  rayscale = 0.0;
14836  }
14837  else
14838  {
14839  assert(rayobjval != 0.0);
14840 
14841  /* scale the ray, such that the resulting point has infinite objective value */
14842  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14843  assert(SCIPsetIsFeasPositive(set, rayscale));
14844 
14845  /* ensure that unbounded point does not violate the bounds of the variables */
14846  for( c = 0; c < nlpicols; ++c )
14847  {
14848  if( SCIPsetIsPositive(set, ray[c]) )
14849  {
14850  if( !SCIPsetIsInfinity(set, primsol[c]) )
14851  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14852  /* if the primsol is infinity, as well as the bound, don't scale the ray to 0 */
14853  else
14854  {
14855  assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
14856  rayscale = MIN(rayscale, 1/ray[c]);
14857  }
14858  }
14859  else if( SCIPsetIsNegative(set, ray[c]) )
14860  {
14861  if( !SCIPsetIsInfinity(set, -primsol[c]) )
14862  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14863  /* if the primsol is infinity, as well as the bound, don't scal the ray to 0 */
14864  else
14865  {
14866  assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
14867  rayscale = MIN(rayscale, -1/ray[c]);
14868  }
14869  }
14870 
14871  assert(SCIPsetIsFeasPositive(set, rayscale));
14872  }
14873  }
14874 
14875  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14876 
14877  /* calculate the unbounded point: x' = x + rayscale * ray */
14878  for( c = 0; c < nlpicols; ++c )
14879  {
14880  if( SCIPsetIsZero(set, ray[c]) )
14881  lpicols[c]->primsol = primsol[c];
14882  else
14883  {
14884  SCIP_Real primsolval;
14885  primsolval = primsol[c] + rayscale * ray[c];
14886  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14887  }
14888  lpicols[c]->redcost = SCIP_INVALID;
14889  lpicols[c]->validredcostlp = -1;
14890  }
14891 
14892  /* transfer solution and check feasibility */
14893  for( r = 0; r < nlpirows; ++r )
14894  {
14895  lpirows[r]->dualsol = SCIP_INVALID;
14896  if( activityvalid )
14897  {
14898  /* use activity as computed above or given by LP solver to set activity in row */
14899  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14900  lpirows[r]->validactivitylp = lpcount;
14901  }
14902  else if( lpirows[r]->validactivitylp != lpcount )
14903  {
14904  /* recalculate activity from row if not valid */
14905  SCIProwRecalcLPActivity(lpirows[r], stat);
14906  }
14907 
14908  /* check for feasibility of the rows */
14909  if( primalfeasible != NULL )
14910  *primalfeasible = *primalfeasible
14911  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14912  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14913  }
14914 
14915  /* free temporary memory */
14916  SCIPsetFreeBufferArray(set, &ray);
14917  SCIPsetFreeBufferArray(set, &activity);
14918  SCIPsetFreeBufferArray(set, &primsol);
14919 
14920  return SCIP_OKAY;
14921 }
14922 
14923 /** returns primal ray proving the unboundedness of the current LP */
14925  SCIP_LP* lp, /**< current LP data */
14926  SCIP_SET* set, /**< global SCIP settings */
14927  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14928  * so the size of this array should be at least number of active variables
14929  * (all entries have to be initialized to 0 before) */
14930  )
14931 {
14932  SCIP_COL** lpicols;
14933  SCIP_Real* lpiray;
14934  SCIP_VAR* var;
14935  int nlpicols;
14936  int c;
14937 
14938  assert(lp != NULL);
14939  assert(set != NULL);
14940  assert(ray != NULL);
14941  assert(lp->flushed);
14942  assert(lp->solved);
14943  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14944  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14945 
14946  /* check if the LP solver is able to provide a primal unbounded ray */
14947  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14948  {
14949  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14950  return SCIP_LPERROR;
14951  }
14952 
14953  /* get temporary memory */
14954  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14955 
14956  SCIPsetDebugMsg(set, "getting primal ray values\n");
14957 
14958  /* get primal unbounded ray */
14959  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14960 
14961  lpicols = lp->lpicols;
14962  nlpicols = lp->nlpicols;
14963 
14964  /* store the ray values of active problem variables */
14965  for( c = 0; c < nlpicols; c++ )
14966  {
14967  assert(lpicols[c] != NULL);
14968 
14969  var = lpicols[c]->var;
14970  assert(var != NULL);
14971  assert(SCIPvarGetProbindex(var) != -1);
14972  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14973  }
14974 
14975  SCIPsetFreeBufferArray(set, &lpiray);
14976 
14977  return SCIP_OKAY;
14978 }
14979 
14980 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
14981  * lp/checkfarkas = TRUE.
14982  *
14983  * @note the check will not be performed if @p valid is NULL.
14984  */
14986  SCIP_LP* lp, /**< current LP data */
14987  SCIP_SET* set, /**< global SCIP settings */
14988  SCIP_STAT* stat, /**< problem statistics */
14989  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
14990  )
14991 {
14992  SCIP_COL** lpicols;
14993  SCIP_ROW** lpirows;
14994  SCIP_Real* dualfarkas;
14995  SCIP_Real* farkascoefs;
14996  SCIP_Real farkaslhs;
14997  SCIP_Real maxactivity;
14998  SCIP_Bool checkfarkas;
14999  int nlpicols;
15000  int nlpirows;
15001  int c;
15002  int r;
15003 
15004  assert(lp != NULL);
15005  assert(lp->flushed);
15006  assert(lp->solved);
15007  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
15008  assert(set != NULL);
15009  assert(stat != NULL);
15010  assert(lp->validfarkaslp <= stat->lpcount);
15011 
15012  if( valid != NULL )
15013  *valid = TRUE;
15014 
15015  /* check if the values are already calculated */
15016  if( lp->validfarkaslp == stat->lpcount )
15017  return SCIP_OKAY;
15018  lp->validfarkaslp = stat->lpcount;
15019 
15020  farkascoefs = NULL;
15021  maxactivity = 0.0;
15022  farkaslhs = 0.0;
15023 
15024  checkfarkas = (set->lp_checkfarkas && valid != NULL);
15025 
15026  /* get temporary memory */
15027  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
15028 
15029  if( checkfarkas )
15030  {
15031  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
15032  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
15033  }
15034 
15035  /* get dual Farkas infeasibility proof */
15036  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
15037 
15038  lpicols = lp->lpicols;
15039  lpirows = lp->lpirows;
15040  nlpicols = lp->nlpicols;
15041  nlpirows = lp->nlpirows;
15042 
15043  /* store infeasibility proof in rows */
15044  SCIPsetDebugMsg(set, "LP is infeasible:\n");
15045  for( r = 0; r < nlpirows; ++r )
15046  {
15047  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
15048  lpirows[r]->dualfarkas = dualfarkas[r];
15049  lpirows[r]->dualsol = SCIP_INVALID;
15050  lpirows[r]->activity = 0.0;
15051  lpirows[r]->validactivitylp = -1L;
15052  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
15053 
15054  if( checkfarkas )
15055  {
15056  assert(farkascoefs != NULL);
15057 
15058  /* the infeasibility proof would be invalid if
15059  * (i) dualfarkas[r] > 0 and lhs = -inf
15060  * (ii) dualfarkas[r] < 0 and rhs = inf
15061  * however, due to numerics we accept slightly negative / positive values
15062  */
15063  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15064  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15065  {
15066  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15067  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15068 
15069  if( valid != NULL )
15070  *valid = FALSE;
15071 
15072  goto TERMINATE;
15073  }
15074 
15075  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15076  * within tolerances (see above) but slighty positive / negative
15077  */
15078  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15079  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15080  continue;
15081 
15082  /* iterate over all columns and scale with dual solution */
15083  for( c = 0; c < lpirows[r]->len; c++ )
15084  {
15085  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15086 
15087  if( pos == -1 )
15088  continue;
15089 
15090  assert(pos >= 0 && pos < nlpicols);
15091 
15092  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15093  }
15094 
15095  /* the row contributes with its left-hand side to the proof */
15096  if( dualfarkas[r] > 0.0 )
15097  {
15098  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15099 
15100  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
15101  }
15102  /* the row contributes with its right-hand side to the proof */
15103  else if( dualfarkas[r] < 0.0 )
15104  {
15105  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15106 
15107  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
15108  }
15109  }
15110  }
15111 
15112  /* set columns as invalid */
15113  for( c = 0; c < nlpicols; ++c )
15114  {
15115  lpicols[c]->primsol = SCIP_INVALID;
15116  lpicols[c]->redcost = SCIP_INVALID;
15117  lpicols[c]->validredcostlp = -1L;
15118  lpicols[c]->validfarkaslp = -1L;
15119 
15120  if( checkfarkas )
15121  {
15122  assert(farkascoefs != NULL);
15123  assert(SCIPcolGetLPPos(lpicols[c]) == c);
15124 
15125  /* skip coefficients that are too close to zero */
15126  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
15127  continue;
15128 
15129  /* calculate the maximal activity */
15130  if( farkascoefs[c] > 0.0 )
15131  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
15132  else
15133  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
15134  }
15135  }
15136 
15137  /* check whether the farkasproof is valid
15138  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
15139  * in that case, we declare the Farkas proof to be invalid.
15140  */
15141  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
15142  {
15143  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15144 
15145  if( valid != NULL )
15146  *valid = FALSE;
15147  }
15148 
15149  TERMINATE:
15150  /* free temporary memory */
15151  if( checkfarkas )
15152  SCIPsetFreeBufferArray(set, &farkascoefs);
15153 
15154  SCIPsetFreeBufferArray(set, &dualfarkas);
15155 
15156  return SCIP_OKAY;
15157 }
15158 
15159 /** get number of iterations used in last LP solve */
15161  SCIP_LP* lp, /**< current LP data */
15162  int* iterations /**< pointer to store the iteration count */
15163  )
15164 {
15165  assert(lp != NULL);
15166 
15167  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15168 
15169  return SCIP_OKAY;
15170 }
15171 
15172 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15173  * resets age of non-zero columns and sharp rows
15174  */
15176  SCIP_LP* lp, /**< current LP data */
15177  SCIP_STAT* stat /**< problem statistics */
15178  )
15179 {
15180  SCIP_COL** lpicols;
15181  SCIP_ROW** lpirows;
15182  int nlpicols;
15183  int nlpirows;
15184  int c;
15185  int r;
15186 
15187  assert(lp != NULL);
15188  assert(lp->flushed);
15189  assert(lp->solved);
15190  assert(lp->nlpicols == lp->ncols);
15191  assert(lp->nlpirows == lp->nrows);
15192  assert(stat != NULL);
15193  assert(lp->validsollp == stat->lpcount);
15194 
15195  SCIPdebugMessage("updating LP ages\n");
15196 
15197  lpicols = lp->lpicols;
15198  lpirows = lp->lpirows;
15199  nlpicols = lp->nlpicols;
15200  nlpirows = lp->nlpirows;
15201 
15202  for( c = 0; c < nlpicols; ++c )
15203  {
15204  assert(lpicols[c] == lp->cols[c]);
15205  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15206  lpicols[c]->age++;
15207  else
15208  lpicols[c]->age = 0;
15209  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15210  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15211  }
15212 
15213  for( r = 0; r < nlpirows; ++r )
15214  {
15215  lpirows[r]->nlpsaftercreation++;
15216  assert(lpirows[r] == lp->rows[r]);
15217 
15218  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15219  {
15220  lpirows[r]->age++;
15221  }
15222  else
15223  {
15224  lpirows[r]->activeinlpcounter++;
15225  lpirows[r]->age = 0;
15226  }
15227  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15228  }
15229 
15230  return SCIP_OKAY;
15231 }
15232 
15233 /* deletes the marked columns from the LP and the LP interface */
15234 static
15236  SCIP_LP* lp, /**< current LP data */
15237  SCIP_SET* set, /**< global SCIP settings */
15238  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15239  )
15240 {
15241  SCIP_COL* col;
15242  int ncols;
15243  int c;
15244 
15245  assert(lp != NULL);
15246  assert(lp->flushed);
15247  assert(lp->ncols == lp->nlpicols);
15248  assert(!lp->diving);
15249  assert(coldstat != NULL);
15250  assert(lp->nlazycols <= lp->ncols);
15251 
15252  ncols = lp->ncols;
15253 
15254  /* delete columns in LP solver */
15255  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15256 
15257  /* update LP data respectively */
15258  for( c = 0; c < ncols; ++c )
15259  {
15260  col = lp->cols[c];
15261  assert(col != NULL);
15262  assert(col == lp->lpicols[c]);
15263  assert(coldstat[c] <= c);
15264  col->lppos = coldstat[c];
15265  if( coldstat[c] == -1 )
15266  {
15267  assert(col->removable);
15268 
15269  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15270  * function vector norms
15271  */
15272  markColDeleted(col);
15273  colUpdateDelLP(col, set);
15274  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15275  col->lpdepth = -1;
15276 
15277  lp->cols[c] = NULL;
15278  lp->lpicols[c] = NULL;
15279  lp->ncols--;
15280  lp->nremovablecols--;
15281  lp->nlpicols--;
15282  }
15283  else if( coldstat[c] < c )
15284  {
15285  assert(lp->cols[coldstat[c]] == NULL);
15286  assert(lp->lpicols[coldstat[c]] == NULL);
15287  lp->cols[coldstat[c]] = col;
15288  lp->lpicols[coldstat[c]] = col;
15289  lp->cols[coldstat[c]]->lppos = coldstat[c];
15290  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15291  lp->cols[c] = NULL;
15292  lp->lpicols[c] = NULL;
15293  }
15294  }
15295 
15296  /* remove columns which are deleted from the lazy column array */
15297  c = 0;
15298  while( c < lp->nlazycols )
15299  {
15300  if( lp->lazycols[c]->lpipos < 0 )
15301  {
15302  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15303  lp->nlazycols--;
15304  }
15305  else
15306  c++;
15307  }
15308 
15309  /* mark LP to be unsolved */
15310  if( lp->ncols < ncols )
15311  {
15312  assert(lp->ncols == lp->nlpicols);
15313  assert(lp->nchgcols == 0);
15314  assert(lp->flushed);
15315 
15316  lp->lpifirstchgcol = lp->nlpicols;
15317 
15318  /* mark the current solution invalid */
15319  lp->solved = FALSE;
15320  lp->primalfeasible = FALSE;
15321  lp->primalchecked = FALSE;
15322  lp->lpobjval = SCIP_INVALID;
15324  }
15325 
15326  checkLazyColArray(lp, set);
15327  checkLinks(lp);
15328 
15329  return SCIP_OKAY;
15330 }
15331 
15332 /* deletes the marked rows from the LP and the LP interface */
15333 static
15335  SCIP_LP* lp, /**< current LP data */
15336  BMS_BLKMEM* blkmem, /**< block memory buffers */
15337  SCIP_SET* set, /**< global SCIP settings */
15338  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15339  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15340  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15341  )
15342 {
15343  SCIP_ROW* row;
15344  int nrows;
15345  int r;
15346 
15347  assert(lp != NULL);
15348  assert(lp->flushed);
15349  assert(lp->nrows == lp->nlpirows);
15350  assert(!lp->diving);
15351  assert(rowdstat != NULL);
15352 
15353  nrows = lp->nrows;
15354 
15355  /* delete rows in LP solver */
15356  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15357 
15358  /* update LP data respectively */
15359  for( r = 0; r < nrows; ++r )
15360  {
15361  row = lp->rows[r];
15362  assert(row == lp->lpirows[r]);
15363  assert(rowdstat[r] <= r);
15364  assert(row != NULL);
15365  row->lppos = rowdstat[r];
15366  if( rowdstat[r] == -1 )
15367  {
15368  if( row->removable )
15369  lp->nremovablerows--;
15370 
15371  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15372  markRowDeleted(row);
15373  rowUpdateDelLP(row);
15374  row->lpdepth = -1;
15375 
15376  /* check, if row deletion events are tracked
15377  * if so, issue ROWDELETEDLP event
15378  */
15379  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15380  {
15381  SCIP_EVENT* event;
15382 
15383  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15384  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15385  }
15386 
15387  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15388  SCIProwUnlock(lp->rows[r]);
15389  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15390  assert(lp->lpirows[r] == NULL);
15391  assert(lp->rows[r] == NULL);
15392  lp->nrows--;
15393  lp->nlpirows--;
15394  }
15395  else if( rowdstat[r] < r )
15396  {
15397  assert(lp->rows[rowdstat[r]] == NULL);
15398  assert(lp->lpirows[rowdstat[r]] == NULL);
15399  lp->rows[rowdstat[r]] = row;
15400  lp->lpirows[rowdstat[r]] = row;
15401  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15402  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15403  lp->rows[r] = NULL;
15404  lp->lpirows[r] = NULL;
15405  }
15406  }
15407 
15408  /* mark LP to be unsolved */
15409  if( lp->nrows < nrows )
15410  {
15411  assert(lp->nrows == lp->nlpirows);
15412  assert(lp->nchgrows == 0);
15413  assert(lp->flushed);
15414 
15415  lp->lpifirstchgrow = lp->nlpirows;
15416 
15417  /* mark the current solution invalid */
15418  lp->solved = FALSE;
15419  lp->dualfeasible = FALSE;
15420  lp->dualchecked = FALSE;
15421  lp->lpobjval = SCIP_INVALID;
15423  }
15424 
15425  checkLinks(lp);
15426 
15427  return SCIP_OKAY;
15428 }
15429 
15430 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15431 static
15433  SCIP_LP* lp, /**< current LP data */
15434  SCIP_SET* set, /**< global SCIP settings */
15435  SCIP_STAT* stat, /**< problem statistics */
15436  int firstcol /**< first column to check for clean up */
15437  )
15438 {
15439  SCIP_COL** cols;
15440 #ifndef NDEBUG
15441  SCIP_COL** lpicols;
15442 #endif
15443  int* coldstat;
15444  int ncols;
15445  int ndelcols;
15446  int c;
15447 
15448  assert(lp != NULL);
15449  assert(lp->flushed);
15450  assert(lp->ncols == lp->nlpicols);
15451  assert(lp->nremovablecols <= lp->ncols);
15452  assert(!lp->diving);
15453  assert(set != NULL);
15454  assert(stat != NULL);
15455 
15456  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15457  return SCIP_OKAY;
15458 
15459  ncols = lp->ncols;
15460  cols = lp->cols;
15461 #ifndef NDEBUG
15462  lpicols = lp->lpicols;
15463 #endif
15464 
15465  /* get temporary memory */
15466  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15467 
15468  /* mark obsolete columns to be deleted */
15469  ndelcols = 0;
15470  BMSclearMemoryArray(coldstat, ncols);
15471  for( c = firstcol; c < ncols; ++c )
15472  {
15473  assert(cols[c] == lpicols[c]);
15474  assert(cols[c]->lppos == c);
15475  assert(cols[c]->lpipos == c);
15476  if( cols[c]->removable
15477  && cols[c]->obsoletenode != stat->nnodes /* don't remove column a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
15478  && cols[c]->age > set->lp_colagelimit
15480  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15481  {
15482  assert(cols[c]->primsol == 0.0);
15483  coldstat[c] = 1;
15484  ndelcols++;
15485  cols[c]->obsoletenode = stat->nnodes;
15486  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15487  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15488  }
15489  }
15490 
15491  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15492 
15493  /* delete the marked columns in the LP solver interface, update the LP respectively */
15494  if( ndelcols > 0 )
15495  {
15496  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15497  }
15498  assert(lp->ncols == ncols - ndelcols);
15499 
15500  /* release temporary memory */
15501  SCIPsetFreeBufferArray(set, &coldstat);
15502 
15503  return SCIP_OKAY;
15504 }
15505 
15506 /** removes all basic rows, that are too old, beginning with the given firstrow */
15507 static
15509  SCIP_LP* lp, /**< current LP data */
15510  BMS_BLKMEM* blkmem, /**< block memory buffers */
15511  SCIP_SET* set, /**< global SCIP settings */
15512  SCIP_STAT* stat, /**< problem statistics */
15513  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15514  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15515  int firstrow /**< first row to check for clean up */
15516  )
15517 {
15518  SCIP_ROW** rows;
15519 #ifndef NDEBUG
15520  SCIP_ROW** lpirows;
15521 #endif
15522  int* rowdstat;
15523  int nrows;
15524  int ndelrows;
15525  int r;
15526 
15527  assert(lp != NULL);
15528  assert(lp->flushed);
15529  assert(lp->nrows == lp->nlpirows);
15530  assert(lp->nremovablerows <= lp->nrows);
15531  assert(!lp->diving);
15532  assert(set != NULL);
15533  assert(stat != NULL);
15534 
15535  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15536  return SCIP_OKAY;
15537 
15538  nrows = lp->nrows;
15539  rows = lp->rows;
15540 #ifndef NDEBUG
15541  lpirows = lp->lpirows;
15542 #endif
15543 
15544  /* get temporary memory */
15545  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15546 
15547  /* mark obsolete rows to be deleted */
15548  ndelrows = 0;
15549  BMSclearMemoryArray(rowdstat, nrows);
15550  for( r = firstrow; r < nrows; ++r )
15551  {
15552  assert(rows[r] == lpirows[r]);
15553  assert(rows[r]->lppos == r);
15554  assert(rows[r]->lpipos == r);
15555  if( rows[r]->removable
15556  && rows[r]->obsoletenode != stat->nnodes /* don't remove row a second time from same node (avoid cycling), or a first time if marked nonremovable locally */
15557  && rows[r]->age > set->lp_rowagelimit
15559  {
15560  rowdstat[r] = 1;
15561  ndelrows++;
15562  rows[r]->obsoletenode = stat->nnodes;
15563  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15564  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15565  }
15566  }
15567 
15568  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15569 
15570  /* delete the marked rows in the LP solver interface, update the LP respectively */
15571  if( ndelrows > 0 )
15572  {
15573  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15574  }
15575  assert(lp->nrows == nrows - ndelrows);
15576 
15577  /* release temporary memory */
15578  SCIPsetFreeBufferArray(set, &rowdstat);
15579 
15580  return SCIP_OKAY;
15581 }
15582 
15583 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15585  SCIP_LP* lp, /**< current LP data */
15586  BMS_BLKMEM* blkmem, /**< block memory buffers */
15587  SCIP_SET* set, /**< global SCIP settings */
15588  SCIP_STAT* stat, /**< problem statistics */
15589  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15590  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15591  )
15592 {
15593  assert(lp != NULL);
15594  assert(lp->solved);
15595  assert(!lp->diving);
15597  assert(set != NULL);
15598 
15599  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15600  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15601 
15602  if( lp->firstnewcol < lp->ncols )
15603  {
15604  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15605  }
15606  if( lp->firstnewrow < lp->nrows )
15607  {
15608  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15609  }
15610 
15611  return SCIP_OKAY;
15612 }
15613 
15614 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15616  SCIP_LP* lp, /**< current LP data */
15617  BMS_BLKMEM* blkmem, /**< block memory buffers */
15618  SCIP_SET* set, /**< global SCIP settings */
15619  SCIP_STAT* stat, /**< problem statistics */
15620  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15621  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15622  )
15623 {
15624  assert(lp != NULL);
15625  assert(lp->solved);
15626  assert(!lp->diving);
15628  assert(set != NULL);
15629 
15630  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15631 
15632  if( 0 < lp->ncols )
15633  {
15634  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15635  }
15636  if( 0 < lp->nrows )
15637  {
15638  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15639  }
15640 
15641  return SCIP_OKAY;
15642 }
15643 
15644 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15645 static
15647  SCIP_LP* lp, /**< current LP data */
15648  SCIP_SET* set, /**< global SCIP settings */
15649  SCIP_STAT* stat, /**< problem statistics */
15650  int firstcol /**< first column to check for clean up */
15651  )
15652 {
15653  SCIP_COL** cols;
15654  SCIP_COL** lpicols;
15655  int* coldstat;
15656  int ncols;
15657  int ndelcols;
15658  int c;
15659 
15660  assert(lp != NULL);
15661  assert(lp->flushed);
15662  assert(lp->ncols == lp->nlpicols);
15663  assert(!lp->diving);
15664  assert(stat != NULL);
15665  assert(lp->validsollp == stat->lpcount);
15666  assert(0 <= firstcol && firstcol < lp->ncols);
15667 
15668  if( lp->nremovablecols == 0 || !lp->solisbasic )
15669  return SCIP_OKAY;
15670 
15671  ncols = lp->ncols;
15672  cols = lp->cols;
15673  lpicols = lp->lpicols;
15674 
15675  /* get temporary memory */
15676  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15677 
15678  /* mark unused columns to be deleted */
15679  ndelcols = 0;
15680  BMSclearMemoryArray(coldstat, ncols);
15681  for( c = firstcol; c < ncols; ++c )
15682  {
15683  assert(cols[c] == lpicols[c]);
15684  assert(cols[c]->lppos == c);
15685  assert(cols[c]->lpipos == c);
15686  if( lpicols[c]->removable
15687  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15688  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15689  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15690  {
15691  coldstat[c] = 1;
15692  ndelcols++;
15693  }
15694  }
15695 
15696  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15697 
15698  /* delete the marked columns in the LP solver interface, update the LP respectively */
15699  if( ndelcols > 0 )
15700  {
15701  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15702  }
15703  assert(lp->ncols == ncols - ndelcols);
15704 
15705  /* release temporary memory */
15706  SCIPsetFreeBufferArray(set, &coldstat);
15707 
15708  return SCIP_OKAY;
15709 }
15710 
15711 /** removes all basic rows beginning with the given firstrow */
15712 static
15714  SCIP_LP* lp, /**< current LP data */
15715  BMS_BLKMEM* blkmem, /**< block memory buffers */
15716  SCIP_SET* set, /**< global SCIP settings */
15717  SCIP_STAT* stat, /**< problem statistics */
15718  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15719  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15720  int firstrow /**< first row to check for clean up */
15721  )
15722 {
15723 #ifndef NDEBUG
15724  SCIP_ROW** rows;
15725 #endif
15726  SCIP_ROW** lpirows;
15727  int* rowdstat;
15728  int nrows;
15729  int ndelrows;
15730  int r;
15731 
15732  assert(lp != NULL);
15733  assert(lp->flushed);
15734  assert(lp->ncols == lp->nlpicols);
15735  assert(lp->nrows == lp->nlpirows);
15736  assert(!lp->diving);
15737  assert(stat != NULL);
15738  assert(lp->validsollp == stat->lpcount);
15739  assert(0 <= firstrow && firstrow < lp->nrows);
15740 
15741  if( lp->nremovablerows == 0 || !lp->solisbasic )
15742  return SCIP_OKAY;
15743 
15744 #ifndef NDEBUG
15745  rows = lp->rows;
15746 #endif
15747  nrows = lp->nrows;
15748  lpirows = lp->lpirows;
15749 
15750  /* get temporary memory */
15751  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15752 
15753  /* mark unused rows to be deleted */
15754  ndelrows = 0;
15755  BMSclearMemoryArray(rowdstat, nrows);
15756  for( r = firstrow; r < nrows; ++r )
15757  {
15758  assert(rows[r] == lpirows[r]);
15759  assert(rows[r]->lppos == r);
15760  assert(rows[r]->lpipos == r);
15761  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15762  {
15763  rowdstat[r] = 1;
15764  ndelrows++;
15765  }
15766  }
15767 
15768  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15769 
15770  /* delete the marked rows in the LP solver interface, update the LP respectively */
15771  if( ndelrows > 0 )
15772  {
15773  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15774  }
15775  assert(lp->nrows == nrows - ndelrows);
15776 
15777  /* release temporary memory */
15778  SCIPsetFreeBufferArray(set, &rowdstat);
15779 
15780  return SCIP_OKAY;
15781 }
15782 
15783 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15785  SCIP_LP* lp, /**< current LP data */
15786  BMS_BLKMEM* blkmem, /**< block memory buffers */
15787  SCIP_SET* set, /**< global SCIP settings */
15788  SCIP_STAT* stat, /**< problem statistics */
15789  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15790  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15791  SCIP_Bool root /**< are we at the root node? */
15792  )
15793 {
15794  SCIP_Bool cleanupcols;
15795  SCIP_Bool cleanuprows;
15796 
15797  assert(lp != NULL);
15798  assert(lp->solved);
15799  assert(!lp->diving);
15801  assert(set != NULL);
15802 
15803  /* check, if we want to clean up the columns and rows */
15804  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15805  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15806 
15807  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15808  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15809 
15810  if( cleanupcols && lp->firstnewcol < lp->ncols )
15811  {
15812  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15813  }
15814  if( cleanuprows && lp->firstnewrow < lp->nrows )
15815  {
15816  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15817  }
15818 
15819  return SCIP_OKAY;
15820 }
15821 
15822 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15824  SCIP_LP* lp, /**< current LP data */
15825  BMS_BLKMEM* blkmem, /**< block memory buffers */
15826  SCIP_SET* set, /**< global SCIP settings */
15827  SCIP_STAT* stat, /**< problem statistics */
15828  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15829  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15830  SCIP_Bool root /**< are we at the root node? */
15831  )
15832 {
15833  SCIP_Bool cleanupcols;
15834  SCIP_Bool cleanuprows;
15835 
15836  assert(lp != NULL);
15837  assert(lp->solved);
15838  assert(!lp->diving);
15840  assert(set != NULL);
15841 
15842  /* check, if we want to clean up the columns and rows */
15843  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15844  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15845 
15846  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15847  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15848 
15849  if( cleanupcols && 0 < lp->ncols )
15850  {
15851  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15852  }
15853  if( cleanuprows && 0 < lp->nrows )
15854  {
15855  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15856  }
15857 
15858  return SCIP_OKAY;
15859 }
15860 
15861 /** removes all redundant rows that were added at the current node */
15863  SCIP_LP* lp, /**< current LP data */
15864  BMS_BLKMEM* blkmem, /**< block memory buffers */
15865  SCIP_SET* set, /**< global SCIP settings */
15866  SCIP_STAT* stat, /**< problem statistics */
15867  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15868  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15869  )
15870 {
15871 #ifndef NDEBUG
15872  SCIP_ROW** rows;
15873 #endif
15874  SCIP_ROW** lpirows;
15875  int* rowdstat;
15876  int nrows;
15877  int ndelrows;
15878  int r;
15879 
15880  assert(lp != NULL);
15881  assert(lp->flushed);
15882  assert(lp->ncols == lp->nlpicols);
15883  assert(lp->nrows == lp->nlpirows);
15884  assert(!lp->diving);
15885  assert(stat != NULL);
15886  assert(lp->validsollp == stat->lpcount);
15887  assert(lp->firstnewrow <= lp->nrows);
15888 
15889  if( lp->firstnewrow == lp->nrows )
15890  return SCIP_OKAY;
15891 
15892 #ifndef NDEBUG
15893  rows = lp->rows;
15894 #endif
15895  nrows = lp->nrows;
15896  lpirows = lp->lpirows;
15897 
15898  /* get temporary memory */
15899  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15900 
15901  /* mark redundant rows to be deleted (only delete basic rows!) */
15902  ndelrows = 0;
15903  BMSclearMemoryArray(rowdstat, nrows);
15904  for( r = lp->firstnewrow; r < nrows; ++r )
15905  {
15906  assert(rows[r] == lpirows[r]);
15907  assert(rows[r]->lppos == r);
15908  assert(rows[r]->lpipos == r);
15909  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15910  && SCIProwIsRedundant(lpirows[r], set, stat) )
15911  {
15912  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15913  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15914  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15915  rowdstat[r] = 1;
15916  ndelrows++;
15917  }
15918  }
15919 
15920  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15921 
15922  /* delete the marked rows in the LP solver interface, update the LP respectively */
15923  if( ndelrows > 0 )
15924  {
15925  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15926  }
15927  assert(lp->nrows == nrows - ndelrows);
15928 
15929  /* release temporary memory */
15930  SCIPsetFreeBufferArray(set, &rowdstat);
15931 
15932  return SCIP_OKAY;
15933 }
15934 
15935 /** initiates LP diving */
15937  SCIP_LP* lp, /**< current LP data */
15938  BMS_BLKMEM* blkmem, /**< block memory */
15939  SCIP_SET* set, /**< global SCIP settings */
15940  SCIP_STAT* stat /**< problem statistics */
15941  )
15942 {
15943  int c;
15944  int r;
15945 
15946  assert(lp != NULL);
15947  assert(lp->flushed || !lp->solved);
15948  assert(!lp->diving);
15949  assert(!lp->probing);
15950  assert(lp->divelpistate == NULL);
15951  assert(lp->divelpwasprimfeas);
15952  assert(lp->divelpwasdualfeas);
15953  assert(lp->validsollp <= stat->lpcount);
15954  assert(blkmem != NULL);
15955  assert(set != NULL);
15956  assert(lp->ndivechgsides == 0);
15957 
15958  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15959  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15960 
15961 #ifndef NDEBUG
15962  for( c = 0; c < lp->ncols; ++c )
15963  {
15964  assert(lp->cols[c] != NULL);
15965  assert(lp->cols[c]->var != NULL);
15966  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15967  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15968  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15969  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15970  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15971  }
15972 #endif
15973 
15974  /* save current LPI state (basis information) */
15975  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15977  lp->divelpwasdualfeas = lp->dualfeasible;
15980 
15981  /* save current LP values dependent on the solution */
15982  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15983  assert(lp->storedsolvals != NULL);
15984  if( !set->lp_resolverestore && lp->solved )
15985  {
15986  SCIP_Bool store = TRUE;
15987 
15988  switch ( lp->lpsolstat )
15989  {
15991  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15992  assert(lp->validsollp == stat->lpcount);
15993  break;
15995  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15996  assert(lp->validsollp == stat->lpcount);
15997  break;
16001  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16002  assert(lp->validsollp == stat->lpcount);
16003  break;
16005  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
16006  break;
16008  case SCIP_LPSOLSTAT_ERROR:
16009  default:
16010  store = FALSE;
16011  }
16012 
16013  if ( store )
16014  {
16015  for( c = 0; c < lp->ncols; ++c )
16016  {
16017  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
16018  }
16019  for( r = 0; r < lp->nrows; ++r )
16020  {
16022  }
16023  }
16024  }
16025 
16026  /* store LPI iteration limit */
16028 
16029  /* remember the number of domain changes */
16030  lp->divenolddomchgs = stat->domchgcount;
16031 
16032  /* store current number of rows */
16033  lp->ndivingrows = lp->nrows;
16034 
16035  /* switch to diving mode */
16036  lp->diving = TRUE;
16037 
16038  return SCIP_OKAY;
16039 }
16040 
16041 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
16043  SCIP_LP* lp, /**< current LP data */
16044  BMS_BLKMEM* blkmem, /**< block memory */
16045  SCIP_SET* set, /**< global SCIP settings */
16046  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16047  SCIP_STAT* stat, /**< problem statistics */
16048  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16049  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16050  SCIP_PROB* prob, /**< problem data */
16051  SCIP_VAR** vars, /**< array with all active variables */
16052  int nvars /**< number of active variables */
16053  )
16054 {
16055  SCIP_VAR* var;
16056  int v;
16057 
16058  assert(lp != NULL);
16059  assert(lp->diving);
16060  assert(blkmem != NULL);
16061  assert(nvars == 0 || vars != NULL);
16062 
16063  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16064 
16065  /* reset all columns' objective values and bounds to its original values */
16066  for( v = 0; v < nvars; ++v )
16067  {
16068  var = vars[v];
16069  assert(var != NULL);
16071  {
16072  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
16073  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
16074  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
16075  }
16076  }
16077 
16078  /* remove rows which were added in diving mode */
16079  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16080 
16081  /* undo changes to left hand sides and right hand sides */
16082  while( lp->ndivechgsides > 0 )
16083  {
16084  SCIP_Real oldside;
16085  SCIP_SIDETYPE sidetype;
16086  SCIP_ROW* row;
16087 
16088  lp->ndivechgsides--;
16089  oldside = lp->divechgsides[lp->ndivechgsides];
16090  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16091  row = lp->divechgrows[lp->ndivechgsides];
16092 
16093  if( sidetype == SCIP_SIDETYPE_LEFT )
16094  {
16095  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16096  }
16097  else
16098  {
16099  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16100  }
16101  }
16102 
16103  /* restore LPI iteration limit */
16105 
16106  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16107  * happens
16108  */
16109  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
16111  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16112  lp->divelpwasprimfeas = TRUE;
16113  lp->divelpwasdualfeas = TRUE;
16114  lp->divelpwasprimchecked = TRUE;
16115  lp->divelpwasdualchecked = TRUE;
16116  assert(lp->divelpistate == NULL);
16117 
16118  /* switch to standard (non-diving) mode */
16119  lp->diving = FALSE;
16120  lp->divingobjchg = FALSE;
16121 
16122  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16123  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16124  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16125  * the parameter resolverestore to TRUE
16126  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16127  */
16128  assert(lp->storedsolvals != NULL);
16129  if( lp->storedsolvals->lpissolved
16130  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16131  {
16132  SCIP_Bool lperror;
16133 
16134  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
16135  if( lperror )
16136  {
16137  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16138  lp->resolvelperror = TRUE;
16139  }
16144  {
16145  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16146  "LP was not resolved to a sufficient status after diving\n");
16147  lp->resolvelperror = TRUE;
16148  }
16149  }
16150  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16151  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16152  * re-solve as above can lead to a different LP status
16153  */
16154  else
16155  {
16156  int c;
16157  int r;
16158 
16159  /* if there are lazy bounds, remove them from the LP */
16160  if( lp->nlazycols > 0 )
16161  {
16162  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16163  * first resolve LP?
16164  */
16165  SCIP_CALL( updateLazyBounds(lp, set) );
16166  assert(lp->diving == lp->divinglazyapplied);
16167 
16168  /* flush changes to the LP solver */
16169  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
16170  }
16171 
16172  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
16173  SCIPstatIncrement(stat, set, lpcount);
16174 
16175  /* restore LP solution values in lp data, columns and rows */
16176  if( lp->storedsolvals->lpissolved &&
16183  )
16184  {
16185  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16186 
16187  for( c = 0; c < lp->ncols; ++c )
16188  {
16189  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16190  }
16191  for( r = 0; r < lp->nrows; ++r )
16192  {
16193  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16194  }
16195  }
16196  else
16197  {
16198  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16199  }
16200  }
16201 
16202 #ifndef NDEBUG
16203  {
16204  int c;
16205  for( c = 0; c < lp->ncols; ++c )
16206  {
16207  assert(lp->cols[c] != NULL);
16208  assert(lp->cols[c]->var != NULL);
16209  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16210  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16211  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16212  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16213  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16214  }
16215  }
16216 #endif
16217 
16218  return SCIP_OKAY;
16219 }
16220 
16221 #define DIVESTACKGROWFACT 1.5
16222 
16223 /** records a current row side such that any change will be undone after diving */
16225  SCIP_LP* lp, /**< LP data object */
16226  SCIP_ROW* row, /**< row affected by the change */
16227  SCIP_SIDETYPE sidetype /**< side type */
16228  )
16229 {
16230  assert(lp != NULL);
16231  assert(row != NULL);
16232 
16233  if( lp->ndivechgsides == lp->divechgsidessize )
16234  {
16236  }
16237  assert(lp->ndivechgsides < lp->divechgsidessize);
16238 
16239  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16240  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16241  lp->divechgrows[lp->ndivechgsides] = row;
16242  lp->ndivechgsides++;
16243 
16244  return SCIP_OKAY;
16245 }
16246 
16247 /** informs the LP that probing mode was initiated */
16249  SCIP_LP* lp /**< current LP data */
16250  )
16251 {
16252  assert(lp != NULL);
16253  assert(!lp->probing);
16254  assert(!lp->strongbranching);
16255  assert(!lp->strongbranchprobing);
16256 
16257  lp->probing = TRUE;
16258 
16259  return SCIP_OKAY;
16260 }
16261 
16262 /** informs the LP that probing mode was finished */
16264  SCIP_LP* lp /**< current LP data */
16265  )
16266 {
16267  assert(lp != NULL);
16268  assert(lp->probing);
16269  assert(!lp->strongbranching);
16270  assert(!lp->strongbranchprobing);
16271 
16272  lp->probing = FALSE;
16273 
16274  return SCIP_OKAY;
16275 }
16276 
16277 /** informs the LP that the probing mode is now used for strongbranching */
16279  SCIP_LP* lp /**< current LP data */
16280  )
16281 {
16282  assert(lp != NULL);
16283  assert(lp->probing);
16284  assert(!lp->strongbranching);
16285  assert(!lp->strongbranchprobing);
16286 
16287  lp->strongbranchprobing = TRUE;
16288 }
16289 
16290 /** informs the LP that the probing mode is not used for strongbranching anymore */
16292  SCIP_LP* lp /**< current LP data */
16293  )
16294 {
16295  assert(lp != NULL);
16296  assert(lp->probing);
16297  assert(!lp->strongbranching);
16298  assert(lp->strongbranchprobing);
16299 
16300  lp->strongbranchprobing = FALSE;
16301 }
16302 
16303 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16304  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16305  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16306  * we have only left hand sides):
16307  * min{cx | b <= Ax, lb <= x <= ub}
16308  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16309  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16310  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16311  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16312  */
16313 static
16315  SCIP_LP* lp, /**< current LP data */
16316  SCIP_SET* set, /**< global SCIP settings */
16317  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16318  SCIP_Real* bound /**< result of interval arithmetic minimization */
16319  )
16320 {
16321  SCIP_INTERVAL* yinter;
16322  SCIP_INTERVAL b;
16323  SCIP_INTERVAL ytb;
16324  SCIP_INTERVAL prod;
16325  SCIP_INTERVAL diff;
16326  SCIP_INTERVAL x;
16327  SCIP_INTERVAL minprod;
16328  SCIP_INTERVAL a;
16329  SCIP_ROW* row;
16330  SCIP_COL* col;
16331  SCIP_Real y;
16332  SCIP_Real c;
16333  int i;
16334  int j;
16335 
16336  assert(lp != NULL);
16337  assert(lp->solved);
16338  assert(set != NULL);
16339  assert(bound != NULL);
16340 
16341  /* allocate buffer for storing y in interval arithmetic */
16342  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16343 
16344  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16345  SCIPintervalSet(&ytb, 0.0);
16346  for( j = 0; j < lp->nrows; ++j )
16347  {
16348  row = lp->rows[j];
16349  assert(row != NULL);
16350 
16351  y = (usefarkas ? row->dualfarkas : row->dualsol);
16352 
16353  if( SCIPsetIsFeasPositive(set, y) )
16354  {
16355  SCIPintervalSet(&yinter[j], y);
16356  SCIPintervalSet(&b, row->lhs - row->constant);
16357  }
16358  else if( SCIPsetIsFeasNegative(set, y) )
16359  {
16360  SCIPintervalSet(&yinter[j], y);
16361  SCIPintervalSet(&b, row->rhs - row->constant);
16362  }
16363  else
16364  {
16365  SCIPintervalSet(&yinter[j], 0.0);
16366  SCIPintervalSet(&b, 0.0);
16367  }
16368 
16369  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16370  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16371  }
16372 
16373  /* calculate min{(c^T - y^TA)x} */
16374  SCIPintervalSet(&minprod, 0.0);
16375  for( j = 0; j < lp->ncols; ++j )
16376  {
16377  col = lp->cols[j];
16378  assert(col != NULL);
16379  assert(col->nunlinked == 0);
16380 
16382 
16383  c = usefarkas ? 0.0 : col->obj;
16384  SCIPintervalSet(&diff, c);
16385 
16386  for( i = 0; i < col->nlprows; ++i )
16387  {
16388  assert(col->rows[i] != NULL);
16389  assert(col->rows[i]->lppos >= 0);
16390  assert(col->linkpos[i] >= 0);
16391  SCIPintervalSet(&a, col->vals[i]);
16392  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16393  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16394  }
16395 
16396 #ifndef NDEBUG
16397  for( i = col->nlprows; i < col->len; ++i )
16398  {
16399  assert(col->rows[i] != NULL);
16400  assert(col->rows[i]->lppos == -1);
16401  assert(col->rows[i]->dualsol == 0.0);
16402  assert(col->rows[i]->dualfarkas == 0.0);
16403  assert(col->linkpos[i] >= 0);
16404  }
16405 #endif
16406 
16407  SCIPintervalSetBounds(&x, col->lb, col->ub);
16408  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16409  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16410  }
16411 
16412  /* add y^Tb */
16413  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16414 
16415  /* free buffer for storing y in interval arithmetic */
16416  SCIPsetFreeBufferArray(set, &yinter);
16417 
16418  *bound = SCIPintervalGetInf(minprod);
16419 
16420  return SCIP_OKAY;
16421 }
16422 
16423 /** gets proven lower (dual) bound of last LP solution */
16425  SCIP_LP* lp, /**< current LP data */
16426  SCIP_SET* set, /**< global SCIP settings */
16427  SCIP_Real* bound /**< pointer to store proven dual bound */
16428  )
16429 {
16430  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16431 
16432  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16433 
16434  return SCIP_OKAY;
16435 }
16436 
16437 /** gets proven dual bound of last LP solution */
16439  SCIP_LP* lp, /**< current LP data */
16440  SCIP_SET* set, /**< global SCIP settings */
16441  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16442  )
16443 {
16444  SCIP_Real bound;
16445 
16446  assert(proved != NULL);
16447 
16448  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16449 
16450  *proved = (bound > 0.0);
16451 
16452  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16453 
16454  return SCIP_OKAY;
16455 }
16456 
16457 
16458 
16459 /** writes LP to a file */
16461  SCIP_LP* lp, /**< current LP data */
16462  const char* fname /**< file name */
16463  )
16464 {
16465  assert(lp != NULL);
16466  assert(lp->flushed);
16467  assert(fname != NULL);
16468 
16469  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16470 
16471  return SCIP_OKAY;
16472 }
16473 
16474 /** writes MIP relaxation of the current B&B node to a file */
16476  SCIP_LP* lp, /**< current LP data */
16477  SCIP_SET* set, /**< global SCIP settings */
16478  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16479  const char* fname, /**< file name */
16480  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16481  * troubles with reserved symbols? */
16482  SCIP_Bool origobj, /**< should the original objective function be used? */
16483  SCIP_OBJSENSE objsense, /**< objective sense */
16484  SCIP_Real objscale, /**< objective scaling factor */
16485  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16486  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16487  )
16488 {
16489  FILE* file;
16490  int i;
16491  int j;
16492  char rowname[SCIP_MAXSTRLEN];
16493  SCIP_Real coeff;
16494 
16495  assert(lp != NULL);
16496  assert(lp->flushed);
16497  assert(fname != NULL);
16498 
16499  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16500  file = fopen(fname, "w");
16501  if( file == NULL )
16502  {
16503  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16504  SCIPprintSysError(fname);
16505  return SCIP_FILECREATEERROR;
16506  }
16507 
16508  /* print comments */
16509  if( genericnames )
16510  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16511  else
16512  {
16513  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16514  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16515  }
16516 
16517  if( origobj && objoffset != 0.0 )
16518  {
16519  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16520  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16521  }
16522 
16523  /* print objective function */
16524  /**@note the transformed problem in SCIP is always a minimization problem */
16525  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16526  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16527  else
16528  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16529 
16530  /* print objective */
16531  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16532  j = 0;
16533  for( i = 0; i < lp->ncols; ++i )
16534  {
16535  if( lp->cols[i]->obj != 0.0 )
16536  {
16537  coeff = lp->cols[i]->obj;
16538  if( origobj )
16539  {
16540  coeff *= (SCIP_Real) objsense;
16541  coeff *= objscale;
16542  }
16543 
16544  if( genericnames )
16545  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16546  else
16547  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16548 
16549  ++j;
16550  if( j % 10 == 0 )
16551  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16552  }
16553  }
16554  /* add artificial variable 'objoffset' to transfer objective offset */
16555  if( origobj && objoffset != 0.0 )
16556  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16557 
16558  /* print constraint section */
16559  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16560  for( i = 0; i < lp->nrows; i++ )
16561  {
16562  char type = 'i';
16563 
16564  /* skip removable rows if we want to write them as lazy constraints */
16565  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16566  continue;
16567 
16568  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16569  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16570  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16571  * type 'i' means: lhs and rhs are both infinite */
16572  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16573  type = 'r';
16574  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16575  type = 'l';
16576  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16577  type = 'e';
16578  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16579  type = 'b';
16580 
16581  /* print name of row */
16582  if( genericnames )
16583  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16584  else
16585  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16586 
16587  WRITEROW:
16588  switch( type )
16589  {
16590  case 'r':
16591  case 'l':
16592  case 'e':
16593  if( strlen(rowname) > 0 )
16594  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16595  break;
16596  case 'i':
16597  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16598  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16599  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16600  type = 'b';
16601  /*lint -fallthrough*/
16602  case 'b':
16603  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16604  break;
16605  default:
16606  assert(type == 'B');
16607  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16608  break;
16609  }
16610 
16611  /* print coefficients and variables */
16612  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16613  {
16614  if( genericnames )
16615  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16616  else
16617  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16618 
16619  if( (j+1) % 10 == 0 )
16620  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16621  }
16622 
16623  /* print right hand side */
16624  switch( type )
16625  {
16626  case 'b':
16627  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16628  type = 'B';
16629  goto WRITEROW;
16630  case 'l':
16631  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16632  break;
16633  case 'B':
16634  case 'r':
16635  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16636  break;
16637  case 'e':
16638  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16639  break;
16640  default:
16641  SCIPerrorMessage("Undefined row type!\n");
16642  fclose(file);
16643  return SCIP_ERROR;
16644  }
16645  }
16646 
16647  if ( lazyconss )
16648  {
16649  /* print lazy constraint section */
16650  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16651  for( i = 0; i < lp->nrows; i++ )
16652  {
16653  char type = 'i';
16654 
16655  /* skip non-removable rows if we want to write lazy constraints */
16656  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16657  continue;
16658 
16659  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16660  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16661  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16662  * type 'i' means: lhs and rhs are both infinite */
16663  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16664  type = 'r';
16665  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16666  type = 'l';
16667  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16668  type = 'e';
16669  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16670  type = 'b';
16671 
16672  /* print name of row */
16673  if( genericnames )
16674  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16675  else
16676  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16677 
16678  WRITELAZYROW:
16679  switch( type )
16680  {
16681  case 'r':
16682  case 'l':
16683  case 'e':
16684  if( strlen(rowname) > 0 )
16685  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16686  break;
16687  case 'i':
16688  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16689  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16690  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16691  type = 'b';
16692  /*lint -fallthrough*/
16693  case 'b':
16694  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16695  break;
16696  default:
16697  assert(type == 'B');
16698  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16699  break;
16700  }
16701 
16702  /* print coefficients and variables */
16703  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16704  {
16705  if( genericnames )
16706  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16707  else
16708  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16709 
16710  if( (j+1) % 10 == 0 )
16711  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16712  }
16713 
16714  /* print right hand side */
16715  switch( type )
16716  {
16717  case 'b':
16718  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16719  type = 'B';
16720  goto WRITELAZYROW;
16721  case 'l':
16722  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16723  break;
16724  case 'B':
16725  case 'r':
16726  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16727  break;
16728  case 'e':
16729  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16730  break;
16731  default:
16732  SCIPerrorMessage("Undefined row type!\n");
16733  fclose(file);
16734  return SCIP_ERROR;
16735  }
16736  }
16737  }
16738 
16739  /* print variable bounds */
16740  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16741  for( i = 0; i < lp->ncols; ++i )
16742  {
16743  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16744  {
16745  /* print lower bound as far this one is not infinity */
16746  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16747  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16748 
16749  /* print variable name */
16750  if( genericnames )
16751  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16752  else
16753  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16754 
16755  /* print upper bound as far this one is not infinity */
16756  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16757  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16758  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16759  }
16760  }
16761  if( origobj && objoffset != 0.0 )
16762  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16763 
16764  /* print integer variables */
16765  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16766  j = 0;
16767  for( i = 0; i < lp->ncols; ++i )
16768  {
16769  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16770  {
16771  /* print variable name */
16772  if( genericnames )
16773  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16774  else
16775  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16776 
16777  j++;
16778  if( j % 10 == 0 )
16779  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16780  }
16781  }
16782 
16783  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16784  fclose(file);
16785 
16786  return SCIP_OKAY;
16787 }
16788 
16789 /*
16790  * simple functions implemented as defines
16791  */
16792 
16793 /* In debug mode, the following methods are implemented as function calls to ensure
16794  * type validity.
16795  * In optimized mode, the methods are implemented as defines to improve performance.
16796  * However, we want to have them in the library anyways, so we have to undef the defines.
16797  */
16798 
16799 #undef SCIPcolGetObj
16800 #undef SCIPcolGetLb
16801 #undef SCIPcolGetUb
16802 #undef SCIPcolGetBestBound
16803 #undef SCIPcolGetPrimsol
16804 #undef SCIPcolGetMinPrimsol
16805 #undef SCIPcolGetMaxPrimsol
16806 #undef SCIPcolGetBasisStatus
16807 #undef SCIPcolGetVar
16808 #undef SCIPcolGetIndex
16809 #undef SCIPcolGetVarProbindex
16810 #undef SCIPcolIsIntegral
16811 #undef SCIPcolIsRemovable
16812 #undef SCIPcolGetLPPos
16813 #undef SCIPcolGetLPDepth
16814 #undef SCIPcolIsInLP
16815 #undef SCIPcolGetNNonz
16816 #undef SCIPcolGetNLPNonz
16817 #undef SCIPcolGetRows
16818 #undef SCIPcolGetVals
16819 #undef SCIPcolGetStrongbranchNode
16820 #undef SCIPcolGetNStrongbranchs
16821 #undef SCIPcolGetAge
16822 #undef SCIPboundtypeOpposite
16823 #undef SCIProwGetNNonz
16824 #undef SCIProwGetNLPNonz
16825 #undef SCIProwGetCols
16826 #undef SCIProwGetVals
16827 #undef SCIProwGetConstant
16828 #undef SCIProwGetNorm
16829 #undef SCIProwGetSumNorm
16830 #undef SCIProwGetLhs
16831 #undef SCIProwGetRhs
16832 #undef SCIProwGetDualsol
16833 #undef SCIProwGetDualfarkas
16834 #undef SCIProwGetBasisStatus
16835 #undef SCIProwGetName
16836 #undef SCIProwGetIndex
16837 #undef SCIProwGetAge
16838 #undef SCIProwGetRank
16839 #undef SCIProwIsIntegral
16840 #undef SCIProwIsLocal
16841 #undef SCIProwIsModifiable
16842 #undef SCIProwIsRemovable
16843 #undef SCIProwGetOrigintype
16844 #undef SCIProwGetOriginCons
16845 #undef SCIProwGetOriginConshdlr
16846 #undef SCIProwGetOriginSepa
16847 #undef SCIProwIsInGlobalCutpool
16848 #undef SCIProwGetLPPos
16849 #undef SCIProwGetLPDepth
16850 #undef SCIProwIsInLP
16851 #undef SCIProwGetActiveLPCount
16852 #undef SCIProwGetNLPsAfterCreation
16853 #undef SCIProwChgRank
16854 #undef SCIPlpGetCols
16855 #undef SCIPlpGetNCols
16856 #undef SCIPlpGetRows
16857 #undef SCIPlpGetNRows
16858 #undef SCIPlpGetNewcols
16859 #undef SCIPlpGetNNewcols
16860 #undef SCIPlpGetNewrows
16861 #undef SCIPlpGetNNewrows
16862 #undef SCIPlpGetObjNorm
16863 #undef SCIPlpGetRootObjval
16864 #undef SCIPlpGetRootColumnObjval
16865 #undef SCIPlpGetRootLooseObjval
16866 #undef SCIPlpGetLPI
16867 #undef SCIPlpSetIsRelax
16868 #undef SCIPlpIsRelax
16869 #undef SCIPlpIsSolved
16870 #undef SCIPlpIsSolBasic
16871 #undef SCIPlpDiving
16872 #undef SCIPlpDivingObjChanged
16873 #undef SCIPlpMarkDivingObjChanged
16874 #undef SCIPlpUnmarkDivingObjChanged
16875 #undef SCIPlpDivingRowsChanged
16876 #undef SCIPlpIsFeasEQ
16877 #undef SCIPlpIsFeasLT
16878 #undef SCIPlpIsFeasLE
16879 #undef SCIPlpIsFeasGT
16880 #undef SCIPlpIsFeasGE
16881 #undef SCIPlpIsFeasZero
16882 #undef SCIPlpIsFeasPositive
16883 #undef SCIPlpIsFeasNegative
16884 
16885 /** gets objective value of column */
16887  SCIP_COL* col /**< LP column */
16888  )
16889 {
16890  assert(col != NULL);
16891 
16892  return col->obj;
16893 }
16894 
16895 /** gets lower bound of column */
16897  SCIP_COL* col /**< LP column */
16898  )
16899 {
16900  assert(col != NULL);
16901 
16902  return col->lb;
16903 }
16904 
16905 /** gets upper bound of column */
16907  SCIP_COL* col /**< LP column */
16908  )
16909 {
16910  assert(col != NULL);
16911 
16912  return col->ub;
16913 }
16914 
16915 /** gets best bound of column with respect to the objective function */
16917  SCIP_COL* col /**< LP column */
16918  )
16919 {
16920  assert(col != NULL);
16921 
16922  if( col->obj >= 0.0 )
16923  return col->lb;
16924  else
16925  return col->ub;
16926 }
16927 
16928 /** gets the primal LP solution of a column */
16930  SCIP_COL* col /**< LP column */
16931  )
16932 {
16933  assert(col != NULL);
16934 
16935  if( col->lppos >= 0 )
16936  return col->primsol;
16937  else
16938  return 0.0;
16939 }
16940 
16941 /** gets the minimal LP solution value, this column ever assumed */
16943  SCIP_COL* col /**< LP column */
16944  )
16945 {
16946  assert(col != NULL);
16947 
16948  return col->minprimsol;
16949 }
16950 
16951 /** gets the maximal LP solution value, this column ever assumed */
16953  SCIP_COL* col /**< LP column */
16954  )
16955 {
16956  assert(col != NULL);
16957 
16958  return col->maxprimsol;
16959 }
16960 
16961 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16962  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16963  */
16965  SCIP_COL* col /**< LP column */
16966  )
16967 {
16968  assert(col != NULL);
16969  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16970 
16971  return (SCIP_BASESTAT)col->basisstatus;
16972 }
16973 
16974 /** gets variable this column represents */
16976  SCIP_COL* col /**< LP column */
16977  )
16978 {
16979  assert(col != NULL);
16980 
16981  return col->var;
16982 }
16983 
16984 /** gets unique index of col */
16986  SCIP_COL* col /**< LP col */
16987  )
16988 {
16989  assert(col != NULL);
16990 
16991  return col->index;
16992 }
16993 
16994 /** gets probindex of corresponding variable */
16996  SCIP_COL* col /**< LP col */
16997  )
16998 {
16999  assert(col != NULL);
17000 
17001  return col->var_probindex;
17002 }
17003 
17004 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
17006  SCIP_COL* col /**< LP column */
17007  )
17008 {
17009  assert(col != NULL);
17010  assert(SCIPvarIsIntegral(col->var) == col->integral);
17011 
17012  return col->integral;
17013 }
17014 
17015 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
17017  SCIP_COL* col /**< LP column */
17018  )
17019 {
17020  assert(col != NULL);
17021 
17022  return col->removable;
17023 }
17024 
17025 /** gets position of column in current LP, or -1 if it is not in LP */
17027  SCIP_COL* col /**< LP column */
17028  )
17029 {
17030  assert(col != NULL);
17031  assert((col->lppos == -1) == (col->lpdepth == -1));
17032 
17033  return col->lppos;
17034 }
17035 
17036 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
17038  SCIP_COL* col /**< LP column */
17039  )
17040 {
17041  assert(col != NULL);
17042  assert((col->lppos == -1) == (col->lpdepth == -1));
17043 
17044  return col->lpdepth;
17045 }
17046 
17047 /** returns TRUE iff column is member of current LP */
17049  SCIP_COL* col /**< LP column */
17050  )
17051 {
17052  assert(col != NULL);
17053  assert((col->lppos == -1) == (col->lpdepth == -1));
17054 
17055  return (col->lppos >= 0);
17056 }
17057 
17058 /** get number of nonzero entries in column vector */
17060  SCIP_COL* col /**< LP column */
17061  )
17062 {
17063  assert(col != NULL);
17064 
17065  return col->len;
17066 }
17067 
17068 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
17069  *
17070  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17071  * that is in the current LP and the LP was solved, or a column that was in a solved LP and didn't change afterwards
17072  */
17074  SCIP_COL* col /**< LP column */
17075  )
17076 {
17077  assert(col != NULL);
17078  assert(col->nunlinked == 0);
17079 
17080  return col->nlprows;
17081 }
17082 
17083 /** gets array with rows of nonzero entries */
17085  SCIP_COL* col /**< LP column */
17086  )
17087 {
17088  assert(col != NULL);
17089 
17090  return col->rows;
17091 }
17092 
17093 /** gets array with coefficients of nonzero entries */
17095  SCIP_COL* col /**< LP column */
17096  )
17097 {
17098  assert(col != NULL);
17099 
17100  return col->vals;
17101 }
17102 
17103 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
17104  * given column, or -1 if strong branching was never applied to the column in current run
17105  */
17107  SCIP_COL* col /**< LP column */
17108  )
17109 {
17110  assert(col != NULL);
17111 
17112  return col->sbnode;
17113 }
17114 
17115 /** gets number of times, strong branching was applied in current run on the given column */
17117  SCIP_COL* col /**< LP column */
17118  )
17119 {
17120  assert(col != NULL);
17121 
17122  return col->nsbcalls;
17123 }
17124 
17125 /** gets the age of a column, i.e., the total number of successive times a column was in the LP and was 0.0 in the solution */
17127  SCIP_COL* col /**< LP column */
17128  )
17129 {
17130  assert(col != NULL);
17131 
17132  return col->age;
17133 }
17134 
17135 /** gets opposite bound type of given bound type */
17137  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17138  )
17139 {
17140  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17141 
17143 }
17144 
17145 /** get number of nonzero entries in row vector */
17147  SCIP_ROW* row /**< LP row */
17148  )
17149 {
17150  assert(row != NULL);
17151 
17152  return row->len;
17153 }
17154 
17155 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17156  *
17157  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17158  * that is in the current LP and the LP was solved, or a row that was in a solved LP and didn't change afterwards
17159  */
17161  SCIP_ROW* row /**< LP row */
17162  )
17163 {
17164  assert(row != NULL);
17165  assert(row->nunlinked == 0);
17166 
17167  return row->nlpcols;
17168 }
17169 
17170 /** gets array with columns of nonzero entries */
17172  SCIP_ROW* row /**< LP row */
17173  )
17174 {
17175  assert(row != NULL);
17176 
17177  return row->cols;
17178 }
17179 
17180 /** gets array with coefficients of nonzero entries */
17182  SCIP_ROW* row /**< LP row */
17183  )
17184 {
17185  assert(row != NULL);
17186 
17187  return row->vals;
17188 }
17189 
17190 /** gets constant shift of row */
17192  SCIP_ROW* row /**< LP row */
17193  )
17194 {
17195  assert(row != NULL);
17196 
17197  return row->constant;
17198 }
17199 
17200 /** gets Euclidean norm of row vector */
17202  SCIP_ROW* row /**< LP row */
17203  )
17204 {
17205  assert(row != NULL);
17206 
17207  checkRowSqrnorm(row);
17208 
17209  return sqrt(row->sqrnorm);
17210 }
17211 
17212 /** gets sum norm of row vector (sum of absolute values of coefficients) */
17214  SCIP_ROW* row /**< LP row */
17215  )
17216 {
17217  assert(row != NULL);
17218 
17219  checkRowSumnorm(row);
17220 
17221  return row->sumnorm;
17222 }
17223 
17224 /** returns the left hand side of the row */
17226  SCIP_ROW* row /**< LP row */
17227  )
17228 {
17229  assert(row != NULL);
17230 
17231  return row->lhs;
17232 }
17233 
17234 /** returns the right hand side of the row */
17236  SCIP_ROW* row /**< LP row */
17237  )
17238 {
17239  assert(row != NULL);
17240 
17241  return row->rhs;
17242 }
17243 
17244 /** gets the dual LP solution of a row */
17246  SCIP_ROW* row /**< LP row */
17247  )
17248 {
17249  assert(row != NULL);
17250 
17251  if( row->lppos >= 0 )
17252  return row->dualsol;
17253  else
17254  return 0.0;
17255 }
17256 
17257 /** gets the dual Farkas coefficient of a row in an infeasible LP */
17259  SCIP_ROW* row /**< LP row */
17260  )
17261 {
17262  assert(row != NULL);
17263 
17264  if( row->lppos >= 0 )
17265  return row->dualfarkas;
17266  else
17267  return 0.0;
17268 }
17269 
17270 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17271  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17272  */
17274  SCIP_ROW* row /**< LP row */
17275  )
17276 {
17277  assert(row != NULL);
17278  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17279 
17280  return (SCIP_BASESTAT)row->basisstatus;
17281 }
17282 
17283 /** returns the name of the row */
17284 const char* SCIProwGetName(
17285  SCIP_ROW* row /**< LP row */
17286  )
17287 {
17288  assert(row != NULL);
17289 
17290  return row->name;
17291 }
17292 
17293 /** gets unique index of row */
17295  SCIP_ROW* row /**< LP row */
17296  )
17297 {
17298  assert(row != NULL);
17299 
17300  return row->index;
17301 }
17302 
17303 /** gets age of row */
17305  SCIP_ROW* row /**< LP row */
17306  )
17307 {
17308  assert(row != NULL);
17309 
17310  return row->age;
17311 }
17312 
17313 /** gets rank of row */
17315  SCIP_ROW* row /**< LP row */
17316  )
17317 {
17318  assert(row != NULL);
17319 
17320  return row->rank;
17321 }
17322 
17323 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17325  SCIP_ROW* row /**< LP row */
17326  )
17327 {
17328  assert(row != NULL);
17329 
17330  return row->integral;
17331 }
17332 
17333 /** returns TRUE iff row is only valid locally */
17335  SCIP_ROW* row /**< LP row */
17336  )
17337 {
17338  assert(row != NULL);
17339 
17340  return row->local;
17341 }
17342 
17343 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17345  SCIP_ROW* row /**< LP row */
17346  )
17347 {
17348  assert(row != NULL);
17349 
17350  return row->modifiable;
17351 }
17352 
17353 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17355  SCIP_ROW* row /**< LP row */
17356  )
17357 {
17358  assert(row != NULL);
17359 
17360  return row->removable;
17361 }
17362 
17363 /** returns type of origin that created the row */
17365  SCIP_ROW* row /**< LP row */
17366  )
17367 {
17368  assert( row != NULL );
17369 
17370  return (SCIP_ROWORIGINTYPE) row->origintype;
17371 }
17372 
17373 /** returns origin constraint that created the row (NULL if not available) */
17375  SCIP_ROW* row /**< LP row */
17376  )
17377 {
17378  assert( row != NULL );
17379 
17381  {
17382  assert( row->origin != NULL );
17383  return (SCIP_CONS*) row->origin;
17384  }
17385  return NULL;
17386 }
17387 
17388 /** returns origin constraint handler that created the row (NULL if not available) */
17390  SCIP_ROW* row /**< LP row */
17391  )
17392 {
17393  assert( row != NULL );
17394 
17396  {
17397  assert( row->origin != NULL );
17398  return (SCIP_CONSHDLR*) row->origin;
17399  }
17401  {
17402  assert(row->origin != NULL);
17403  return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17404  }
17405  return NULL;
17406 }
17407 
17408 /** returns origin separator that created the row (NULL if not available) */
17410  SCIP_ROW* row /**< LP row */
17411  )
17412 {
17413  assert( row != NULL );
17414 
17416  {
17417  assert( row->origin != NULL );
17418  return (SCIP_SEPA*) row->origin;
17419  }
17420  return NULL;
17421 }
17422 
17423 /** returns TRUE iff row is member of the global cut pool */
17425  SCIP_ROW* row /**< LP row */
17426  )
17427 {
17428  assert(row != NULL);
17429 
17430  return row->inglobalcutpool;
17431 }
17432 
17433 /** gets position of row in current LP, or -1 if it is not in LP */
17435  SCIP_ROW* row /**< LP row */
17436  )
17437 {
17438  assert(row != NULL);
17439  assert((row->lppos == -1) == (row->lpdepth == -1));
17440 
17441  return row->lppos;
17442 }
17443 
17444 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17446  SCIP_ROW* row /**< LP row */
17447  )
17448 {
17449  assert(row != NULL);
17450  assert((row->lppos == -1) == (row->lpdepth == -1));
17451 
17452  return row->lpdepth;
17453 }
17454 
17455 /** returns TRUE iff row is member of current LP */
17457  SCIP_ROW* row /**< LP row */
17458  )
17459 {
17460  assert(row != NULL);
17461  assert((row->lppos == -1) == (row->lpdepth == -1));
17462 
17463  return (row->lppos >= 0);
17464 }
17465 
17466 /** changes the rank of LP row */
17468  SCIP_ROW* row, /**< LP row */
17469  int rank /**< new value for rank */
17470  )
17471 {
17472  assert(row != NULL);
17473 
17474  row->rank = rank;
17475 }
17476 
17477 /** returns the number of times that this row has been sharp in an optimal LP solution */
17479  SCIP_ROW* row /**< row */
17480  )
17481 {
17482  assert(row != NULL);
17483 
17484  return row->activeinlpcounter;
17485 }
17486 
17487 /** returns the number of LPs since this row has been created */
17489  SCIP_ROW* row /**< row */
17490  )
17491 {
17492  assert(row != NULL);
17493 
17494  return row->nlpsaftercreation;
17495 }
17496 
17497 /** gets array with columns of the LP */
17499  SCIP_LP* lp /**< current LP data */
17500  )
17501 {
17502  assert(lp != NULL);
17503 
17504  return lp->cols;
17505 }
17506 
17507 /** gets current number of columns in LP */
17509  SCIP_LP* lp /**< current LP data */
17510  )
17511 {
17512  assert(lp != NULL);
17513 
17514  return lp->ncols;
17515 }
17516 
17517 /** gets current number of unfixed columns in LP */
17519  SCIP_LP* lp, /**< current LP data */
17520  SCIP_Real eps /**< numerical tolerance */
17521  )
17522 {
17523  SCIP_COL** lpcols;
17524  int nlpcols;
17525  int nunfixedcols;
17526  int c;
17527 
17528  assert(lp != NULL);
17529  assert(eps > 0.0);
17530 
17531  lpcols = lp->cols;
17532  nlpcols = lp->ncols;
17533 
17534  nunfixedcols = 0;
17535  for( c = 0; c < nlpcols; ++c )
17536  {
17537  if( lpcols[c]->ub - lpcols[c]->lb > eps )
17538  ++nunfixedcols;
17539  }
17540 
17541  return nunfixedcols;
17542 }
17543 
17544 /** gets array with rows of the LP */
17546  SCIP_LP* lp /**< current LP data */
17547  )
17548 {
17549  assert(lp != NULL);
17550 
17551  return lp->rows;
17552 }
17553 
17554 /** gets current number of rows in LP */
17556  SCIP_LP* lp /**< current LP data */
17557  )
17558 {
17559  assert(lp != NULL);
17560 
17561  return lp->nrows;
17562 }
17563 
17564 /** gets array with newly added columns after the last mark */
17566  SCIP_LP* lp /**< current LP data */
17567  )
17568 {
17569  assert(lp != NULL);
17570  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17571 
17572  return &(lp->cols[lp->firstnewcol]);
17573 }
17574 
17575 /** gets number of newly added columns after the last mark */
17577  SCIP_LP* lp /**< current LP data */
17578  )
17579 {
17580  assert(lp != NULL);
17581  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17582 
17583  return lp->ncols - lp->firstnewcol;
17584 }
17585 
17586 /** gets array with newly added rows after the last mark */
17588  SCIP_LP* lp /**< current LP data */
17589  )
17590 {
17591  assert(lp != NULL);
17592  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17593 
17594  return &(lp->rows[lp->firstnewrow]);
17595 }
17596 
17597 /** gets number of newly added rows after the last mark */
17599  SCIP_LP* lp /**< current LP data */
17600  )
17601 {
17602  assert(lp != NULL);
17603  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17604 
17605  return lp->nrows - lp->firstnewrow;
17606 }
17607 
17608 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17610  SCIP_SET* set, /**< global SCIP settings */
17611  SCIP_LP* lp /**< LP data */
17612  )
17613 {
17614  if( lp->objsqrnormunreliable )
17615  {
17616  SCIP_COL** cols;
17617  int c;
17618 
17619  cols = lp->cols;
17620  assert(cols != NULL || lp->ncols == 0);
17621 
17622  lp->objsqrnorm = 0.0;
17623 
17624  for( c = lp->ncols - 1; c >= 0; --c )
17625  {
17626  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17627  }
17628  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17629 
17630  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17631  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17632 
17634  }
17635  return;
17636 }
17637 
17638 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17639  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17641  SCIP_LP* lp /**< LP data */
17642  )
17643 {
17644  assert(lp != NULL);
17645  assert(!lp->objsqrnormunreliable);
17646  assert(lp->objsqrnorm >= 0.0);
17647 
17648  return SQRT(lp->objsqrnorm);
17649 }
17650 
17651 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17653  SCIP_LP* lp, /**< LP data */
17654  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17655  )
17656 {
17657  assert(lp != NULL);
17658 
17659  lp->rootlpisrelax = isrelax;
17660 }
17661 
17662 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17664  SCIP_LP* lp /**< LP data */
17665  )
17666 {
17667  assert(lp != NULL);
17668 
17669  return lp->rootlpisrelax;
17670 }
17671 
17672 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17674  SCIP_LP* lp /**< LP data */
17675  )
17676 {
17677  assert(lp != NULL);
17678 
17679  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17680 }
17681 
17682 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17683  * returns SCIP_INVALID if the root node LP was not (yet) solved
17684  */
17686  SCIP_LP* lp /**< LP data */
17687  )
17688 {
17689  assert(lp != NULL);
17690 
17691  return lp->rootlpobjval;
17692 }
17693 
17694 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17695  * returns SCIP_INVALID if the root node LP was not (yet) solved
17696  */
17698  SCIP_LP* lp /**< LP data */
17699  )
17700 {
17701  assert(lp != NULL);
17702 
17703  return lp->rootlooseobjval;
17704 }
17705 
17706 /** gets the LP solver interface */
17708  SCIP_LP* lp /**< current LP data */
17709  )
17710 {
17711  assert(lp != NULL);
17712 
17713  return lp->lpi;
17714 }
17715 
17716 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17718  SCIP_LP* lp, /**< LP data */
17719  SCIP_Bool relax /**< is the current lp a relaxation? */
17720  )
17721 {
17722  assert(lp != NULL);
17723 
17724  lp->isrelax = relax;
17725 }
17726 
17727 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17728  * solution value a valid local lower bound?
17729  */
17731  SCIP_LP* lp /**< LP data */
17732  )
17733 {
17734  assert(lp != NULL);
17735 
17736  return lp->isrelax;
17737 }
17738 
17739 /** returns whether the current LP is flushed and solved */
17741  SCIP_LP* lp /**< current LP data */
17742  )
17743 {
17744  assert(lp != NULL);
17745 
17746  return lp->flushed && lp->solved;
17747 }
17748 
17749 /** return whether the current LP solution passed the primal feasibility check */
17751  SCIP_LP* lp /**< current LP data */
17752  )
17753 {
17754  assert(lp != NULL);
17755 
17756  return (lp->primalchecked && lp->primalfeasible);
17757 }
17758 
17759 /** return whether the current LP solution passed the dual feasibility check */
17761  SCIP_LP* lp /**< current LP data */
17762  )
17763 {
17764  assert(lp != NULL);
17765 
17766  return (lp->dualchecked && lp->dualfeasible);
17767 }
17768 
17769 /** returns whether the current LP solution is a basic solution */
17771  SCIP_LP* lp /**< current LP data */
17772  )
17773 {
17774  assert(lp != NULL);
17775 
17776  return lp->solisbasic;
17777 }
17778 
17779 /** returns whether the LP is in diving mode */
17781  SCIP_LP* lp /**< current LP data */
17782  )
17783 {
17784  assert(lp != NULL);
17785 
17786  return lp->diving;
17787 }
17788 
17789 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17791  SCIP_LP* lp /**< current LP data */
17792  )
17793 {
17794  assert(lp != NULL);
17795 
17796  return lp->divingobjchg;
17797 }
17798 
17799 /** marks the diving LP to have a changed objective function */
17801  SCIP_LP* lp /**< current LP data */
17802  )
17803 {
17804  assert(lp != NULL);
17805  assert(lp->diving || lp->probing);
17806 
17807  lp->divingobjchg = TRUE;
17808 }
17809 
17810 /** marks the diving LP to not have a changed objective function anymore */
17812  SCIP_LP* lp /**< current LP data */
17813  )
17814 {
17815  assert(lp != NULL);
17816  assert(lp->diving || lp->probing);
17817 
17818  lp->divingobjchg = FALSE;
17819 }
17820 
17821 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17823  SCIP_LP* lp /**< current LP data */
17824  )
17825 {
17826  assert(lp != NULL);
17827  assert(lp->diving || lp->ndivechgsides == 0);
17828 
17829  return (lp->ndivechgsides > 0);
17830 }
17831 
17832 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17833 static
17835  SCIP_LPI* lpi, /**< auxiliary LP interface */
17836  SCIP_SET* set, /**< global SCIP settings */
17837  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17838  SCIP_LP* lp, /**< LP data */
17839  SCIP_PROB* prob, /**< problem data */
17840  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17841  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17842  SCIP_Real timelimit, /**< time limit for LP solver */
17843  int iterlimit, /**< iteration limit for LP solver */
17844  SCIP_Real* point, /**< array to store relative interior point on exit */
17845  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17846  )
17847 {
17848  SCIP_RETCODE retcode;
17849  SCIP_Real* primal;
17850  SCIP_Real* obj;
17851  SCIP_Real* lb;
17852  SCIP_Real* ub;
17853  SCIP_Real* matvals;
17854  SCIP_Real* matlhs;
17855  SCIP_Real* matrhs;
17856  SCIP_Real objval;
17857  SCIP_Real alpha;
17858  int* matinds;
17859  int* matbeg;
17860 #ifndef NDEBUG
17861  int nslacks;
17862 #endif
17863  int nnewcols;
17864  int ntotnonz = 0;
17865  int ntotrows = 0;
17866  int matrowidx;
17867  int matidx;
17868  int cnt;
17869  int j;
17870  int i;
17871 
17872  assert(lpi != NULL);
17873 
17874  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
17875  if( retcode != SCIP_OKAY )
17876  {
17877  /* stop execution on error, since result is likely to be unsuable */
17878  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17879  return SCIP_LPERROR;
17880  }
17881 
17883  if( retcode != SCIP_OKAY )
17884  {
17885  /* stop execution on error, since result is likely to be unsuable */
17886  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17887  return SCIP_LPERROR;
17888  }
17889 
17890  /* get storage */
17891  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17892  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17893  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17894  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17895 
17896  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17897  for( j = 0; j < lp->ncols; ++j )
17898  {
17899  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17900  obj[j] = 0.0;
17901  lb[j] = -SCIPlpiInfinity(lpi);
17902  ub[j] = SCIPlpiInfinity(lpi);
17903  /* note: we could also use the original bounds - free variables seem to be faster. */
17904  }
17905 
17906  /* add artificial alpha variable */
17907  nnewcols = lp->ncols;
17908  obj[nnewcols] = 0.0;
17909  lb[nnewcols] = 1.0;
17910  ub[nnewcols] = SCIPlpiInfinity(lpi);
17911  ++nnewcols;
17912 
17913  /* create slacks for rows */
17914  for( i = 0; i < lp->nrows; ++i )
17915  {
17916  SCIP_ROW* row;
17917 
17918  row = lp->rows[i];
17919  assert( row != NULL );
17920 
17921  if( SCIProwIsModifiable(row) )
17922  continue;
17923 
17924  /* make sure row is sorted */
17925  rowSortLP(row);
17926  assert( row->lpcolssorted );
17927 
17928  /* check whether we have an equation */
17929  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17930  {
17931  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17932  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17933  ntotnonz += row->nlpcols + 1;
17934  ++ntotrows;
17935  }
17936  else
17937  {
17938  /* otherwise add slacks for each side if necessary */
17939  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17940  {
17941  if ( relaxrows )
17942  {
17943  lb[nnewcols] = 0.0;
17944  ub[nnewcols] = 1.0;
17945  obj[nnewcols++] = 1.0;
17946  ntotnonz += row->nlpcols + 2;
17947  }
17948  else
17949  ntotnonz += row->nlpcols + 1;
17950  ++ntotrows;
17951  }
17952  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17953  {
17954  if ( relaxrows )
17955  {
17956  lb[nnewcols] = 0.0;
17957  ub[nnewcols] = 1.0;
17958  obj[nnewcols++] = 1.0;
17959  ntotnonz += row->nlpcols + 2;
17960  }
17961  else
17962  ntotnonz += row->nlpcols + 1;
17963  ++ntotrows;
17964  }
17965  }
17966  }
17967 
17968  /* create slacks for objective cutoff row */
17969  if( inclobjcutoff && relaxrows )
17970  {
17971  /* add slacks for right hand side */
17972  lb[nnewcols] = 0.0;
17973  ub[nnewcols] = 1.0;
17974  obj[nnewcols++] = 1.0;
17975  ntotnonz += lp->ncols + 2;
17976  ++ntotrows;
17977  }
17978 
17979  /* create slacks for bounds */
17980  for( j = 0; j < lp->ncols; ++j )
17981  {
17982  SCIP_COL* col;
17983 
17984  col = lp->cols[j];
17985  assert( col != NULL );
17986 
17987  /* no slacks for fixed variables */
17988  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17989  {
17990  ++ntotrows;
17991  ntotnonz += 2;
17992  }
17993  else
17994  {
17995  /* add slacks for each bound if necessary */
17996  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17997  {
17998  lb[nnewcols] = 0.0;
17999  ub[nnewcols] = 1.0;
18000  obj[nnewcols++] = 1.0;
18001  ntotnonz += 3;
18002  ++ntotrows;
18003  }
18004  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
18005  {
18006  lb[nnewcols] = 0.0;
18007  ub[nnewcols] = 1.0;
18008  obj[nnewcols++] = 1.0;
18009  ntotnonz += 3;
18010  ++ntotrows;
18011  }
18012  }
18013  }
18014 #ifndef NDEBUG
18015  nslacks = nnewcols - lp->ncols - 1;
18016  assert( nslacks >= 0 );
18017  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
18018 #endif
18019 
18020  /* add columns */
18021  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
18022 
18023  /* free storage */
18024  SCIPsetFreeBufferArray(set, &obj);
18025  SCIPsetFreeBufferArray(set, &ub);
18026  SCIPsetFreeBufferArray(set, &lb);
18027 
18028  /* prepare storage for rows */
18029  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
18030  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
18031  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
18032  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
18033  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
18034 
18035  /* create rows arising from original rows */
18036  cnt = 0;
18037  matrowidx = 0;
18038  matidx = 0;
18039  for( i = 0; i < lp->nrows; ++i )
18040  {
18041  SCIP_ROW* row;
18042  SCIP_COL** rowcols;
18043  SCIP_Real* rowvals;
18044  SCIP_Real lhs;
18045  SCIP_Real rhs;
18046  int nnonz;
18047 
18048  row = lp->rows[i];
18049  assert( row != NULL );
18050 
18051  if( SCIProwIsModifiable(row) )
18052  continue;
18053  assert( row->lpcolssorted );
18054 
18055  /* get row data */
18056  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18057  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18058  nnonz = row->nlpcols;
18059  assert( nnonz <= lp->ncols );
18060  rowcols = row->cols;
18061  rowvals = row->vals;
18062 
18063  /* if we have an equation */
18064  if( SCIPsetIsEQ(set, lhs, rhs) )
18065  {
18066  /* set up indices */
18067  matbeg[matrowidx] = matidx;
18068  for( j = 0; j < nnonz; ++j )
18069  {
18070  assert( rowcols[j] != NULL );
18071  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18072  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18073  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18074  matinds[matidx] = rowcols[j]->lppos;
18075  matvals[matidx++] = rowvals[j];
18076  assert( matidx <= ntotnonz );
18077  }
18078 
18079  /* add artificial variable */
18080  if ( ! SCIPsetIsZero(set, rhs) )
18081  {
18082  matinds[matidx] = lp->ncols;
18083  matvals[matidx++] = -rhs;
18084  assert( matidx <= ntotnonz );
18085  }
18086 
18087  matlhs[matrowidx] = 0.0;
18088  matrhs[matrowidx++] = 0.0;
18089  assert( matrowidx <= ntotrows );
18090  }
18091  else
18092  {
18093  SCIP_Real abslhs = REALABS(lhs);
18094  SCIP_Real absrhs = REALABS(rhs);
18095 
18096  assert(!SCIPsetIsEQ(set, lhs, rhs));
18097 
18098  /* treat lhs */
18099  if( !SCIPsetIsInfinity(set, abslhs) )
18100  {
18101  /* set up indices */
18102  matbeg[matrowidx] = matidx;
18103  for( j = 0; j < nnonz; ++j )
18104  {
18105  assert( rowcols[j] != NULL );
18106  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18107  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18108  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18109  matinds[matidx] = rowcols[j]->lppos;
18110  matvals[matidx++] = rowvals[j];
18111  assert( matidx <= ntotnonz );
18112  }
18113 
18114  /* add artificial variable */
18115  if ( ! SCIPsetIsZero(set, lhs) )
18116  {
18117  matinds[matidx] = lp->ncols;
18118  matvals[matidx++] = -lhs;
18119  assert( matidx <= ntotnonz );
18120  }
18121 
18122  if( relaxrows )
18123  {
18124  /* add slack variable */
18125  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18126  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18127  assert( matidx <= ntotnonz );
18128  ++cnt;
18129  }
18130 
18131  matlhs[matrowidx] = 0.0;
18132  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18133  assert( matrowidx <= ntotrows );
18134  }
18135 
18136  /* treat rhs */
18137  if( !SCIPsetIsInfinity(set, absrhs) )
18138  {
18139  /* set up indices */
18140  matbeg[matrowidx] = matidx;
18141  for( j = 0; j < nnonz; ++j )
18142  {
18143  assert( rowcols[j] != NULL );
18144  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18145  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18146  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18147  matinds[matidx] = rowcols[j]->lppos;
18148  matvals[matidx++] = rowvals[j];
18149  assert( matidx <= ntotnonz );
18150  }
18151 
18152  /* add artificial variable */
18153  if ( ! SCIPsetIsZero(set, rhs) )
18154  {
18155  matinds[matidx] = lp->ncols;
18156  matvals[matidx++] = -rhs;
18157  assert( matidx <= ntotnonz );
18158  }
18159 
18160  if( relaxrows )
18161  {
18162  /* add slack variable */
18163  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18164  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18165  ++cnt;
18166  }
18167 
18168  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18169  matrhs[matrowidx++] = 0.0;
18170  assert( matrowidx <= ntotrows );
18171  }
18172  }
18173  }
18174 
18175  /* create row arising from objective cutoff */
18176  if( inclobjcutoff )
18177  {
18178  SCIP_Real rhs;
18179 
18180  /* get row data */
18181  assert(lp->looseobjvalinf == 0);
18182  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18183 
18184  /* set up indices and coefficients */
18185  matbeg[matrowidx] = matidx;
18186  for( j = 0; j < lp->ncols; ++j )
18187  {
18188  assert( lp->cols[j] != NULL );
18189  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18190  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18191 
18192  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18193  {
18194  matinds[matidx] = lp->cols[j]->lppos;
18195  matvals[matidx++] = lp->cols[j]->obj;
18196  assert( matidx <= ntotnonz );
18197  }
18198  }
18199 
18200  /* treat rhs */
18201 
18202  /* add artificial variable */
18203  if ( ! SCIPsetIsZero(set, rhs) )
18204  {
18205  matinds[matidx] = lp->ncols;
18206  matvals[matidx++] = -rhs;
18207  assert( matidx <= ntotnonz );
18208  }
18209 
18210  if( relaxrows )
18211  {
18212  SCIP_Real absrhs = REALABS(rhs);
18213 
18214  /* add slack variable */
18215  matvals[matidx] = MAX(1.0, absrhs);
18216  matinds[matidx++] = lp->ncols + 1 + cnt;
18217  assert( matidx <= ntotnonz );
18218  ++cnt;
18219  }
18220  matlhs[matrowidx] = -SCIPsetInfinity(set);
18221  matrhs[matrowidx++] = 0.0;
18222  assert( matrowidx <= ntotrows );
18223  }
18224 
18225  /* create rows arising from bounds */
18226  for( j = 0; j < lp->ncols; ++j )
18227  {
18228  SCIP_COL* col;
18229  SCIP_Real abscollb;
18230  SCIP_Real abscolub;
18231 
18232  col = lp->cols[j];
18233  assert( col != NULL );
18234  assert( col->lppos == j );
18235 
18236  /* fixed variable */
18237  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18238  {
18239  /* set up index of column */
18240  matbeg[matrowidx] = matidx;
18241 
18242  matinds[matidx] = j;
18243  matvals[matidx++] = 1.0;
18244  assert( matidx <= ntotnonz );
18245 
18246  /* add artificial variable */
18247  if ( ! SCIPsetIsZero(set, col->ub) )
18248  {
18249  matinds[matidx] = lp->ncols;
18250  matvals[matidx++] = -col->ub;
18251  assert( matidx <= ntotnonz );
18252  }
18253 
18254  matlhs[matrowidx] = 0.0;
18255  matrhs[matrowidx++] = 0.0;
18256  assert( matrowidx <= ntotrows );
18257 
18258  continue;
18259  }
18260 
18261  abscollb = REALABS(col->lb);
18262  abscolub = REALABS(col->ub);
18263 
18264  /* lower bound */
18265  if ( ! SCIPsetIsInfinity(set, abscollb) )
18266  {
18267  /* set up index of column */
18268  matbeg[matrowidx] = matidx;
18269 
18270  matinds[matidx] = j;
18271  matvals[matidx++] = 1.0;
18272  assert( matidx <= ntotnonz );
18273 
18274  /* add artificial variable */
18275  if ( ! SCIPsetIsZero(set, col->lb) )
18276  {
18277  matinds[matidx] = lp->ncols;
18278  matvals[matidx++] = -col->lb;
18279  assert( matidx <= ntotnonz );
18280  }
18281 
18282  /* add slack variable */
18283  matvals[matidx] = -MAX(1.0, abscollb);
18284  matinds[matidx++] = lp->ncols + 1 + cnt;
18285  assert( matidx <= ntotnonz );
18286  ++cnt;
18287 
18288  matlhs[matrowidx] = 0.0;
18289  matrhs[matrowidx++] = SCIPsetInfinity(set);
18290  assert( matrowidx <= ntotrows );
18291  }
18292 
18293  /* upper bound */
18294  if ( ! SCIPsetIsInfinity(set, abscolub) )
18295  {
18296  /* set up index of column */
18297  matbeg[matrowidx] = matidx;
18298 
18299  matinds[matidx] = j;
18300  matvals[matidx++] = 1.0;
18301  assert( matidx <= ntotnonz );
18302 
18303  /* add artificial variable */
18304  if ( ! SCIPsetIsZero(set, col->ub) )
18305  {
18306  matinds[matidx] = lp->ncols;
18307  matvals[matidx++] = -col->ub;
18308  assert( matidx <= ntotnonz );
18309  }
18310 
18311  /* add slack variable */
18312  matvals[matidx] = MAX(1.0, abscolub);
18313  matinds[matidx++] = lp->ncols + 1 + cnt;
18314  assert( matidx <= ntotnonz );
18315  ++cnt;
18316 
18317  matlhs[matrowidx] = -SCIPsetInfinity(set);
18318  matrhs[matrowidx++] = 0.0;
18319  assert( matrowidx <= ntotrows );
18320  }
18321  }
18322  assert( cnt == nslacks );
18323  assert( matrowidx == ntotrows );
18324 
18325  /* add rows */
18326  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18327 
18328  SCIPsetFreeBufferArray(set, &matrhs);
18329  SCIPsetFreeBufferArray(set, &matlhs);
18330  SCIPsetFreeBufferArray(set, &matbeg);
18331  SCIPsetFreeBufferArray(set, &matvals);
18332  SCIPsetFreeBufferArray(set, &matinds);
18333 
18334 #ifdef SCIP_OUTPUT
18335  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18336 #endif
18337 
18338 #ifndef NDEBUG
18339  {
18340  int ncols;
18341  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18342  assert( ncols == nnewcols );
18343  }
18344 #endif
18345 
18346  /* set time limit */
18347  if( SCIPsetIsInfinity(set, timelimit) )
18348  timelimit = SCIPlpiInfinity(lpi);
18349  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18350 
18351  /* check, if parameter is unknown */
18352  if( retcode == SCIP_PARAMETERUNKNOWN )
18353  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18354  else if ( retcode != SCIP_OKAY )
18355  return retcode;
18356 
18357  /* set iteration limit */
18358  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18359 
18360  /* check, if parameter is unknown */
18361  if( retcode == SCIP_PARAMETERUNKNOWN )
18362  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18363  else if ( retcode != SCIP_OKAY )
18364  return retcode;
18365 
18366  /* solve and store point */
18367  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18368  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18369 
18370 #ifndef NDEBUG
18371  if ( SCIPlpiIsIterlimExc(lpi) )
18372  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18373  if ( SCIPlpiIsTimelimExc(lpi) )
18374  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18375 #endif
18376 
18377  if( SCIPlpiIsOptimal(lpi) )
18378  {
18379  /* get primal solution */
18380  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18381  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18382  alpha = primal[lp->ncols];
18383  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18384 
18385  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18386 
18387  /* construct relative interior point */
18388  for( j = 0; j < lp->ncols; ++j )
18389  point[j] = primal[j]/alpha;
18390 
18391 #ifdef SCIP_DEBUG
18392  /* check whether the point is a relative interior point */
18393  cnt = 0;
18394  if( relaxrows )
18395  {
18396  for( i = 0; i < lp->nrows; ++i )
18397  {
18398  SCIP_ROW* row;
18399  SCIP_COL** rowcols;
18400  SCIP_Real* rowvals;
18401  SCIP_Real lhs;
18402  SCIP_Real rhs;
18403  SCIP_Real sum;
18404  int nnonz;
18405 
18406  row = lp->rows[i];
18407  assert( row != NULL );
18408 
18409  /* get row data */
18410  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18411  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18412  nnonz = row->nlpcols;
18413  assert( nnonz <= lp->ncols );
18414  rowcols = row->cols;
18415  rowvals = row->vals;
18416 
18417  sum = 0.0;
18418  for( j = 0; j < nnonz; ++j )
18419  sum += rowvals[j] * primal[rowcols[j]->lppos];
18420  sum /= alpha;
18421 
18422  /* if we have an equation */
18423  if( SCIPsetIsEQ(set, lhs, rhs) )
18424  {
18425  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18426  }
18427  else
18428  {
18429  /* treat lhs */
18430  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18431  {
18432  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18433  ++cnt;
18434  }
18435  /* treat rhs */
18436  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18437  {
18438  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18439  ++cnt;
18440  }
18441  }
18442  }
18443  if( inclobjcutoff )
18444  {
18445  SCIP_Real sum;
18446 #ifndef NDEBUG
18447  SCIP_Real rhs;
18448 
18449  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18450 #endif
18451  sum = 0.0;
18452  for( j = 0; j < lp->ncols; ++j )
18453  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18454  sum /= alpha;
18455 
18456  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18457  ++cnt;
18458  }
18459  }
18460  /* check bounds */
18461  for( j = 0; j < lp->ncols; ++j )
18462  {
18463  SCIP_COL* col;
18464 #ifndef NDEBUG
18465  SCIP_Real val;
18466 #endif
18467 
18468  col = lp->cols[j];
18469  assert( col != NULL );
18470 #ifndef NDEBUG
18471  val = primal[col->lppos] / alpha;
18472 #endif
18473  /* if the variable is not fixed */
18474  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18475  {
18476  /* treat lb */
18477  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18478  {
18479  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18480  ++cnt;
18481  }
18482  /* treat rhs */
18483  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18484  {
18485  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18486  ++cnt;
18487  }
18488  }
18489  }
18490 #endif
18491 
18492  /* free */
18493  SCIPsetFreeBufferArray(set, &primal);
18494 
18495  *success = TRUE;
18496  }
18497 
18498  return SCIP_OKAY;
18499 }
18500 
18501 /** compute relative interior point
18502  *
18503  * We use the approach of@par
18504  * R. Freund, R. Roundy, M. J. Todd@par
18505  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18506  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18507  *
18508  * to compute a relative interior point for the current LP.
18509  *
18510  * Assume the original LP looks as follows:
18511  * \f[
18512  * \begin{array}{rrl}
18513  * \min & c^T x &\\
18514  * & A x & \geq a\\
18515  * & B x & \leq b\\
18516  * & D x & = d.
18517  * \end{array}
18518  * \f]
18519  * Note that bounds should be included in the system.
18520  *
18521  * To find an interior point the following LP does the job:
18522  * \f[
18523  * \begin{array}{rrl}
18524  * \max & 1^T y &\\
18525  * & A x - y - \alpha a & \geq 0\\
18526  * & B x + y - \alpha b & \leq 0\\
18527  * & D x - \alpha d & = 0\\
18528  * & 0 \leq y & \leq 1\\
18529  * & \alpha & \geq 1.
18530  * \end{array}
18531  * \f]
18532  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18533  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18534  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18535  */
18537  SCIP_SET* set, /**< global SCIP settings */
18538  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18539  SCIP_LP* lp, /**< LP data */
18540  SCIP_PROB* prob, /**< problem data */
18541  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18542  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18543  SCIP_Real timelimit, /**< time limit for LP solver */
18544  int iterlimit, /**< iteration limit for LP solver */
18545  SCIP_Real* point, /**< array to store relative interior point on exit */
18546  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18547  )
18548 {
18549  SCIP_LPI* lpi;
18550  SCIP_RETCODE retcode;
18551 
18552  assert(set != NULL);
18553  assert(lp != NULL);
18554  assert(point != NULL);
18555  assert(success != NULL);
18556 
18557  *success = FALSE;
18558 
18559  /* check time and iteration limits */
18560  if ( timelimit <= 0.0 || iterlimit <= 0 )
18561  return SCIP_OKAY;
18562 
18563  /* exit if there are no columns */
18564  assert(lp->nrows >= 0);
18565  assert(lp->ncols >= 0);
18566  if( lp->ncols == 0 )
18567  return SCIP_OKAY;
18568 
18569  /* disable objective cutoff if we have none */
18570  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18571  inclobjcutoff = FALSE;
18572 
18573  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18574 
18575  /* if there are no rows, we return the zero point */
18576  if( lp->nrows == 0 && !inclobjcutoff )
18577  {
18578  /* create zero point */
18579  BMSclearMemoryArray(point, lp->ncols);
18580  *success = TRUE;
18581 
18582  return SCIP_OKAY;
18583  }
18584 
18585  /* create auxiliary LP */
18586  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18587 
18588  /* catch return code and ensure that lpi is freed, anyway */
18589  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18590 
18591  SCIP_CALL( SCIPlpiFree(&lpi) );
18592 
18593  /* return error, unless we obtained an LP error */
18594  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18595  {
18596  SCIP_CALL( retcode );
18597  }
18598 
18599  return SCIP_OKAY;
18600 }
18601 
18602 /** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
18603  * based on the changes applied when reducing the problem to the optimal face
18604  *
18605  * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
18606  * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
18607  */
18609  SCIP_LP* lp, /**< LP data */
18610  SCIP_SET* set, /**< global SCIP settings */
18611  SCIP_STAT* stat, /**< problem statistics */
18612  SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
18613  SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
18614  )
18615 {
18616  assert(lp != NULL);
18617  assert(lp->solved);
18618  assert(lp->flushed);
18619 
18620  if( lp->validdegeneracylp != stat->nlps )
18621  {
18622  lp->validdegeneracylp = stat->nlps;
18623 
18624  /* if the LP was solved to optimality, we determine the dual degeneracy */
18626  {
18627  SCIP_COL** cols;
18628  SCIP_ROW** rows;
18629  SCIP_COL* col;
18630  int ncols;
18631  int nrows;
18632  int nfixedcols = 0;
18633  int nalreadyfixedcols = 0;
18634  int nfixedrows = 0;
18635  int nimplicitfixedrows = 0;
18636  int nineq = 0;
18637  int c;
18638  int r;
18639  int nbasicequalities = 0;
18640 
18641  cols = lp->cols;
18642  rows = lp->rows;
18643  ncols = lp->ncols;
18644  nrows = lp->nrows;
18645 
18646  /* count number of columns that will be fixed when reducing the LP to the optimal face */
18647  for( c = ncols - 1 ; c >= 0; --c )
18648  {
18649  col = cols[c];
18650  assert(SCIPcolIsInLP(col));
18651 
18652  /* column is not basic and not fixed already */
18654  {
18655  /* variable with nonzero reduced costs are fixed */
18656  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18657  if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
18658  ++nfixedcols;
18659  else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
18660  ++nalreadyfixedcols;
18661  }
18662  }
18663 
18664  /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
18665  for( r = nrows - 1; r >= 0; --r )
18666  {
18667  SCIP_ROW* row = rows[r];
18668 
18669  assert(SCIProwIsInLP(row));
18670 
18671  if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
18672  {
18673  SCIP_Real dualsol = SCIProwGetDualsol(row);
18674 
18675  ++nineq;
18676 
18678  {
18679  /* rows with nonzero dual solution are turned into equations */
18680  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18681  if( !SCIPsetIsZero(set, dualsol) )
18682  {
18683  if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18684  {
18685  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol));
18686  ++nfixedrows;
18687  }
18688  else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18689  {
18690  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol));
18691  ++nfixedrows;
18692  }
18693  }
18694  else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
18695  || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
18696  {
18697  ++nimplicitfixedrows;
18698  }
18699  }
18700  }
18701  else if( SCIProwGetBasisStatus(row) == SCIP_BASESTAT_BASIC )
18702  ++nbasicequalities;
18703  }
18704  assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
18705 
18706  if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
18707  lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
18708  else
18709  lp->degeneracy = 0.0;
18710 
18711  if( nrows > 0 )
18712  lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
18713  else
18714  lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
18715  assert(lp->degeneracy >= 0);
18716  assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
18717  assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
18718  }
18719  else
18720  {
18721  lp->degeneracy = 0.0;
18722  lp->varconsratio = 0.0;
18723  }
18724  }
18725 
18726  *degeneracy = lp->degeneracy;
18727  *varconsratio = lp->varconsratio;
18728 
18729  return SCIP_OKAY;
18730 }
18731 
18732 /** checks, if absolute difference of values is in range of LP primal feastol */
18734  SCIP_SET* set, /**< global SCIP settings */
18735  SCIP_LP* lp, /**< current LP data */
18736  SCIP_Real val1, /**< first value to be compared */
18737  SCIP_Real val2 /**< second value to be compared */
18738  )
18739 {
18740  assert(set != NULL);
18741  assert(lp != NULL);
18742 
18743  /* avoid to compare two different infinities; the reason for that is
18744  * that such a comparison can lead to unexpected results */
18745  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18746  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18747  || val1 == val2 ); /*lint !e777*/
18748 
18749  return EPSEQ(val1, val2, lp->feastol);
18750 }
18751 
18752 /** checks, if absolute difference of val1 and val2 is lower than LP primal feastol */
18754  SCIP_SET* set, /**< global SCIP settings */
18755  SCIP_LP* lp, /**< current LP data */
18756  SCIP_Real val1, /**< first value to be compared */
18757  SCIP_Real val2 /**< second value to be compared */
18758  )
18759 {
18760  assert(set != NULL);
18761  assert(lp != NULL);
18762 
18763  /* avoid to compare two different infinities; the reason for that is
18764  * that such a comparison can lead to unexpected results */
18765  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18766  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18767  || val1 == val2 ); /*lint !e777*/
18768 
18769  return EPSLT(val1, val2, lp->feastol);
18770 }
18771 
18772 /** checks, if absolute difference of val1 and val2 is not greater than LP primal feastol */
18774  SCIP_SET* set, /**< global SCIP settings */
18775  SCIP_LP* lp, /**< current LP data */
18776  SCIP_Real val1, /**< first value to be compared */
18777  SCIP_Real val2 /**< second value to be compared */
18778  )
18779 {
18780  assert(set != NULL);
18781  assert(lp != NULL);
18782 
18783  /* avoid to compare two different infinities; the reason for that is
18784  * that such a comparison can lead to unexpected results */
18785  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18786  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18787  || val1 == val2 ); /*lint !e777*/
18788 
18789  return EPSLE(val1, val2, lp->feastol);
18790 }
18791 
18792 /** checks, if absolute difference of val1 and val2 is greater than LP primal feastol */
18794  SCIP_SET* set, /**< global SCIP settings */
18795  SCIP_LP* lp, /**< current LP data */
18796  SCIP_Real val1, /**< first value to be compared */
18797  SCIP_Real val2 /**< second value to be compared */
18798  )
18799 {
18800  assert(set != NULL);
18801  assert(lp != NULL);
18802 
18803  /* avoid to compare two different infinities; the reason for that is
18804  * that such a comparison can lead to unexpected results */
18805  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18806  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18807  || val1 == val2 ); /*lint !e777*/
18808 
18809  return EPSGT(val1, val2, lp->feastol);
18810 }
18811 
18812 /** checks, if absolute difference of val1 and val2 is not lower than -LP primal feastol */
18814  SCIP_SET* set, /**< global SCIP settings */
18815  SCIP_LP* lp, /**< current LP data */
18816  SCIP_Real val1, /**< first value to be compared */
18817  SCIP_Real val2 /**< second value to be compared */
18818  )
18819 {
18820  assert(set != NULL);
18821  assert(lp != NULL);
18822 
18823  /* avoid to compare two different infinities; the reason for that is
18824  * that such a comparison can lead to unexpected results */
18825  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18826  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18827  || val1 == val2 ); /*lint !e777*/
18828 
18829  return EPSGE(val1, val2, lp->feastol);
18830 }
18831 
18832 /** checks, if value is in range LP primal feasibility tolerance of 0.0 */
18834  SCIP_LP* lp, /**< current LP data */
18835  SCIP_Real val /**< value to process */
18836  )
18837 {
18838  assert(lp != NULL);
18839 
18840  return EPSZ(val, lp->feastol);
18841 }
18842 
18843 /** checks, if value is greater than LP primal feasibility tolerance */
18845  SCIP_LP* lp, /**< current LP data */
18846  SCIP_Real val /**< value to process */
18847  )
18848 {
18849  assert(lp != NULL);
18850 
18851  return EPSP(val, lp->feastol);
18852 }
18853 
18854 /** checks, if value is lower than -LP primal feasibility tolerance */
18856  SCIP_LP* lp, /**< current LP data */
18857  SCIP_Real val /**< value to process */
18858  )
18859 {
18860  assert(lp != NULL);
18861 
18862  return EPSN(val, lp->feastol);
18863 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:401
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:7317
SCIP_Longint nprimallps
Definition: struct_stat.h:185
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17354
SCIP_Bool solisbasic
Definition: struct_lp.h:362
SCIP_Real lazyub
Definition: struct_lp.h:134
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1812
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:61
SCIP_Bool lpissolved
Definition: struct_lp.h:116
int nunlinked
Definition: struct_lp.h:228
static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition: lp.c:17834
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4745
int firstnewrow
Definition: struct_lp.h:326
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16424
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6501
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13169
void SCIPcolGetStrongbranchLast(SCIP_COL *col, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
Definition: lp.c:4701
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3262
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:93
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1408
void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:10271
int nsbcalls
Definition: struct_lp.h:167
SCIP_Bool primalchecked
Definition: struct_lp.h:112
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lp.c:367
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6200
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6503
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2536
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2854
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6696
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4293
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:461
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2742
static SCIP_RETCODE lpUpdateVarProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real oldlb, SCIP_Real oldub, SCIP_Real newobj, SCIP_Real newlb, SCIP_Real newub)
Definition: lp.c:13703
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8929
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:885
internal methods for managing events
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10167
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17822
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:634
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2829
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7358
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6258
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17598
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6708
SCIP_Longint validdegeneracylp
Definition: struct_lp.h:304
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2960
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7001
void * origin
Definition: struct_lp.h:216
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:222
static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
Definition: lp.c:4934
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14006
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3415
SCIP_STATUS status
Definition: struct_stat.h:177
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17780
SCIP_Real farkascoef
Definition: struct_lp.h:141
unsigned int ubchanged
Definition: struct_lp.h:175
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1855
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9696
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17717
SCIP_Longint validactivitylp
Definition: struct_lp.h:223
int lpifirstchgrow
Definition: struct_lp.h:311
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2388
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6521
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3638
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:17304
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1392
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17409
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:101
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:201
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:6107
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6680
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:79
int * cols_index
Definition: struct_lp.h:219
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_clp.cpp:3596
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16291
int nremovablecols
Definition: struct_lp.h:321
char * name
Definition: struct_var.h:226
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition: set.c:7394
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15646
SCIP_Bool primalfeasible
Definition: struct_lp.h:358
SCIP_RETCODE SCIPlpComputeRelIntPoint(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition: lp.c:18536
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:896
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3109
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:904
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2843
int nchgrows
Definition: struct_lp.h:315
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:228
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8664
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9863
char * name
Definition: struct_lp.h:217
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:18058
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6267
SCIP_RETCODE SCIPcolChgCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition: lp.c:3507
int nlpicols
Definition: struct_lp.h:307
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6598
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1992
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_clp.cpp:2774
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:535
enum SCIP_BaseStat SCIP_BASESTAT
Definition: type_lpi.h:87
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15615
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6415
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17652
SCIP_Longint nlps
Definition: struct_stat.h:183
SCIP_Longint activeinlpcounter
Definition: struct_lp.h:213
SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
Definition: event.c:2231
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6633
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:344
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3678
#define SCIP_MAXSTRLEN
Definition: def.h:293
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7998
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16964
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6165
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1796
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17609
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:69
internal methods for clocks and timing issues
SCIP_RETCODE SCIPlpInterrupt(SCIP_LP *lp, SCIP_Bool interrupt)
Definition: lp.c:10107
unsigned int origintype
Definition: struct_lp.h:255
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13580
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17094
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17106
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6323
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:117
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17146
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2953
SCIP_Real objsumnorm
Definition: struct_lp.h:283
SCIP_Longint ndivinglps
Definition: struct_stat.h:198
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: event.c:1970
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_ROW ** chgrows
Definition: struct_lp.h:290
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5332
SCIP_COL ** chgcols
Definition: struct_lp.h:289
SCIP_RETCODE SCIProwChgConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real constant)
Definition: lp.c:5578
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:15235
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:15160
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1158
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11984
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17284
int rank
Definition: struct_lp.h:239
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3634
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:1024
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6065
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2907
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1259
int rowssize
Definition: struct_lp.h:323
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8894
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3692
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7890
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17478
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13248
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:14985
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13897
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14185
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:620
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11487
unsigned int nonlprowssorted
Definition: struct_lp.h:172
int nclockskipsleft
Definition: struct_stat.h:266
SCIP_COL ** cols
Definition: struct_lp.h:291
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10090
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1295
int nlpirows
Definition: struct_lp.h:310
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:105
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:139
int soldirectionsize
Definition: struct_lp.h:317
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:17160
#define debugColPrint(x, y)
Definition: lp.c:150
SCIP_RETCODE SCIPcolCreate(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, int len, SCIP_ROW **rows, SCIP_Real *vals, SCIP_Bool removable)
Definition: lp.c:3273
static const int nscalars
Definition: lp.c:5737
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10291
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:38
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13870
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17225
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:87
int lppos
Definition: struct_lp.h:163
SCIP_Real lazylb
Definition: struct_lp.h:132
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:16460
#define EPSEQ(x, y, eps)
Definition: def.h:202
#define EPSISINT(x, eps)
Definition: def.h:214
int pseudoobjvalinf
Definition: struct_lp.h:330
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17770
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:294
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13938
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6741
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:770
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:17005
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3613
int divinglpiitlim
Definition: struct_lp.h:334
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16906
SCIP_Bool solved
Definition: struct_lp.h:357
static SCIP_RETCODE colAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val, int linkpos)
Definition: lp.c:1689
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11063
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_Longint nrootlps
Definition: struct_stat.h:184
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:17273
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16886
SCIP_Bool dualchecked
Definition: struct_lp.h:361
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6312
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16438
#define TRUE
Definition: def.h:86
#define SCIPdebug(x)
Definition: pub_message.h:84
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8221
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Bool lpifromscratch
Definition: struct_lp.h:375
unsigned int basisstatus
Definition: struct_lp.h:240
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2785
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6801
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10024
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3819
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:17685
#define EPSP(x, eps)
Definition: def.h:208
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16278
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1725
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:459
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2454
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2576
SCIP_RETCODE SCIProwChgCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
Definition: lp.c:5469
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17600
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3578
SCIP_Bool SCIPlpIsFeasLE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18773
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:350
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:48
unsigned int sbdownvalid
Definition: struct_lp.h:179
unsigned int objchanged
Definition: struct_lp.h:173
#define DIVESTACKGROWFACT
Definition: lp.c:16221
unsigned int delaysort
Definition: struct_lp.h:243
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5779
#define SCIP_UNUSED(x)
Definition: def.h:438
unsigned int basisstatus
Definition: struct_lp.h:170
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:17037
SCIP_Real lpidualfeastol
Definition: struct_lp.h:278
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15584
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6409
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3086
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:9050
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:336
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1426
public methods for problem variables
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6957
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1899
SCIP_RETCODE SCIPlpEndDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_VAR **vars, int nvars)
Definition: lp.c:16042
SCIP_RETCODE SCIProwMakeIntegral(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
Definition: lp.c:5974
int index
Definition: struct_lp.h:158
SCIP_Real relpseudoobjval
Definition: struct_lp.h:271
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2935
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real dualfarkas
Definition: struct_lp.h:206
#define EPSGE(x, y, eps)
Definition: def.h:206
SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12399
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:158
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12317
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition: set.c:6179
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17545
SCIP_Bool diving
Definition: struct_lp.h:370
#define SCIPdebugMessage
Definition: pub_message.h:87
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7912
static void lpUpdateObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real deltaval, int deltainf, SCIP_Bool local, SCIP_Bool loose, SCIP_Bool global)
Definition: lp.c:13621
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13280
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6744
SCIP_Real rootlooseobjval
Definition: struct_lp.h:273
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1700
SCIP_RETCODE SCIPcolIncCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real incval)
Definition: lp.c:3558
int firstnewcol
Definition: struct_lp.h:322
SCIP_RETCODE SCIPlpCleanupAll(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
Definition: lp.c:15823
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17374
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3462
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10181
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:15175
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
unsigned int integral
Definition: struct_lp.h:248
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:461
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:10147
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1128
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:102
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6334
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17364
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:3021
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1057
#define SCIP_LONGINT_MAX
Definition: def.h:163
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:159
int lpifirstchgcol
Definition: struct_lp.h:308
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1732
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:138
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16263
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:471
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2548
#define checkRow(row)
Definition: lp.c:686
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6554
int maxdepth
Definition: struct_stat.h:227
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:9024
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
int looseobjvalinf
Definition: struct_lp.h:327
SCIP_Real obj
Definition: struct_var.h:200
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:351
unsigned int rhschanged
Definition: struct_lp.h:246
SCIP_RETCODE SCIProwIncCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real incval)
Definition: lp.c:5521
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17245
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:287
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13081
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition: lp.c:274
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4733
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:522
int lazycolssize
Definition: struct_lp.h:319
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14098
Definition: heur_padm.c:123
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:854
SCIP_Real objprod
Definition: struct_lp.h:201
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3300
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:17663
int colssize
Definition: struct_lp.h:316
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:345
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:16224
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:381
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:391
SCIP_Bool lpipresolving
Definition: struct_lp.h:376
int nremovablerows
Definition: struct_lp.h:325
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:749
SCIP_Bool primalchecked
Definition: struct_lp.h:359
real eps
SCIP_Bool strongbranching
Definition: struct_lp.h:367
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1338
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2474
#define checkLinks(lp)
Definition: lp.c:1615
int lpithreads
Definition: struct_lp.h:337
int ndivechgsides
Definition: struct_lp.h:332
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17508
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12290
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11566
#define SCIP_DEFAULT_EPSILON
Definition: def.h:183
static SCIP_RETCODE lpSolveStable(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int itlim, int harditlim, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:11569
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6294
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2738
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17456
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:7062
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2344
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int integral
Definition: struct_lp.h:177
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:9295
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4304
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1871
int nloosevars
Definition: struct_lp.h:328
static void rowDelNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool forcenormupdate, SCIP_Bool updateindex, SCIP_Bool updateval)
Definition: lp.c:1976
SCIP_Bool SCIPlpIsFeasEQ(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18733
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2633
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17673
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3841
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4824
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6152
int divechgsidessize
Definition: struct_lp.h:333
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6240
SCIP_RETCODE SCIPlpCleanupNew(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool root)
Definition: lp.c:15784
int * linkpos
Definition: struct_lp.h:157
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:363
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6467
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:905
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:46
int lpiitlim
Definition: struct_lp.h:335
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition: lp.c:10048
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: lp.c:7826
int SCIPcolGetAge(SCIP_COL *col)
Definition: lp.c:17126
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:3987
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:279
SCIP_RETCODE SCIPcolAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val)
Definition: lp.c:3441
int glbpseudoobjvalinf
Definition: struct_lp.h:329
#define EPSN(x, eps)
Definition: def.h:209
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17576
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13965
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:17213
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:455
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2470
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14230
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:488
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15936
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16929
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6712
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:16248
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5659
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6009
int lpirefactorinterval
Definition: struct_lp.h:341
SCIP_ROW ** divechgrows
Definition: struct_lp.h:298
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:387
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:8172
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: event.c:1877
SCIP_RETCODE SCIPlpWriteMip(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *fname, SCIP_Bool genericnames, SCIP_Bool origobj, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_Bool lazyconss)
Definition: lp.c:16475
SCIP_Bool installing
Definition: struct_lp.h:366
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:392
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:17750
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17136
internal methods for storing and manipulating the main problem
static SCIP_Bool isIntegralScalar(SCIP_Real val, SCIP_Real scalar, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Real *intval)
Definition: lp.c:4894
#define SCIPerrorMessage
Definition: pub_message.h:55
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:669
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition: lp.c:3223
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14308
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17760
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:181
SCIP_Bool lpilpinfo
Definition: struct_lp.h:377
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17084
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3175
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2290
SCIP_Real pseudoactivity
Definition: struct_lp.h:207
SCIP_PRICING lpipricing
Definition: struct_lp.h:342
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9441
SCIP_Bool dualchecked
Definition: struct_lp.h:114
SCIP_COL ** cols
Definition: struct_lp.h:218
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:993
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9624
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17498
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17334
SCIP_Bool adjustlpval
Definition: struct_lp.h:374
SCIP_Real minval
Definition: struct_lp.h:203
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:4076
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIP_ROW ** lpirows
Definition: struct_lp.h:288
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3489
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:189
SCIP_Longint validsoldirlp
Definition: struct_lp.h:303
static SCIP_RETCODE lpCleanupRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition: lp.c:15713
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8616
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5723
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_Longint validfarkaslp
Definition: struct_lp.h:302
SCIP_RETCODE SCIPlpSumRows(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real *weights, SCIP_REALARRAY *sumcoef, SCIP_Real *sumlhs, SCIP_Real *sumrhs)
Definition: lp.c:9938
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2488
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9781
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:6135
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16896
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:104
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:164
int nuses
Definition: struct_lp.h:229
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
int lpiscaling
Definition: struct_lp.h:340
static SCIP_RETCODE rowAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val, int linkpos)
Definition: lp.c:2034
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:17324
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2269
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6329
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14630
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6141
SCIP_Real cutoffbound
Definition: struct_lp.h:274
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6443
SCIP_RETCODE SCIPlpAddRow(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_ROW *row, int depth)
Definition: lp.c:9500
internal miscellaneous methods
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_Bool isrelax
Definition: struct_lp.h:364
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17640
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6875
int numintcols
Definition: struct_lp.h:235
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2336
SCIP_Bool userinterrupt
Definition: struct_stat.h:269
#define REALABS(x)
Definition: def.h:201
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:299
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2699
SCIP_Bool looseobjvalid
Definition: struct_lp.h:348
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:384
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition: lp.c:10246
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6686
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:18048
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6519
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2391
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17555
int lpirandomseed
Definition: struct_lp.h:339
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:585
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:214
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17800
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:354
SCIP_Bool resolvelperror
Definition: struct_lp.h:373
unsigned int removable
Definition: struct_lp.h:178
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:271
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17235
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8369
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11478
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3609
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:977
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6222
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real objlim, SCIP_Bool *success)
Definition: lp.c:2648
#define lpCutoffDisabled(set)
Definition: lp.c:2641
int lpicolssize
Definition: struct_lp.h:306
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17707
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13097
SCIP_LPI * lpi
Definition: struct_lp.h:286
SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18855
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5292
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2427
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17344
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1810
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:266
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6642
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17171
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6901
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:192
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:297
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2291
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4174
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6728
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:160
static SCIP_RETCODE rowEventSideChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1515
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:9002
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8854
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5345
int var_probindex
Definition: struct_lp.h:169
static SCIP_RETCODE lpSolve(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12015
SCIP_Longint nduallps
Definition: struct_stat.h:187
SCIP_RETCODE SCIPlpGetDualDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
Definition: lp.c:18608
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6459
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16985
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition: lp.c:10236
internal methods for problem variables
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2436
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7963
#define SCIP_UNKNOWN
Definition: def.h:198
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9807
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6345
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17181
int nchgcols
Definition: struct_lp.h:313
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:1009
public data structures and miscellaneous methods
SCIP_Bool SCIPlpIsFeasGT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18793
int len
Definition: struct_lp.h:160
SCIP_Real * soldirection
Definition: struct_lp.h:294
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17697
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9762
SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18813
#define SCIP_Bool
Definition: def.h:84
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13180
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3508
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:828
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:6097
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:193
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
int numminval
Definition: struct_lp.h:237
int lpipos
Definition: struct_lp.h:231
int size
Definition: struct_lp.h:225
unsigned int modifiable
Definition: struct_lp.h:250
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:812
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3905
void SCIPprintSysError(const char *message)
Definition: misc.c:10664
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15334
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
SCIP_RETCODE SCIPlpFree(SCIP_LP **lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9362
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16916
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6042
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:103
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3893
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:971
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3375
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: cons.c:6203
int chgrowssize
Definition: struct_lp.h:314
int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
Definition: lp.c:17518
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17587
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18297
SCIP_Longint validfarkaslp
Definition: struct_lp.h:155
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:317
unsigned int lbchanged
Definition: struct_lp.h:174
SCIP_Bool divingobjchg
Definition: struct_lp.h:371
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9841
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:460
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17790
SCIP_Real feastol
Definition: struct_lp.h:275
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3751
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3423
#define MAX(x, y)
Definition: tclique_def.h:83
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition: lp.c:1092
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8105
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition: lp.c:3134
SCIP_Real degeneracy
Definition: struct_lp.h:284
SCIP_Bool updateintegrality
Definition: struct_lp.h:355
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17768
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:9067
#define SCIPsetDebugMsg
Definition: set.h:1761
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:385
void SCIPcolSetStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real lpobjval, SCIP_Real primsol, SCIP_Real sbdown, SCIP_Real sbup, SCIP_Bool sbdownvalid, SCIP_Bool sbupvalid, SCIP_Longint iter, int itlim)
Definition: lp.c:4204
int minidx
Definition: struct_lp.h:233
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:17016
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2175
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2300
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:390
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17758
#define EPSLE(x, y, eps)
Definition: def.h:204
int nlprows
Definition: struct_lp.h:161
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition: lp.c:5423
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9070
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9824
unsigned int lpcolssorted
Definition: struct_lp.h:241
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:372
SCIP_Longint validsollp
Definition: struct_lp.h:301
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3454
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9793
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17258
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17621
SCIP_CLOCK * resolveinstablelptime
Definition: struct_stat.h:159
static void colSortLP(SCIP_COL *col)
Definition: lp.c:960
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13922
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6858
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6917
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:251
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15862
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6620
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6431
SCIP_ROW ** rows
Definition: struct_lp.h:293
SCIP_SOL * validsoldirsol
Definition: struct_lp.h:300
SCIP_Longint validredcostlp
Definition: struct_lp.h:154
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3796
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1206
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:295
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10123
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3209
SCIP_RETCODE SCIProwDropEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: lp.c:7850
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3371
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3401
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12379
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1167
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:923
SCIP_Real flushedrhs
Definition: struct_lp.h:198
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition: lp.c:17389
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:17314
static void getObjvalDeltaObj(SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj, SCIP_Real lb, SCIP_Real ub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13408
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:157
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16942
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:1075
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9407
SCIP_RETCODE SCIPcolGetStrongbranches(SCIP_COL **cols, int ncols, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4478
#define SCIP_REAL_MAX
Definition: def.h:178
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5371
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6930
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6612
SCIP_Real rhs
Definition: struct_lp.h:196
static void getObjvalDeltaLb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13539
static SCIP_RETCODE lpBarrier(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool crossover, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:11258
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2722
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7717
#define checkRowObjprod(row)
Definition: lp.c:761
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13136
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16314
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8156
datastructures for storing and manipulating the main problem
SCIP_Real SCIPlpGetModifiedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13310
unsigned int removable
Definition: struct_lp.h:251
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lp.c:572
unsigned int lhschanged
Definition: struct_lp.h:245
SCIP_Real * r
Definition: circlepacking.c:50
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2612
#define EPSLT(x, y, eps)
Definition: def.h:203
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:161
methods for sorting joint arrays of various types
SCIP_COL ** lazycols
Definition: struct_lp.h:292
static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1457
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2315
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:268
#define EPSGT(x, y, eps)
Definition: def.h:205
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17191
int sbitlim
Definition: struct_lp.h:166
static SCIP_RETCODE lpRemoveObsoleteCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15432
SCIP_VAR ** b
Definition: circlepacking.c:56
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13156
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1948
SCIP_Real lpimarkowitz
Definition: struct_lp.h:281
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:17059
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6842
int age
Definition: struct_lp.h:168
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:210
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3410
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:150
void SCIPconsCapture(SCIP_CONS *cons)
Definition: cons.c:6191
SCIP_Real * vals
Definition: struct_lp.h:153
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6591
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2818
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:369
SCIP_Real rellooseobjval
Definition: struct_lp.h:264
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2004
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16975
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8968
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10191
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static const SCIP_Real scalars[]
Definition: lp.c:5736
int lpipos
Definition: struct_lp.h:164
int chgcolssize
Definition: struct_lp.h:312
int lpitiming
Definition: struct_lp.h:338
internal methods for main solving loop and node processing
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:624
SCIP_Longint domchgcount
Definition: struct_stat.h:105
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:215
SCIP_Real * divechgsides
Definition: struct_lp.h:296
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:17467
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8726
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1624
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1731
SCIP_Real rootlpobjval
Definition: struct_lp.h:272
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1837
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:143
unsigned int coefchanged
Definition: struct_lp.h:247
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:151
SCIP_Longint nbarrierlps
Definition: struct_stat.h:190
SCIP_Bool flushed
Definition: struct_lp.h:356
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8517
SCIP_CLOCK * primallptime
Definition: struct_stat.h:155
SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18844
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13816
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6565
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:139
int lpdepth
Definition: struct_lp.h:165
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2542
unsigned int inglobalcutpool
Definition: struct_lp.h:252
int nrows
Definition: struct_lp.h:324
#define checkRowSqrnorm(row)
Definition: lp.c:759
static SCIP_RETCODE lpRemoveObsoleteRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition: lp.c:15508
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:184
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14051
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:182
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3335
data structures for LP management
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4765
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:389
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:230
SCIP_VAR * a
Definition: circlepacking.c:57
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6247
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6276
datastructures for problem variables
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1677
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17116
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17370
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2676
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17434
int ndivingrows
Definition: struct_lp.h:331
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Longint divenolddomchgs
Definition: struct_lp.h:305
SCIP_Real lpobjval
Definition: struct_lp.h:261
static SCIP_RETCODE lpPrimalSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition: lp.c:10311
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:177
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2507
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17740
int size
Definition: struct_lp.h:159
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7793
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6719
SCIP_Longint validsblp
Definition: struct_lp.h:156
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:4028
SCIP_Real lpiobjlim
Definition: struct_lp.h:276
SCIP_VAR ** y
Definition: circlepacking.c:55
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:6117
#define SCIPsetDebugMsgPrint
Definition: set.h:1762
int lpirowssize
Definition: struct_lp.h:309
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: lp.c:5104
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4155
#define BMSallocMemory(ptr)
Definition: memory.h:111
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14287
#define SCIP_INVALID
Definition: def.h:197
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:120
internal methods for constraints and constraint handlers
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5691
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17730
SCIP_CLOCK * duallptime
Definition: struct_stat.h:156
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:162
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18022
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6919
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10288
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3044
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17445
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14924
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2985
SCIP_RETCODE SCIProwCalcIntegralScalar(SCIP_ROW *row, SCIP_SET *set, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Real *intscalar, SCIP_Bool *success)
Definition: lp.c:5740
SCIP_Real varconsratio
Definition: struct_lp.h:285
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:347
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6664
SCIP_VAR * var
Definition: struct_lp.h:151
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9889
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7871
int nlazycols
Definition: struct_lp.h:320
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1231
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:17294
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:340
SCIP_Bool dualfeasible
Definition: struct_lp.h:360
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6664
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4129
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6217
static SCIP_RETCODE ignoreInstability(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool *success)
Definition: lp.c:11540
unsigned int nlocks
Definition: struct_lp.h:254
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2885
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_clp.cpp:3881
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2706
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6941
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3429
SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18833
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3970
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:941
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9914
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14163
SCIP_Longint obsoletenode
Definition: struct_lp.h:212
SCIP_Longint nnodes
Definition: struct_stat.h:73
SCIP_Real lpifeastol
Definition: struct_lp.h:277
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13350
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:918
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4258
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14027
SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18753
static SCIP_RETCODE rowEventConstantChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1487
#define SCIP_CALL_ABORT(x)
Definition: def.h:363
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3193
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17565
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16952
SCIP_RETCODE SCIProwAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
Definition: lp.c:5402
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
unsigned int validminmaxidx
Definition: struct_lp.h:244
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3946
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3227
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:14326
#define SCIP_ALLOC(x)
Definition: def.h:395
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:13125
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6388
#define SCIPABORT()
Definition: def.h:356
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2910
SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7165
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:205
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:343
static SCIP_RETCODE rowChgCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:2235
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:17073
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6831
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2509
unsigned int nonlpcolssorted
Definition: struct_lp.h:242
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:17026
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17442
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:445
SCIP_Bool flushaddedcols
Definition: struct_lp.h:352
static SCIP_RETCODE lpLexDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:10660
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17488
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:349
static SCIP_RETCODE lpDualSimplex(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *lperror)
Definition: lp.c:10469
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9022
int ncols
Definition: struct_lp.h:318
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2601
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4189
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:17201
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17811
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:451
SCIP_Real objsqrnorm
Definition: struct_lp.h:282
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition: set.c:6127
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1355
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3656
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17048
unsigned int local
Definition: struct_lp.h:249
#define EPSZ(x, eps)
Definition: def.h:207
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1638
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3782
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5252
SCIP_Bool probing
Definition: struct_lp.h:368
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:353
SCIP_Real looseobjval
Definition: struct_lp.h:262
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7781
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6730
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3246
static SCIP_RETCODE lpFlushAndSolve(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, int resolveitlim, int harditlim, SCIP_Bool needprimalray, SCIP_Bool needdualray, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12201
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9571
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition: lp.c:16995
SCIP_Real flushedlhs
Definition: struct_lp.h:197
static SCIP_RETCODE lpAlgorithm(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_LPALGO lpalgo, SCIP_Bool resolve, SCIP_Bool keepsol, SCIP_Bool instable, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:11395
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:859
SCIP_RETCODE SCIProwAddConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real addval)
Definition: lp.c:5633
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:948
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5386
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:4183
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:142
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:4024
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:280
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3159
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17424
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:760