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-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file 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 
63 /*
64  * debug messages
65  */
66 
67 #ifdef SCIP_DEBUG
68 /** method is to print in row in case SCIP_DEBUG is defined */
69 static
70 void debugRowPrint(
71  SCIP_SET* set, /**< global SCIP settings */
72  SCIP_ROW* row /**< LP row */
73  )
74 {
75  int i;
76 
77  assert(row != NULL);
78 
79  /* print row name */
80  if( row->name != NULL && row->name[0] != '\0' )
81  {
82  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
83  }
84 
85  /* print left hand side */
86  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
87 
88  /* print coefficients */
89  if( row->len == 0 )
90  {
91  SCIPsetDebugMsgPrint(set, "0 ");
92  }
93  for( i = 0; i < row->len; ++i )
94  {
95  assert(row->cols[i] != NULL);
96  assert(row->cols[i]->var != NULL);
97  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
98  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
99  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
100  }
101 
102  /* print constant */
104  {
105  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
106  }
107 
108  /* print right hand side */
109  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
110 }
111 #else
112 #define debugRowPrint(x,y) /**/
113 #endif
114 
115 #ifdef SCIP_DEBUG
116 /** method to output column if SCIP_DEBUG is define */
117 static
118 void debugColPrint(
119  SCIP_SET* set, /**< global SCIP settings */
120  SCIP_COL* col /**< LP column */
121  )
122 {
123  int r;
124 
125  assert(col != NULL);
126  assert(col->var != NULL);
127 
128  /* print bounds */
129  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
130 
131  /* print coefficients */
132  if( col->len == 0 )
133  {
134  SCIPsetDebugMsgPrint(set, "<empty>");
135  }
136  for( r = 0; r < col->len; ++r )
137  {
138  assert(col->rows[r] != NULL);
139  assert(col->rows[r]->name != NULL);
140  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
141  }
142  SCIPsetDebugMsgPrint(set, "\n");
143 }
144 #else
145 #define debugColPrint(x,y) /**/
146 #endif
147 
148 /*
149  * memory growing methods for dynamically allocated arrays
150  */
151 
152 /** ensures, that chgcols array can store at least num entries */
153 static
155  SCIP_LP* lp, /**< current LP data */
156  SCIP_SET* set, /**< global SCIP settings */
157  int num /**< minimum number of entries to store */
158  )
159 {
160  assert(lp->nchgcols <= lp->chgcolssize);
161 
162  if( num > lp->chgcolssize )
163  {
164  int newsize;
165 
166  newsize = SCIPsetCalcMemGrowSize(set, num);
167  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
168  lp->chgcolssize = newsize;
169  }
170  assert(num <= lp->chgcolssize);
171 
172  return SCIP_OKAY;
173 }
174 
175 /** ensures, that chgrows array can store at least num entries */
176 static
178  SCIP_LP* lp, /**< current LP data */
179  SCIP_SET* set, /**< global SCIP settings */
180  int num /**< minimum number of entries to store */
181  )
182 {
183  assert(lp->nchgrows <= lp->chgrowssize);
184 
185  if( num > lp->chgrowssize )
186  {
187  int newsize;
188 
189  newsize = SCIPsetCalcMemGrowSize(set, num);
190  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
191  lp->chgrowssize = newsize;
192  }
193  assert(num <= lp->chgrowssize);
194 
195  return SCIP_OKAY;
196 }
197 
198 /** ensures, that lpicols array can store at least num entries */
199 static
201  SCIP_LP* lp, /**< current LP data */
202  SCIP_SET* set, /**< global SCIP settings */
203  int num /**< minimum number of entries to store */
204  )
205 {
206  assert(lp->nlpicols <= lp->lpicolssize);
207 
208  if( num > lp->lpicolssize )
209  {
210  int newsize;
211 
212  newsize = SCIPsetCalcMemGrowSize(set, num);
213  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
214  lp->lpicolssize = newsize;
215  }
216  assert(num <= lp->lpicolssize);
217 
218  return SCIP_OKAY;
219 }
220 
221 /** ensures, that lpirows array can store at least num entries */
222 static
224  SCIP_LP* lp, /**< current LP data */
225  SCIP_SET* set, /**< global SCIP settings */
226  int num /**< minimum number of entries to store */
227  )
228 {
229  assert(lp->nlpirows <= lp->lpirowssize);
230 
231  if( num > lp->lpirowssize )
232  {
233  int newsize;
234 
235  newsize = SCIPsetCalcMemGrowSize(set, num);
236  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
237  lp->lpirowssize = newsize;
238  }
239  assert(num <= lp->lpirowssize);
240 
241  return SCIP_OKAY;
242 }
243 
244 /** ensures, that cols array can store at least num entries */
245 static
247  SCIP_LP* lp, /**< current LP data */
248  SCIP_SET* set, /**< global SCIP settings */
249  int num /**< minimum number of entries to store */
250  )
251 {
252  assert(lp->ncols <= lp->colssize);
253 
254  if( num > lp->colssize )
255  {
256  int newsize;
257 
258  newsize = SCIPsetCalcMemGrowSize(set, num);
259  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
260  lp->colssize = newsize;
261  }
262  assert(num <= lp->colssize);
263 
264  return SCIP_OKAY;
265 }
266 
267 /** ensures, that soldirection array can store at least num entries */
268 static
270  SCIP_LP* lp, /**< current LP data */
271  int num /**< minimum number of entries to store */
272  )
273 {
274  if( num > lp->soldirectionsize )
275  {
278 
279  lp->soldirectionsize = num;
280  }
281 
282  assert(num <= lp->soldirectionsize);
283 
284  return SCIP_OKAY;
285 }
286 
287 /** ensures, that lazy cols array can store at least num entries */
288 static
290  SCIP_LP* lp, /**< current LP data */
291  SCIP_SET* set, /**< global SCIP settings */
292  int num /**< minimum number of entries to store */
293  )
294 {
295  assert(lp->nlazycols <= lp->lazycolssize);
296 
297  if( num > lp->lazycolssize )
298  {
299  int newsize;
300 
301  newsize = SCIPsetCalcMemGrowSize(set, num);
302  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
303  lp->lazycolssize = newsize;
304  }
305  assert(num <= lp->lazycolssize);
306 
307  return SCIP_OKAY;
308 }
309 
310 /** ensures, that rows array can store at least num entries */
311 static
313  SCIP_LP* lp, /**< current LP data */
314  SCIP_SET* set, /**< global SCIP settings */
315  int num /**< minimum number of entries to store */
316  )
317 {
318  assert(lp->nrows <= lp->rowssize);
319 
320  if( num > lp->rowssize )
321  {
322  int newsize;
323 
324  newsize = SCIPsetCalcMemGrowSize(set, num);
325  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
326  lp->rowssize = newsize;
327  }
328  assert(num <= lp->rowssize);
329 
330  return SCIP_OKAY;
331 }
332 
333 /** ensures, that row array of column can store at least num entries */
334 static
336  SCIP_COL* col, /**< LP column */
337  BMS_BLKMEM* blkmem, /**< block memory */
338  SCIP_SET* set, /**< global SCIP settings */
339  int num /**< minimum number of entries to store */
340  )
341 {
342  assert(col != NULL);
343  assert(col->len <= col->size);
344 
345  if( num > col->size )
346  {
347  int newsize;
348 
349  newsize = SCIPsetCalcMemGrowSize(set, num);
350  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
351  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
352  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
353  col->size = newsize;
354  }
355  assert(num <= col->size);
356 
357  return SCIP_OKAY;
358 }
359 
360 /** save current LP values dependent on the solution */
361 static
363  SCIP_LP* lp, /**< LP data */
364  SCIP_STAT* stat, /**< problem statistics */
365  BMS_BLKMEM* blkmem /**< block memory */
366  )
367 {
368  SCIP_LPSOLVALS* storedsolvals;
369 
370  assert(lp != NULL);
371  assert(stat != NULL);
372  assert(blkmem != NULL);
373 
374  /* allocate memory for storage */
375  if( lp->storedsolvals == NULL )
376  {
378  }
379  storedsolvals = lp->storedsolvals;
380 
381  /* store values */
382  storedsolvals->lpsolstat = lp->lpsolstat;
383  storedsolvals->lpobjval = lp->lpobjval;
384  storedsolvals->primalfeasible = lp->primalfeasible;
385  storedsolvals->primalchecked = lp->primalchecked;
386  storedsolvals->dualfeasible = lp->dualfeasible;
387  storedsolvals->dualchecked = lp->dualchecked;
388  storedsolvals->solisbasic = lp->solisbasic;
389  storedsolvals->lpissolved = lp->solved;
390 
391  return SCIP_OKAY;
392 }
393 
394 /** restore LP solution values in column */
395 static
397  SCIP_LP* lp, /**< LP data */
398  BMS_BLKMEM* blkmem, /**< block memory */
399  SCIP_Longint validlp /**< number of lp for which restored values are valid */
400  )
401 {
402  SCIP_LPSOLVALS* storedsolvals;
403 
404  assert(lp != NULL);
405  assert(blkmem != NULL);
406 
407  /* if stored values are available, restore them */
408  storedsolvals = lp->storedsolvals;
409  if( storedsolvals != NULL )
410  {
411  lp->solved = storedsolvals->lpissolved;
412  lp->validsollp = validlp;
413 
414  lp->lpsolstat = storedsolvals->lpsolstat;
415  lp->lpobjval = storedsolvals->lpobjval;
416  lp->primalfeasible = storedsolvals->primalfeasible;
417  lp->primalchecked = storedsolvals->primalchecked;
418  lp->dualfeasible = storedsolvals->dualfeasible;
419  lp->dualchecked = storedsolvals->dualchecked;
420  lp->solisbasic = storedsolvals->solisbasic;
421 
422  /* solution values are stored only for LPs solved to optimality or unboundedness */
423  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
429  lp->validsollp == -1);
430  }
431  /* no values available, mark LP as unsolved */
432  else
433  {
434  lp->solved = FALSE;
435  lp->validsollp = -1;
436 
438  lp->lpobjval = SCIP_INVALID;
439  lp->primalfeasible = FALSE;
440  lp->primalchecked = FALSE;
441  lp->dualfeasible = FALSE;
442  lp->dualchecked = FALSE;
443  lp->solisbasic = FALSE;
444  lp->validfarkaslp = -1;
445  }
446 
447  lp->validdegeneracylp = -1;
448 
449  /* intentionally keep storage space allocated */
450 
451  return SCIP_OKAY;
452 }
453 
454 /** save current LP solution values stored in each column */
455 static
457  SCIP_COL* col, /**< LP column */
458  BMS_BLKMEM* blkmem /**< block memory */
459  )
460 {
461  SCIP_COLSOLVALS* storedsolvals;
462 
463  assert(col != NULL);
464  assert(blkmem != NULL);
465 
466  /* allocate memory for storage */
467  if( col->storedsolvals == NULL )
468  {
469  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
470  }
471  storedsolvals = col->storedsolvals;
472 
473  /* store values */
474  storedsolvals->primsol = col->primsol;
475  storedsolvals->redcost = col->redcost;
476  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
477 
478  return SCIP_OKAY;
479 }
480 
481 /** restore LP solution values in column */
482 static
484  SCIP_COL* col, /**< LP column */
485  BMS_BLKMEM* blkmem, /**< block memory */
486  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
487  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
488  )
489 {
490  SCIP_COLSOLVALS* storedsolvals;
491 
492  assert(col != NULL);
493  assert(blkmem != NULL);
494 
495  /* if stored values are available, restore them */
496  storedsolvals = col->storedsolvals;
497  if( storedsolvals != NULL )
498  {
499  col->primsol = storedsolvals->primsol;
500  col->redcost = storedsolvals->redcost;
501  col->validredcostlp = validlp;
502  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
503 
504  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
505  col->validfarkaslp = -1;
506  }
507  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
508  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
509  */
510  else
511  {
512  col->primsol = 0.0;
513  col->validredcostlp = -1;
514  col->validfarkaslp = -1;
515  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
516  }
517 
518  /* free memory */
519  if( freebuffer )
520  {
521  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
522  assert(col->storedsolvals == NULL);
523  }
524 
525  return SCIP_OKAY;
526 }
527 
528 /** save current LP solution values stored in each column */
529 static
531  SCIP_ROW* row, /**< LP row */
532  BMS_BLKMEM* blkmem, /**< block memory */
533  SCIP_Bool infeasible /**< is the solution infeasible? */
534  )
535 {
536  SCIP_ROWSOLVALS* storedsolvals;
537 
538  assert(row != NULL);
539  assert(blkmem != NULL);
540 
541  /* allocate memory for storage */
542  if( row->storedsolvals == NULL )
543  {
544  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
545  }
546  storedsolvals = row->storedsolvals;
547 
548  /* store values */
549  if ( infeasible )
550  {
551  storedsolvals->dualsol = row->dualfarkas;
552  storedsolvals->activity = SCIP_INVALID;
553  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
554  }
555  else
556  {
557  storedsolvals->dualsol = row->dualsol;
558  storedsolvals->activity = row->activity;
559  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
560  }
561 
562  return SCIP_OKAY;
563 }
564 
565 /** restore LP solution values in row */
566 static
568  SCIP_ROW* row, /**< LP column */
569  BMS_BLKMEM* blkmem, /**< block memory */
570  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
571  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
572  SCIP_Bool infeasible /**< is the solution infeasible? */
573  )
574 {
575  SCIP_ROWSOLVALS* storedsolvals;
576 
577  assert(row != NULL);
578  assert(blkmem != NULL);
579 
580  /* if stored values are available, restore them */
581  storedsolvals = row->storedsolvals;
582  if( storedsolvals != NULL )
583  {
584  if ( infeasible )
585  row->dualfarkas = storedsolvals->dualsol;
586  else
587  row->dualsol = storedsolvals->dualsol;
588  row->activity = storedsolvals->activity;
589  row->validactivitylp = validlp;
590  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
591  }
592  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
593  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
594  */
595  else
596  {
597  row->dualsol = 0.0;
598  row->dualfarkas = 0.0;
599  row->activity = SCIP_INVALID;
600  row->validactivitylp = -1;
601  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
602  }
603 
604  /* free memory */
605  if( freebuffer )
606  {
607  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
608  assert(row->storedsolvals == NULL);
609  }
610 
611  return SCIP_OKAY;
612 }
613 
614 /** ensures, that column array of row can store at least num entries */
616  SCIP_ROW* row, /**< LP row */
617  BMS_BLKMEM* blkmem, /**< block memory */
618  SCIP_SET* set, /**< global SCIP settings */
619  int num /**< minimum number of entries to store */
620  )
621 {
622  assert(row != NULL);
623  assert(row->len <= row->size);
624 
625  if( num > row->size )
626  {
627  int newsize;
628 
629  newsize = SCIPsetCalcMemGrowSize(set, num);
630  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
631  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
632  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
633  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
634  row->size = newsize;
635  }
636  assert(num <= row->size);
637 
638  return SCIP_OKAY;
639 }
640 
641 
642 #ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
643 static SCIP_Bool msgdisp_checkrow = FALSE;
644 
645 static
646 void checkRow(
647  SCIP_ROW* row
648  )
649 {
650  int i;
651 
652  if( !msgdisp_checkrow )
653  {
654  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
655  msgdisp_checkrow = TRUE;
656  }
657 
658  /* validate sorting of LP part of row */
659  if( row->lpcolssorted && row->nlpcols > 0)
660  {
661  assert(row->cols_index[0] == row->cols[0]->index);
662  for( i = 1; i < row->nlpcols; ++i )
663  {
664  assert(row->cols_index[i] == row->cols[i]->index);
665  assert(row->cols_index[i] >= row->cols_index[i-1]);
666  }
667  }
668 
669  /* validate sorting of non-LP part of row */
670  if( row->nonlpcolssorted && row->len > row->nlpcols )
671  {
672  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
673  for( i = row->nlpcols + 1; i < row->len; ++i )
674  {
675  assert(row->cols_index[i] == row->cols[i]->index);
676  assert(row->cols_index[i] >= row->cols_index[i-1]);
677  }
678  }
679 }
680 #else
681 #define checkRow(row) /**/
682 #endif
683 
684 #ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
685 static
686 void checkRowSqrnorm(
687  SCIP_ROW* row
688  )
689 {
690  SCIP_COL** cols;
691  SCIP_Real sqrnorm;
692  int c;
693 
694  cols = row->cols;
695  assert(cols != NULL || row->len == 0);
696 
697  sqrnorm = 0.0;
698 
699  for( c = row->len - 1; c >= 0; --c )
700  {
701  if( cols[c]->lppos >= 0 )
702  sqrnorm += SQR(row->vals[c]);
703  }
704 
705  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
706 }
707 
708 static
709 void checkRowSumnorm(
710  SCIP_ROW* row
711  )
712 {
713  SCIP_COL** cols;
714  SCIP_Real sumnorm;
715  int c;
716 
717  cols = row->cols;
718  assert(cols != NULL || row->len == 0);
719 
720  sumnorm = 0.0;
721 
722  for( c = row->len - 1; c >= 0; --c )
723  {
724  if( cols[c]->lppos >= 0 )
725  sumnorm += REALABS(row->vals[c]);
726  }
727 
728  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
729 }
730 
731 static
732 void checkRowObjprod(
733  SCIP_ROW* row
734  )
735 {
736  SCIP_COL** cols;
737  SCIP_Real objprod;
738  int c;
739 
740  cols = row->cols;
741  assert(cols != NULL || row->len == 0);
742 
743  objprod = 0.0;
744 
745  for( c = row->len - 1; c >= 0; --c )
746  {
747  if( cols[c]->lppos >= 0 )
748  objprod += row->vals[c] * cols[c]->unchangedobj;
749  }
750 
751  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
752 }
753 #else
754 #define checkRowSqrnorm(row) /**/
755 #define checkRowSumnorm(row) /**/
756 #define checkRowObjprod(row) /**/
757 #endif
758 
759 /*
760  * Local methods for pseudo and loose objective values
761  */
762 
763 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
764 static
766  SCIP_LP* lp, /**< current LP data */
767  SCIP_SET* set, /**< global SCIP settings */
768  SCIP_PROB* prob /**< problem data */
769  )
770 {
771  SCIP_VAR** vars;
772  SCIP_Real obj;
773  int nvars;
774  int v;
775 
776  assert(lp != NULL);
777  assert(set != NULL);
778  assert(prob != NULL);
779  assert(!lp->looseobjvalid);
780 
781  vars = prob->vars;
782  nvars = prob->nvars;
783  lp->looseobjval = 0.0;
784 
785  /* iterate over all variables in the problem */
786  for( v = 0; v < nvars; ++v )
787  {
788  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
789  {
790  obj = SCIPvarGetObj(vars[v]);
791 
792  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
793  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
794  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
795  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
796  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
797  }
798  }
799 
800  /* the recomputed value is reliable */
801  lp->rellooseobjval = lp->looseobjval;
802  lp->looseobjvalid = TRUE;
803 }
804 
805 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
806 static
808  SCIP_LP* lp, /**< current LP data */
809  SCIP_SET* set, /**< global SCIP settings */
810  SCIP_PROB* prob /**< problem data */
811  )
812 {
813  SCIP_VAR** vars;
814  int nvars;
815  int v;
816 
817  assert(lp != NULL);
818  assert(set != NULL);
819  assert(prob != NULL);
820  assert(!lp->pseudoobjvalid);
821 
822  vars = prob->vars;
823  nvars = prob->nvars;
824  lp->pseudoobjval = 0.0;
825 
826  /* iterate over all variables in the problem */
827  for( v = 0; v < nvars; ++v )
828  {
829  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
830  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
831  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
832  {
833  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
834  }
835  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
836  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
837  {
838  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
839  }
840  }
841 
842  /* the recomputed value is reliable */
843  lp->relpseudoobjval = lp->pseudoobjval;
844  lp->pseudoobjvalid = TRUE;
845 }
846 
847 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
848 static
850  SCIP_LP* lp, /**< current LP data */
851  SCIP_SET* set, /**< global SCIP settings */
852  SCIP_PROB* prob /**< problem data */
853  )
854 {
855  SCIP_VAR** vars;
856  int nvars;
857  int v;
858 
859  assert(lp != NULL);
860  assert(set != NULL);
861  assert(prob != NULL);
862  assert(!lp->glbpseudoobjvalid);
863 
864  vars = prob->vars;
865  nvars = prob->nvars;
866  lp->glbpseudoobjval = 0.0;
867 
868  /* iterate over all variables in the problem */
869  for( v = 0; v < nvars; ++v )
870  {
871  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
872  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
873  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
874  {
875  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
876  }
877  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
878  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
879  {
880  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
881  }
882  }
883 
884  /* the recomputed value is reliable */
886  lp->glbpseudoobjvalid = TRUE;
887 }
888 
889 /** gets finite part of objective value of current LP that results from LOOSE variables only */
890 static
892  SCIP_LP* lp, /**< current LP data */
893  SCIP_SET* set, /**< global SCIP settings */
894  SCIP_PROB* prob /**< problem data */
895  )
896 {
897  assert(lp != NULL);
898  assert(set != NULL);
899  assert(prob != NULL);
900  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
901  assert(lp->flushed);
902  assert(lp->looseobjvalinf == 0);
903 
904  /* recalculate the loose objective value, if needed */
905  if( !lp->looseobjvalid )
906  recomputeLooseObjectiveValue(lp, set, prob);
907 
908  return lp->looseobjval;
909 }
910 
911 /** gets finite part of pseudo objective value of current LP */
912 static
914  SCIP_LP* lp, /**< current LP data */
915  SCIP_SET* set, /**< global SCIP settings */
916  SCIP_PROB* prob /**< problem data */
917  )
918 {
919  assert(lp != NULL);
920  assert(set != NULL);
921  assert(prob != NULL);
922 
923  /* recalculate the pseudo objective value, if needed */
924  if( !lp->pseudoobjvalid )
925  recomputePseudoObjectiveValue(lp, set, prob);
926 
927  return lp->pseudoobjval;
928 }
929 
930 /*
931  * Sorting and searching rows and columns
932  */
933 
934 
935 /** comparison method for sorting rows by non-decreasing index */
937 {
938  assert(elem1 != NULL);
939  assert(elem2 != NULL);
940 
941  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
942  return -1;
943  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
944  return +1;
945  else
946  {
947  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
948  return 0;
949  }
950 }
951 
952 
953 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
954 static
956  SCIP_COL* col /**< column to be sorted */
957  )
958 {
959  int i;
960 
961  assert(col != NULL);
962 
963  /* check, if column is already sorted in the LP part */
964  if( col->lprowssorted )
965  return;
966 
967  /* sort coefficients */
968  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
969 
970  /* update links */
971  for( i = 0; i < col->nlprows; ++i )
972  {
973  if( col->linkpos[i] >= 0 )
974  {
975  assert(col->rows[i]->cols[col->linkpos[i]] == col);
976  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
977  col->rows[i]->linkpos[col->linkpos[i]] = i;
978  }
979  }
980 
981  col->lprowssorted = TRUE;
982 }
983 
984 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
985  * ones
986  */
987 static
989  SCIP_COL* col /**< column to be sorted */
990  )
991 {
992  int i;
993 
994  assert(col != NULL);
995 
996  /* check, if column is already sorted in the non-LP part */
997  if( col->nonlprowssorted )
998  return;
999 
1000  /* sort coefficients */
1001  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
1002 
1003  /* update links */
1004  for( i = col->nlprows; i < col->len; ++i )
1005  {
1006  if( col->linkpos[i] >= 0 )
1007  {
1008  assert(col->rows[i]->cols[col->linkpos[i]] == col);
1009  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1010  col->rows[i]->linkpos[col->linkpos[i]] = i;
1011  }
1012  }
1013 
1014  col->nonlprowssorted = TRUE;
1015 }
1016 
1017 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1018 static
1020  SCIP_ROW* row /**< row to be sorted */
1021  )
1022 {
1023  int i;
1024 
1025  assert(row != NULL);
1026 
1027  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1028  if( row->lpcolssorted || row->delaysort )
1029  return;
1030 
1031  /* sort coefficients */
1032  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1033 
1034  /* update links */
1035  for( i = 0; i < row->nlpcols; ++i )
1036  {
1037  if( row->linkpos[i] >= 0 )
1038  {
1039  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1040  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1041  row->cols[i]->linkpos[row->linkpos[i]] = i;
1042  }
1043  }
1044 
1045  row->lpcolssorted = TRUE;
1046 }
1047 
1048 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1049  * higher ones
1050  */
1051 static
1053  SCIP_ROW* row /**< row to be sorted */
1054  )
1055 {
1056  int i;
1057 
1058  assert(row != NULL);
1059 
1060  checkRow(row);
1061 
1062  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1063  if( row->nonlpcolssorted || row->delaysort )
1064  return;
1065 
1066  /* sort coefficients */
1067  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1068 
1069  /* update links */
1070  for( i = row->nlpcols; i < row->len; ++i )
1071  {
1072  if( row->linkpos[i] >= 0 )
1073  {
1074  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1075  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1076  row->cols[i]->linkpos[row->linkpos[i]] = i;
1077  }
1078  }
1079 
1080  checkRow(row);
1081 
1082  row->nonlpcolssorted = TRUE;
1083 }
1084 
1085 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1086 static
1088  SCIP_COL* col, /**< column to be searched in */
1089  const SCIP_ROW* row, /**< coefficient to be searched for */
1090  int minpos, /**< first position of search range */
1091  int maxpos /**< last position of search range */
1092  )
1093 {
1094  int pos;
1095  int idx;
1096  int searchidx;
1097 
1098  assert(col != NULL);
1099  assert(row != NULL);
1100 
1101  /* binary search */
1102  searchidx = row->index;
1103  while(minpos <= maxpos)
1104  {
1105  pos = (minpos + maxpos)/2;
1106  assert(0 <= pos && pos < col->len);
1107  assert(col->rows[pos] != NULL);
1108  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1109  idx = col->rows[pos]->index;
1110  if( searchidx == idx )
1111  return pos;
1112  else if( searchidx < idx )
1113  maxpos = pos-1;
1114  else
1115  minpos = pos+1;
1116  }
1117 
1118  return -1;
1119 }
1120 
1121 /** searches coefficient in column, returns position in col vector or -1 if not found */
1122 static
1124  SCIP_COL* col, /**< column to be searched in */
1125  const SCIP_ROW* row /**< coefficient to be searched for */
1126  )
1127 {
1128  int pos;
1129 
1130  assert(col != NULL);
1131  assert(row != NULL);
1132 
1133  pos = -1;
1134 
1135  /* search in the linked LP rows */
1136  if( row->lppos >= 0 )
1137  {
1138  /* column has to be sorted, such that binary search works */
1139  colSortLP(col);
1140  assert(col->lprowssorted);
1141 
1142  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1143  if( pos >= 0 )
1144  return pos;
1145  }
1146 
1147  /* search in the non-LP/unlinked rows */
1148  if( row->lppos == -1 || col->nunlinked > 0 )
1149  {
1150  /* column has to be sorted, such that binary search works */
1151  colSortNonLP(col);
1152  assert(col->nonlprowssorted);
1153 
1154  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1155  }
1156 
1157  return pos;
1158 }
1159 
1160 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1161 static
1163  SCIP_ROW* row, /**< row to be searched in */
1164  const SCIP_COL* col, /**< coefficient to be searched for */
1165  int minpos, /**< first position of search range */
1166  int maxpos /**< last position of search range */
1167  )
1168 {
1169  int pos;
1170  int idx;
1171  int searchidx;
1172 
1173  assert(row != NULL);
1174  assert(col != NULL);
1175 
1176  /* binary search */
1177  searchidx = col->index;
1178  while(minpos <= maxpos)
1179  {
1180  pos = (minpos + maxpos)/2;
1181  assert(0 <= pos && pos < row->len);
1182  assert(row->cols[pos] != NULL);
1183  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1184  assert(row->cols_index[pos] == row->cols[pos]->index);
1185  idx = row->cols_index[pos];
1186  if( searchidx == idx )
1187  return pos;
1188  else if( searchidx < idx )
1189  maxpos = pos-1;
1190  else
1191  minpos = pos+1;
1192  }
1193 
1194  return -1;
1195 }
1196 
1197 /** searches coefficient in row, returns position in row vector or -1 if not found;
1198  * if the sorting of the row is delayed, returns -1
1199  */
1200 static
1202  SCIP_ROW* row, /**< row to be searched in */
1203  const SCIP_COL* col /**< coefficient to be searched for */
1204  )
1205 {
1206  int pos;
1207 
1208  assert(row != NULL);
1209  assert(col != NULL);
1210 
1211  if( row->delaysort )
1212  return -1;
1213 
1214  pos = -1;
1215 
1216  /* search in the linked LP columns */
1217  if( col->lppos >= 0 )
1218  {
1219  /* row has to be sorted, such that binary search works */
1220  rowSortLP(row);
1221  assert(row->lpcolssorted);
1222 
1223  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1224  }
1225 
1226  /* search in the non-LP/unlinked columns */
1227  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1228  {
1229  /* row has to be sorted, such that binary search works */
1230  rowSortNonLP(row);
1231  assert(row->nonlpcolssorted);
1232 
1233  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1234  }
1235 
1236 #ifndef NDEBUG
1237  /* validate result */
1238  assert(-1 <= pos && pos < row->len);
1239  if( pos >= 0 )
1240  assert(row->cols[pos] == col);
1241  else
1242  {
1243  int i;
1244  for( i = 0; i < row->len; ++i )
1245  assert(row->cols[i] != col);
1246  }
1247 #endif
1248 
1249  return pos;
1250 }
1251 
1252 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1253 static
1255  SCIP_COL* col, /**< LP column */
1256  int oldpos, /**< old position of coefficient */
1257  int newpos /**< new position of coefficient */
1258  )
1259 {
1260  assert(col != NULL);
1261  assert(0 <= oldpos && oldpos < col->len);
1262  assert(0 <= newpos && newpos < col->len);
1263  assert(col->rows[oldpos] != NULL);
1264 
1265  if( oldpos == newpos )
1266  return;
1267 
1268  col->rows[newpos] = col->rows[oldpos];
1269  col->vals[newpos] = col->vals[oldpos];
1270  col->linkpos[newpos] = col->linkpos[oldpos];
1271 
1272  /* update link position in row */
1273  if( col->linkpos[newpos] >= 0 )
1274  {
1275  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1276  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1277 
1278  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1279  }
1280 
1281  /* update sorted flags */
1282  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1283  col->lprowssorted = FALSE;
1284  else
1285  col->nonlprowssorted = FALSE;
1286 }
1287 
1288 /** swaps two coefficients in a column, and updates all corresponding data structures */
1289 static
1291  SCIP_COL* col, /**< LP column */
1292  int pos1, /**< position of first coefficient */
1293  int pos2 /**< position of second coefficient */
1294  )
1295 {
1296  SCIP_ROW* tmprow;
1297  SCIP_Real tmpval;
1298  int tmplinkpos;
1299 
1300  assert(col != NULL);
1301  assert(0 <= pos1 && pos1 < col->len);
1302  assert(0 <= pos2 && pos2 < col->len);
1303  assert(col->rows[pos1] != NULL);
1304 
1305  if( pos1 == pos2 )
1306  return;
1307 
1308  /* swap coefficients */
1309  tmprow = col->rows[pos2];
1310  tmpval = col->vals[pos2];
1311  tmplinkpos = col->linkpos[pos2];
1312 
1313  col->rows[pos2] = col->rows[pos1];
1314  col->vals[pos2] = col->vals[pos1];
1315  col->linkpos[pos2] = col->linkpos[pos1];
1316 
1317  col->rows[pos1] = tmprow;
1318  col->vals[pos1] = tmpval;
1319  col->linkpos[pos1] = tmplinkpos;
1320 
1321  /* update link position in rows */
1322  if( col->linkpos[pos1] >= 0 )
1323  {
1324  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1325  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1326 
1327  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1328  }
1329  if( col->linkpos[pos2] >= 0 )
1330  {
1331  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1332  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1333 
1334  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1335  }
1336 
1337  /* update sorted flags */
1338  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1339  col->lprowssorted = FALSE;
1340  else
1341  col->nonlprowssorted = FALSE;
1342  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1343  col->lprowssorted = FALSE;
1344  else
1345  col->nonlprowssorted = FALSE;
1346 }
1347 
1348 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1349 static
1351  SCIP_ROW* row, /**< LP row */
1352  int oldpos, /**< old position of coefficient */
1353  int newpos /**< new position of coefficient */
1354  )
1355 {
1356  assert(row != NULL);
1357  assert(0 <= oldpos && oldpos < row->len);
1358  assert(0 <= newpos && newpos < row->len);
1359  assert(row->cols[oldpos] != NULL);
1360 
1361  if( oldpos == newpos )
1362  return;
1363 
1364  row->cols[newpos] = row->cols[oldpos];
1365  row->cols_index[newpos] = row->cols_index[oldpos];
1366  row->vals[newpos] = row->vals[oldpos];
1367  row->linkpos[newpos] = row->linkpos[oldpos];
1368 
1369  /* update link position in column */
1370  if( row->linkpos[newpos] >= 0 )
1371  {
1372  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1373  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1374 
1375  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1376  }
1377 
1378  /* update sorted flags */
1379  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1380  row->lpcolssorted = FALSE;
1381  else
1382  row->nonlpcolssorted = FALSE;
1383 }
1384 
1385 /** swaps two coefficients in a row, and updates all corresponding data structures */
1386 static
1388  SCIP_ROW* row, /**< LP row */
1389  int pos1, /**< position of first coefficient */
1390  int pos2 /**< position of second coefficient */
1391  )
1392 {
1393  SCIP_COL* tmpcol;
1394  SCIP_Real tmpval;
1395  int tmpindex;
1396  int tmplinkpos;
1397 
1398  assert(row != NULL);
1399  assert(0 <= pos1 && pos1 < row->len);
1400  assert(0 <= pos2 && pos2 < row->len);
1401  assert(row->cols[pos1] != NULL);
1402  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1403 
1404  if( pos1 == pos2 )
1405  return;
1406 
1407  /* swap coefficients */
1408  tmpcol = row->cols[pos2];
1409  tmpindex = row->cols_index[pos2];
1410  tmpval = row->vals[pos2];
1411  tmplinkpos = row->linkpos[pos2];
1412 
1413  row->cols[pos2] = row->cols[pos1];
1414  row->cols_index[pos2] = row->cols_index[pos1];
1415  row->vals[pos2] = row->vals[pos1];
1416  row->linkpos[pos2] = row->linkpos[pos1];
1417 
1418  row->cols[pos1] = tmpcol;
1419  row->cols_index[pos1] = tmpindex;
1420  row->vals[pos1] = tmpval;
1421  row->linkpos[pos1] = tmplinkpos;
1422 
1423  /* update link position in columns */
1424  if( row->linkpos[pos1] >= 0 )
1425  {
1426  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1427  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1428 
1429  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1430  }
1431  if( row->linkpos[pos2] >= 0 )
1432  {
1433  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1434  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1435 
1436  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1437  }
1438 
1439  /* update sorted flags */
1440  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1441  row->lpcolssorted = FALSE;
1442  else
1443  row->nonlpcolssorted = FALSE;
1444  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1445  row->lpcolssorted = FALSE;
1446  else
1447  row->nonlpcolssorted = FALSE;
1448 }
1449 
1450 /** issues a ROWCOEFCHANGED event on the given row */
1451 static
1453  SCIP_ROW* row, /**< row which coefficient has changed */
1454  BMS_BLKMEM* blkmem, /**< block memory */
1455  SCIP_SET* set, /**< global SCIP settings */
1456  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1457  SCIP_COL* col, /**< the column which coefficient has changed */
1458  SCIP_Real oldval, /**< old value of the coefficient */
1459  SCIP_Real newval /**< new value of the coefficient */
1460  )
1461 {
1462  assert(row != NULL);
1463  assert(row->eventfilter != NULL);
1464  assert(col != NULL);
1465 
1466  /* check, if the row is being tracked for coefficient changes
1467  * if so, issue ROWCOEFCHANGED event
1468  */
1469  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1470  {
1471  SCIP_EVENT* event;
1472 
1473  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1474  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1475  }
1476 
1477  return SCIP_OKAY;
1478 }
1479 
1480 /** issues a ROWCONSTCHANGED event on the given row */
1481 static
1483  SCIP_ROW* row, /**< row which coefficient has changed */
1484  BMS_BLKMEM* blkmem, /**< block memory */
1485  SCIP_SET* set, /**< global SCIP settings */
1486  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1487  SCIP_Real oldval, /**< old value of the constant */
1488  SCIP_Real newval /**< new value of the constant */
1489  )
1490 {
1491  assert(row != NULL);
1492  assert(row->eventfilter != NULL);
1493 
1494  /* check, if the row is being tracked for coefficient changes
1495  * if so, issue ROWCONSTCHANGED event
1496  */
1497  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED)) )
1498  {
1499  SCIP_EVENT* event;
1500 
1501  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1502  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1503  }
1504 
1505  return SCIP_OKAY;
1506 }
1507 
1508 /** issues a ROWSIDECHANGED event on the given row */
1509 static
1511  SCIP_ROW* row, /**< row which coefficient has changed */
1512  BMS_BLKMEM* blkmem, /**< block memory */
1513  SCIP_SET* set, /**< global SCIP settings */
1514  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1515  SCIP_SIDETYPE side, /**< the side that has changed */
1516  SCIP_Real oldval, /**< old value of side */
1517  SCIP_Real newval /**< new value of side */
1518  )
1519 {
1520  assert(row != NULL);
1521  assert(row->eventfilter != NULL);
1522 
1523  /* check, if the row is being tracked for coefficient changes
1524  * if so, issue ROWSIDECHANGED event
1525  */
1526  if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
1527  {
1528  SCIP_EVENT* event;
1529 
1530  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1531  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1532  }
1533 
1534  return SCIP_OKAY;
1535 }
1536 
1537 #ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1538 
1539 #ifdef NDEBUG
1540 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1541 #else
1542 #define ASSERT(x) assert(x)
1543 #endif
1544 
1545 static SCIP_Bool msgdisp_checklinks = FALSE;
1546 
1547 
1548 static
1549 void checkLinks(
1550  SCIP_LP* lp /**< current LP data */
1551  )
1552 {
1553  SCIP_COL* col;
1554  SCIP_ROW* row;
1555  int i;
1556  int j;
1557 
1558  ASSERT(lp != NULL);
1559 
1560  if( !msgdisp_checklinks )
1561  {
1562  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1563  msgdisp_checklinks = TRUE;
1564  }
1565 
1566  for( i = 0; i < lp->ncols; ++i )
1567  {
1568  col = lp->cols[i];
1569  ASSERT(col != NULL);
1570  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1571  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1572  ASSERT(col->nlprows <= col->len);
1573  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1574 
1575  for( j = 0; j < col->len; ++j )
1576  {
1577  row = col->rows[j];
1578  ASSERT(row != NULL);
1579  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1580  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1581  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1582  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1583  }
1584  }
1585 
1586  for( i = 0; i < lp->nrows; ++i )
1587  {
1588  row = lp->rows[i];
1589  ASSERT(row != NULL);
1590  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1591  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1592  ASSERT(row->nlpcols <= row->len);
1593  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1594 
1595  for( j = 0; j < row->len; ++j )
1596  {
1597  col = row->cols[j];
1598  ASSERT(col != NULL);
1599  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1600  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1601  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1602  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1603  }
1604  }
1605 }
1606 
1607 #undef ASSERT
1608 
1609 #else
1610 #define checkLinks(lp) /**/
1611 #endif
1612 
1613 /*
1614  * Changing announcements
1615  */
1616 
1617 /** announces, that the given coefficient in the constraint matrix changed */
1618 static
1620  SCIP_ROW* row, /**< LP row */
1621  SCIP_COL* col, /**< LP col */
1622  SCIP_LP* lp /**< current LP data */
1623  )
1624 {
1625  assert(row != NULL);
1626  assert(col != NULL);
1627  assert(lp != NULL);
1628 
1629  if( row->lpipos >= 0 && col->lpipos >= 0 )
1630  {
1631  assert(row->lpipos < lp->nlpirows);
1632  assert(col->lpipos < lp->nlpicols);
1633 
1634  /* we have to remember the change only in the row or in the column,
1635  * because the readdition of one vector would change the other automatically.
1636  */
1637  if( row->lpipos >= lp->lpifirstchgrow )
1638  row->coefchanged = TRUE;
1639  else if( col->lpipos >= lp->lpifirstchgcol )
1640  col->coefchanged = TRUE;
1641  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1642  {
1643  row->coefchanged = TRUE;
1644  lp->lpifirstchgrow = row->lpipos;
1645  }
1646  else
1647  {
1648  col->coefchanged = TRUE;
1649  lp->lpifirstchgcol = col->lpipos;
1650  }
1651 
1652  /* mark the current LP unflushed */
1653  lp->flushed = FALSE;
1654  }
1655 
1657  row->minactivity = SCIP_INVALID;
1658  row->maxactivity = SCIP_INVALID;
1659  row->validpsactivitydomchg = -1;
1660  row->validactivitybdsdomchg = -1;
1661 }
1662 
1663 
1664 
1665 /*
1666  * local column changing methods
1667  */
1668 
1669 /* forward declaration for colAddCoef() */
1670 static
1672  SCIP_ROW* row, /**< LP row */
1673  BMS_BLKMEM* blkmem, /**< block memory */
1674  SCIP_SET* set, /**< global SCIP settings */
1675  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1676  SCIP_LP* lp, /**< current LP data */
1677  SCIP_COL* col, /**< LP column */
1678  SCIP_Real val, /**< value of coefficient */
1679  int linkpos /**< position of row in the column's row array, or -1 */
1680  );
1681 
1682 /** adds a previously non existing coefficient to an LP column */
1683 static
1685  SCIP_COL* col, /**< LP column */
1686  BMS_BLKMEM* blkmem, /**< block memory */
1687  SCIP_SET* set, /**< global SCIP settings */
1688  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1689  SCIP_LP* lp, /**< current LP data */
1690  SCIP_ROW* row, /**< LP row */
1691  SCIP_Real val, /**< value of coefficient */
1692  int linkpos /**< position of column in the row's col array, or -1 */
1693  )
1694 {
1695  int pos;
1696 
1697  assert(blkmem != NULL);
1698  assert(col != NULL);
1699  assert(col->nlprows <= col->len);
1700  assert(col->var != NULL);
1701  assert(row != NULL);
1702  assert(!SCIPsetIsZero(set, val));
1703  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1704 
1705  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1706  assert(col->rows != NULL);
1707  assert(col->vals != NULL);
1708  assert(col->linkpos != NULL);
1709 
1710  pos = col->len;
1711  col->len++;
1712 
1713  /* 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
1714  * part of the column's arrays
1715  */
1716  if( row->lppos >= 0 && linkpos >= 0 )
1717  {
1718  /* move the first non-LP/not linked row to the end */
1719  if( col->nlprows < pos )
1720  {
1721  colMoveCoef(col, col->nlprows, pos);
1722  pos = col->nlprows;
1723  }
1724  col->nlprows++;
1725  }
1726 
1727  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1728  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1729 
1730  /* insert the row at the correct position and update the links */
1731  col->rows[pos] = row;
1732  col->vals[pos] = val;
1733  col->linkpos[pos] = linkpos;
1734  if( linkpos == -1 )
1735  {
1736  col->nunlinked++;
1737 
1738  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1739  * of the row is not complete
1740  */
1741  if( col->lppos >= 0 )
1742  {
1743  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1744  * has to be updated
1745  */
1746  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1747  if( row->lppos >= 0 )
1748  pos = col->nlprows-1;
1749  linkpos = col->linkpos[pos];
1750 
1751  assert(0 <= linkpos && linkpos < row->len);
1752  assert(row->cols[linkpos] == col);
1753  assert(col->rows[pos] == row);
1754  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1755  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1756  }
1757  }
1758  else
1759  {
1760  assert(row->linkpos[linkpos] == -1);
1761  assert(row->nunlinked > 0);
1762  row->linkpos[linkpos] = pos;
1763  row->nunlinked--;
1764 
1765  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1766  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1767  */
1768  if( col->lppos >= 0 )
1769  {
1770  row->nlpcols++;
1771  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1772 
1773  /* if no swap was necessary, mark nonlpcols to be unsorted */
1774  if( linkpos == row->nlpcols-1 )
1775  row->lpcolssorted = FALSE;
1776  }
1777  }
1778 
1779  /* update the sorted flags */
1780  if( row->lppos >= 0 && linkpos >= 0 )
1781  {
1782  assert(col->nlprows >= 1);
1783  assert(col->rows[col->nlprows-1] == row);
1784  if( col->nlprows > 1 )
1785  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1786  }
1787  else
1788  {
1789  assert(col->len - col->nlprows >= 1);
1790  assert(col->rows[col->len-1] == row);
1791  if( col->len - col->nlprows > 1 )
1792  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1793  }
1794 
1795  coefChanged(row, col, lp);
1796 
1797  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1798  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1799 
1800  return SCIP_OKAY;
1801 }
1802 
1803 /** deletes coefficient at given position from column */
1804 static
1806  SCIP_COL* col, /**< column to be changed */
1807  SCIP_SET* set, /**< global SCIP settings */
1808  SCIP_LP* lp, /**< current LP data */
1809  int pos /**< position in column vector to delete */
1810  )
1811 {
1812  SCIP_ROW* row;
1813 
1814  assert(col != NULL);
1815  assert(col->var != NULL);
1816  assert(set != NULL);
1817  assert(0 <= pos && pos < col->len);
1818  assert(col->rows[pos] != NULL);
1819  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1820  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1821 
1822  row = col->rows[pos];
1823  assert((row->lppos >= 0) == (pos < col->nlprows));
1824 
1825  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1826  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1827 
1828  if( col->linkpos[pos] == -1 )
1829  col->nunlinked--;
1830 
1831  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1832  if( pos < col->nlprows )
1833  {
1834  colMoveCoef(col, col->nlprows-1, pos);
1835  col->nlprows--;
1836  pos = col->nlprows;
1837  }
1838 
1839  /* move last coefficient to position of empty slot */
1840  colMoveCoef(col, col->len-1, pos);
1841  col->len--;
1842 
1843  coefChanged(row, col, lp);
1844 
1845  return SCIP_OKAY;
1846 }
1847 
1848 /** changes a coefficient at given position of an LP column */
1849 static
1851  SCIP_COL* col, /**< LP column */
1852  SCIP_SET* set, /**< global SCIP settings */
1853  SCIP_LP* lp, /**< current LP data */
1854  int pos, /**< position in column vector to change */
1855  SCIP_Real val /**< value of coefficient */
1856  )
1857 {
1858  assert(col != NULL);
1859  assert(col->var != NULL);
1860  assert(0 <= pos && pos < col->len);
1861  assert(col->rows[pos] != NULL);
1862  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1863 
1864  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1865  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1866 
1867  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1868  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1869 
1870  if( SCIPsetIsZero(set, val) )
1871  {
1872  /* delete existing coefficient */
1873  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1874  }
1875  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1876  {
1877  /* change existing coefficient */
1878  col->vals[pos] = val;
1879  coefChanged(col->rows[pos], col, lp);
1880  }
1881 
1882  return SCIP_OKAY;
1883 }
1884 
1885 
1886 
1887 
1888 /*
1889  * local row changing methods
1890  */
1891 
1892 /** update row norms after addition of coefficient */
1893 static
1895  SCIP_ROW* row, /**< LP row */
1896  SCIP_SET* set, /**< global SCIP settings */
1897  SCIP_COL* col, /**< column of added coefficient */
1898  SCIP_Real val, /**< value of added coefficient */
1899  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1900  )
1901 {
1902  SCIP_Real absval;
1903 
1904  assert(row != NULL);
1905  assert(row->nummaxval >= 0);
1906  assert(row->numminval >= 0);
1907  assert(set != NULL);
1908  assert(col != NULL);
1909 
1910  absval = REALABS(val);
1911  assert(!SCIPsetIsZero(set, absval));
1912 
1913  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1914  if( col->lppos >= 0 )
1915  {
1916  /* update squared Euclidean norm and sum norm */
1917  row->sqrnorm += SQR(absval);
1918  row->sumnorm += absval;
1919 
1920  /* update objective function scalar product */
1921  row->objprod += val * col->unchangedobj;
1922  }
1923 
1924  if( updateidxvals )
1925  {
1926  /* update min/maxidx */
1927  row->minidx = MIN(row->minidx, col->index);
1928  row->maxidx = MAX(row->maxidx, col->index);
1929 
1930  /* update maximal and minimal non-zero value */
1931  if( row->nummaxval > 0 )
1932  {
1933  if( SCIPsetIsGT(set, absval, row->maxval) )
1934  {
1935  row->maxval = absval;
1936  row->nummaxval = 1;
1937  }
1938  else if( SCIPsetIsGE(set, absval, row->maxval) )
1939  {
1940  /* make sure the maxval is always exactly the same */
1941  row->maxval = MAX(absval, row->maxval);
1942  row->nummaxval++;
1943  }
1944  }
1945  if( row->numminval > 0 )
1946  {
1947  if( SCIPsetIsLT(set, absval, row->minval) )
1948  {
1949  row->minval = absval;
1950  row->numminval = 1;
1951  }
1952  else if( SCIPsetIsLE(set, absval, row->minval) )
1953  {
1954  /* make sure the minval is always exactly the same */
1955  row->minval = MIN(absval, row->minval);
1956  row->numminval++;
1957  }
1958  }
1959  }
1960  else
1961  {
1962  assert(row->minidx <= col->index);
1963  assert(row->maxidx >= col->index);
1964  assert(row->numminval <= 0 || absval >= row->minval);
1965  assert(row->nummaxval <= 0 || absval <= row->maxval);
1966  }
1967 }
1968 
1969 /** update row norms after deletion of coefficient */
1970 static
1972  SCIP_ROW* row, /**< LP row */
1973  SCIP_SET* set, /**< global SCIP settings */
1974  SCIP_COL* col, /**< column of deleted coefficient */
1975  SCIP_Real val, /**< value of deleted coefficient */
1976  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1977  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1978  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1979  )
1980 {
1981  SCIP_Real absval;
1982 
1983  assert(row != NULL);
1984  assert(row->nummaxval >= 0);
1985  assert(row->numminval >= 0);
1986  assert(set != NULL);
1987  assert(col != NULL);
1988 
1989  absval = REALABS(val);
1990  assert(!SCIPsetIsZero(set, absval));
1991  assert(row->nummaxval == 0 || row->maxval >= absval);
1992  assert(row->numminval == 0 || row->minval <= absval);
1993 
1994  /* update min/maxidx validity */
1995  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
1996  row->validminmaxidx = FALSE;
1997 
1998  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1999  if( forcenormupdate || col->lppos >= 0 )
2000  {
2001  /* update squared Euclidean norm and sum norm */
2002  row->sqrnorm -= SQR(absval);
2003  row->sqrnorm = MAX(row->sqrnorm, 0.0);
2004  row->sumnorm -= absval;
2005  row->sumnorm = MAX(row->sumnorm, 0.0);
2006 
2007  /* update objective function scalar product */
2008  row->objprod -= val * col->unchangedobj;
2009  }
2010 
2011  if( updateval )
2012  {
2013  /* update maximal and minimal non-zero value */
2014  if( row->nummaxval > 0 )
2015  {
2016  if( SCIPsetIsGE(set, absval, row->maxval) )
2017  row->nummaxval--;
2018  }
2019  if( row->numminval > 0 )
2020  {
2021  if( SCIPsetIsLE(set, absval, row->minval) )
2022  row->numminval--;
2023  }
2024  }
2025 }
2026 
2027 /** adds a previously non existing coefficient to an LP row */
2028 static
2030  SCIP_ROW* row, /**< LP row */
2031  BMS_BLKMEM* blkmem, /**< block memory */
2032  SCIP_SET* set, /**< global SCIP settings */
2033  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2034  SCIP_LP* lp, /**< current LP data */
2035  SCIP_COL* col, /**< LP column */
2036  SCIP_Real val, /**< value of coefficient */
2037  int linkpos /**< position of row in the column's row array, or -1 */
2038  )
2039 {
2040  int pos;
2041 
2042  assert(row != NULL);
2043  assert(row->nlpcols <= row->len);
2044  assert(blkmem != NULL);
2045  assert(col != NULL);
2046  assert(col->var != NULL);
2047  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2048  assert(!SCIPsetIsZero(set, val));
2049  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2050 
2051  if( row->nlocks > 0 )
2052  {
2053  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2054  return SCIP_INVALIDDATA;
2055  }
2056 
2057  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2058  assert(row->cols != NULL);
2059  assert(row->vals != NULL);
2060 
2061  pos = row->len;
2062  row->len++;
2063 
2064  /* 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
2065  * part of the row's arrays
2066  */
2067  if( col->lppos >= 0 && linkpos >= 0 )
2068  {
2069  /* move the first non-LP/not linked column to the end */
2070  if( row->nlpcols < pos )
2071  {
2072  rowMoveCoef(row, row->nlpcols, pos);
2073  pos = row->nlpcols;
2074  }
2075  row->nlpcols++;
2076  }
2077 
2078  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2079  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2080 
2081  /* insert the column at the correct position and update the links */
2082  row->cols[pos] = col;
2083  row->cols_index[pos] = col->index;
2084  row->vals[pos] = val;
2085  row->linkpos[pos] = linkpos;
2086  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2087  if( linkpos == -1 )
2088  {
2089  row->nunlinked++;
2090 
2091  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2092  * of the column is not complete
2093  */
2094  if( row->lppos >= 0 )
2095  {
2096  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2097  * has to be updated
2098  */
2099  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2100  if( col->lppos >= 0 )
2101  pos = row->nlpcols-1;
2102  linkpos = row->linkpos[pos];
2103 
2104  assert(0 <= linkpos && linkpos < col->len);
2105  assert(col->rows[linkpos] == row);
2106  assert(row->cols[pos] == col);
2107  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2108  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2109  }
2110  }
2111  else
2112  {
2113  assert(col->linkpos[linkpos] == -1);
2114  assert(col->nunlinked > 0);
2115  col->linkpos[linkpos] = pos;
2116  col->nunlinked--;
2117 
2118  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2119  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2120  */
2121  if( row->lppos >= 0 )
2122  {
2123  col->nlprows++;
2124  colSwapCoefs(col, linkpos, col->nlprows-1);
2125 
2126  /* if no swap was necessary, mark lprows to be unsorted */
2127  if( linkpos == col->nlprows-1 )
2128  col->lprowssorted = FALSE;
2129  }
2130  }
2131 
2132  /* update the sorted flags */
2133  if( col->lppos >= 0 && linkpos >= 0 )
2134  {
2135  assert(row->nlpcols >= 1);
2136  assert(row->cols[row->nlpcols-1] == col);
2137  if( row->nlpcols > 1 )
2138  {
2139  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2140  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2141  }
2142  }
2143  else
2144  {
2145  assert(row->len - row->nlpcols >= 1);
2146  assert(row->cols[row->len-1] == col);
2147  if( row->len - row->nlpcols > 1 )
2148  {
2149  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2150  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2151  }
2152  }
2153 
2154  /* update row norm */
2155  rowAddNorms(row, set, col, val, TRUE);
2156 
2157  coefChanged(row, col, lp);
2158 
2159  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2160  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2161 
2162  /* issue row coefficient changed event */
2163  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2164 
2165  return SCIP_OKAY;
2166 }
2167 
2168 /** deletes coefficient at given position from row */
2169 static
2171  SCIP_ROW* row, /**< row to be changed */
2172  BMS_BLKMEM* blkmem, /**< block memory */
2173  SCIP_SET* set, /**< global SCIP settings */
2174  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2175  SCIP_LP* lp, /**< current LP data */
2176  int pos /**< position in row vector to delete */
2177  )
2178 {
2179  SCIP_COL* col;
2180  SCIP_Real val;
2181 
2182  assert(row != NULL);
2183  assert(set != NULL);
2184  assert(0 <= pos && pos < row->len);
2185  assert(row->cols[pos] != NULL);
2186  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2187 
2188  col = row->cols[pos];
2189  val = row->vals[pos];
2190  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2191 
2192  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2193  val, SCIPvarGetName(col->var), pos, row->name);*/
2194 
2195  if( row->nlocks > 0 )
2196  {
2197  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2198  return SCIP_INVALIDDATA;
2199  }
2200 
2201  if( row->linkpos[pos] == -1 )
2202  row->nunlinked--;
2203 
2204  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2205  if( pos < row->nlpcols )
2206  {
2207  rowMoveCoef(row, row->nlpcols-1, pos);
2208  assert(!row->lpcolssorted);
2209  row->nlpcols--;
2210  pos = row->nlpcols;
2211  }
2212 
2213  /* move last coefficient to position of empty slot */
2214  rowMoveCoef(row, row->len-1, pos);
2215  row->len--;
2216 
2217  /* update norms */
2218  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2219 
2220  coefChanged(row, col, lp);
2221 
2222  /* issue row coefficient changed event */
2223  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2224 
2225  return SCIP_OKAY;
2226 }
2227 
2228 /** changes a coefficient at given position of an LP row */
2229 static
2231  SCIP_ROW* row, /**< LP row */
2232  BMS_BLKMEM* blkmem, /**< block memory */
2233  SCIP_SET* set, /**< global SCIP settings */
2234  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2235  SCIP_LP* lp, /**< current LP data */
2236  int pos, /**< position in row vector to change */
2237  SCIP_Real val /**< value of coefficient */
2238  )
2239 {
2240  SCIP_COL* col;
2241 
2242  assert(row != NULL);
2243  assert(0 <= pos && pos < row->len);
2244 
2245  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2246  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2247 
2248  if( row->nlocks > 0 )
2249  {
2250  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2251  return SCIP_INVALIDDATA;
2252  }
2253 
2254  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2255  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2256  col = row->cols[pos];
2257  assert(row->cols[pos] != NULL);
2258 
2259  if( SCIPsetIsZero(set, val) )
2260  {
2261  /* delete existing coefficient */
2262  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2263  }
2264  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2265  {
2266  SCIP_Real oldval;
2267 
2268  oldval = row->vals[pos];
2269 
2270  /* change existing coefficient */
2271  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2272  row->vals[pos] = val;
2273  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2274  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2275  coefChanged(row, col, lp);
2276 
2277  /* issue row coefficient changed event */
2278  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2279  }
2280 
2281  return SCIP_OKAY;
2282 }
2283 
2284 /** notifies LP row, that its sides were changed */
2285 static
2287  SCIP_ROW* row, /**< LP row */
2288  SCIP_SET* set, /**< global SCIP settings */
2289  SCIP_LP* lp, /**< current LP data */
2290  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2291  )
2292 {
2293  assert(row != NULL);
2294  assert(lp != NULL);
2295 
2296  if( row->lpipos >= 0 )
2297  {
2298  /* insert row in the chgrows list (if not already there) */
2299  if( !row->lhschanged && !row->rhschanged )
2300  {
2301  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2302  lp->chgrows[lp->nchgrows] = row;
2303  lp->nchgrows++;
2304  }
2305 
2306  /* mark side change in the row */
2307  switch( sidetype )
2308  {
2309  case SCIP_SIDETYPE_LEFT:
2310  row->lhschanged = TRUE;
2311  break;
2312  case SCIP_SIDETYPE_RIGHT:
2313  row->rhschanged = TRUE;
2314  break;
2315  default:
2316  SCIPerrorMessage("unknown row side type\n");
2317  SCIPABORT();
2318  return SCIP_INVALIDDATA; /*lint !e527*/
2319  }
2320 
2321  /* mark the current LP unflushed */
2322  lp->flushed = FALSE;
2323 
2324  assert(lp->nchgrows > 0);
2325  }
2326 
2327  return SCIP_OKAY;
2328 }
2329 
2330 
2331 
2332 
2333 /*
2334  * double linked coefficient matrix methods
2335  */
2336 
2337 /** insert column coefficients in corresponding rows */
2338 static
2340  SCIP_COL* col, /**< column data */
2341  BMS_BLKMEM* blkmem, /**< block memory */
2342  SCIP_SET* set, /**< global SCIP settings */
2343  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2344  SCIP_LP* lp /**< current LP data */
2345  )
2346 {
2347  int i;
2348 
2349  assert(col != NULL);
2350  assert(col->var != NULL);
2351  assert(blkmem != NULL);
2352  assert(set != NULL);
2353  assert(lp != NULL);
2354 
2355  if( col->nunlinked > 0 )
2356  {
2357  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2358 
2359  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2360  for( i = col->nlprows; i < col->len; ++i )
2361  {
2362  assert(!SCIPsetIsZero(set, col->vals[i]));
2363  if( col->linkpos[i] == -1 )
2364  {
2365  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2366  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2367  }
2368  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2369  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2370  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2371  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2372  }
2373  }
2374  assert(col->nunlinked == 0);
2375 
2376  checkLinks(lp);
2377 
2378  return SCIP_OKAY;
2379 }
2380 
2381 /** removes column coefficients from corresponding rows */
2382 static
2384  SCIP_COL* col, /**< column data */
2385  BMS_BLKMEM* blkmem, /**< block memory */
2386  SCIP_SET* set, /**< global SCIP settings */
2387  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2388  SCIP_LP* lp /**< current LP data */
2389  )
2390 {
2391  int i;
2392 
2393  assert(col != NULL);
2394  assert(col->var != NULL);
2395  assert(blkmem != NULL);
2396  assert(set != NULL);
2397  assert(lp != NULL);
2398 
2399  if( col->nunlinked < col->len )
2400  {
2401  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2402  for( i = 0; i < col->len; ++i )
2403  {
2404  if( col->linkpos[i] >= 0 )
2405  {
2406  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2407  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2408  col->linkpos[i] = -1;
2409  col->nunlinked++;
2410  }
2411  }
2412  }
2413  assert(col->nunlinked == col->len);
2414 
2415  checkLinks(lp);
2416 
2417  return SCIP_OKAY;
2418 }
2419 
2420 /** insert row coefficients in corresponding columns */
2421 static
2423  SCIP_ROW* row, /**< row data */
2424  BMS_BLKMEM* blkmem, /**< block memory */
2425  SCIP_SET* set, /**< global SCIP settings */
2426  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2427  SCIP_LP* lp /**< current LP data */
2428  )
2429 {
2430  int i;
2431 
2432  assert(row != NULL);
2433  assert(blkmem != NULL);
2434  assert(set != NULL);
2435  assert(lp != NULL);
2436 
2437  if( row->nunlinked > 0 )
2438  {
2439  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2440 
2441  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2442  for( i = row->nlpcols; i < row->len; ++i )
2443  {
2444  assert(!SCIPsetIsZero(set, row->vals[i]));
2445  if( row->linkpos[i] == -1 )
2446  {
2447  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2448  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2449  }
2450  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2451  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2452  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2453  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2454  }
2455  }
2456  assert(row->nunlinked == 0);
2457 
2458  checkLinks(lp);
2459 
2460  return SCIP_OKAY;
2461 }
2462 
2463 /** removes row coefficients from corresponding columns */
2464 static
2466  SCIP_ROW* row, /**< row data */
2467  SCIP_SET* set, /**< global SCIP settings */
2468  SCIP_LP* lp /**< current LP data */
2469  )
2470 {
2471  int i;
2472 
2473  assert(row != NULL);
2474  assert(set != NULL);
2475  assert(lp != NULL);
2476 
2477  if( row->nunlinked < row->len )
2478  {
2479  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2480  for( i = 0; i < row->len; ++i )
2481  {
2482  if( row->linkpos[i] >= 0 )
2483  {
2484  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2485  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2486  row->nunlinked++;
2487  }
2488  }
2489  }
2490  assert(row->nunlinked == row->len);
2491 
2492  return SCIP_OKAY;
2493 }
2494 
2495 
2496 
2497 
2498 /*
2499  * local LP parameter methods
2500  */
2501 
2502 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2503 static
2505  SCIP_LP* lp, /**< current LP data */
2506  SCIP_LPPARAM lpparam, /**< LP parameter */
2507  int value, /**< value to set parameter to */
2508  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2509  )
2510 {
2511  SCIP_RETCODE retcode;
2512 
2513  assert(lp != NULL);
2514  assert(success != NULL);
2515 
2516  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2517 
2518  /* check, if parameter is unknown */
2519  if( retcode == SCIP_PARAMETERUNKNOWN )
2520  {
2521  *success = FALSE;
2522  return SCIP_OKAY;
2523  }
2524  *success = TRUE;
2525 
2526  return retcode;
2527 }
2528 
2529 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2530 static
2532  SCIP_LP* lp, /**< current LP data */
2533  SCIP_LPPARAM lpparam, /**< LP parameter */
2534  SCIP_Bool value, /**< value to set parameter to */
2535  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2536  )
2537 {
2538  return lpSetIntpar(lp, lpparam, (int)value, success);
2539 }
2540 
2541 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2542 static
2544  SCIP_LP* lp, /**< current LP data */
2545  SCIP_LPPARAM lpparam, /**< LP parameter */
2546  SCIP_Real value, /**< value to set parameter to */
2547  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2548  )
2549 {
2550  SCIP_RETCODE retcode;
2551 
2552  assert(lp != NULL);
2553  assert(success != NULL);
2554 
2555  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2556 
2557  /* check, if parameter is unknown */
2558  if( retcode == SCIP_PARAMETERUNKNOWN )
2559  {
2560  *success = FALSE;
2561  return SCIP_OKAY;
2562  }
2563  *success = TRUE;
2564 
2565  return retcode;
2566 }
2567 
2568 #ifndef NDEBUG
2569 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2570 static
2572  SCIP_LP* lp, /**< current LP data */
2573  SCIP_LPPARAM lpparam, /**< LP parameter */
2574  int value /**< value parameter should have */
2575  )
2576 {
2577  SCIP_RETCODE retcode;
2578  int lpivalue;
2579 
2580  assert(lp != NULL);
2581 
2582  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2583 
2584  /* ignore unknown parameter error */
2585  if( retcode == SCIP_PARAMETERUNKNOWN )
2586  return SCIP_OKAY;
2587 
2588  /* check value */
2589  assert(lpivalue == value);
2590 
2591  return retcode;
2592 }
2593 
2594 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2595 static
2597  SCIP_LP* lp, /**< current LP data */
2598  SCIP_LPPARAM lpparam, /**< LP parameter */
2599  SCIP_Bool value /**< value parameter should have */
2600  )
2601 {
2602  return lpCheckIntpar(lp, lpparam, (int)value);
2603 }
2604 
2605 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2606 static
2608  SCIP_LP* lp, /**< current LP data */
2609  SCIP_LPPARAM lpparam, /**< LP parameter */
2610  SCIP_Real value /**< value parameter should have */
2611  )
2612 {
2613  SCIP_RETCODE retcode;
2614  SCIP_Real lpivalue;
2615 
2616  assert(lp != NULL);
2617 
2618  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2619 
2620  /* ignore unknown parameter error */
2621  if( retcode == SCIP_PARAMETERUNKNOWN )
2622  return SCIP_OKAY;
2623 
2624  /* check value */
2625  assert(lpivalue == value); /*lint !e777*/
2626 
2627  return retcode;
2628 }
2629 #else
2630 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2631 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2632 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2633 #endif
2634 
2635 /** should the objective limit of the LP solver be disabled */
2636 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2637 
2638 /** sets the objective limit of the LP solver
2639  *
2640  * Note that we are always minimizing.
2641  */
2642 static
2644  SCIP_LP* lp, /**< current LP data */
2645  SCIP_SET* set, /**< global SCIP settings */
2646  SCIP_Real objlim, /**< new objective limit */
2647  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2648  )
2649 {
2650  assert(lp != NULL);
2651  assert(set != NULL);
2652  assert(success != NULL);
2653 
2654  *success = FALSE;
2655 
2656  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2657  * solver's objective limit handling, so we return here and do not apply the objective limit. */
2658  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2659  return SCIP_OKAY;
2660 
2661  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2662  if( SCIPsetIsInfinity(set, objlim) )
2663  objlim = SCIPlpiInfinity(lp->lpi);
2664 
2666 
2667  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2668  {
2669  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2670  if( *success )
2671  {
2672  SCIP_Real actualobjlim;
2673 
2674  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2675  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2676  if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2677  {
2678  /* mark the current solution invalid */
2679  lp->solved = FALSE;
2680  lp->primalfeasible = FALSE;
2681  lp->primalchecked = FALSE;
2682  lp->lpobjval = SCIP_INVALID;
2684  }
2685  lp->lpiobjlim = actualobjlim;
2686  }
2687  }
2688 
2689  return SCIP_OKAY;
2690 }
2691 
2692 /** sets the feasibility tolerance of the LP solver */
2693 static
2695  SCIP_LP* lp, /**< current LP data */
2696  SCIP_Real feastol, /**< new feasibility tolerance */
2697  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2698  )
2699 {
2700  assert(lp != NULL);
2701  assert(feastol >= 0.0);
2702  assert(success != NULL);
2703 
2705 
2706  if( feastol != lp->lpifeastol ) /*lint !e777*/
2707  {
2708  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2709  if( *success )
2710  {
2711  SCIP_Real actualfeastol;
2712 
2713  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2714  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2715  if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2716  {
2717  /* mark the current solution invalid */
2718  lp->solved = FALSE;
2719  lp->primalfeasible = FALSE;
2720  lp->primalchecked = FALSE;
2721  lp->lpobjval = SCIP_INVALID;
2723  }
2724  else
2725  *success = FALSE;
2726  lp->lpifeastol = actualfeastol;
2727  }
2728  }
2729  else
2730  *success = FALSE;
2731 
2732  return SCIP_OKAY;
2733 }
2734 
2735 /** sets the reduced costs feasibility tolerance of the LP solver */
2736 static
2738  SCIP_LP* lp, /**< current LP data */
2739  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2740  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2741  )
2742 {
2743  assert(lp != NULL);
2744  assert(dualfeastol >= 0.0);
2745  assert(success != NULL);
2746 
2748 
2749  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2750  {
2751  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2752  if( *success )
2753  {
2754  SCIP_Real actualdualfeastol;
2755 
2756  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2757  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2758  if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2759  {
2760  /* mark the current solution invalid */
2761  lp->solved = FALSE;
2762  lp->dualfeasible = FALSE;
2763  lp->dualchecked = FALSE;
2764  lp->lpobjval = SCIP_INVALID;
2766  }
2767  else
2768  *success = FALSE;
2769  lp->lpidualfeastol = actualdualfeastol;
2770  }
2771  }
2772  else
2773  *success = FALSE;
2774 
2775  return SCIP_OKAY;
2776 }
2777 
2778 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2779 static
2781  SCIP_LP* lp, /**< current LP data */
2782  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2783  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2784  )
2785 {
2786  assert(lp != NULL);
2787  assert(barrierconvtol >= 0.0);
2788  assert(success != NULL);
2789 
2791 
2792  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2793  {
2794  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2795  if( *success )
2796  {
2797  SCIP_Real actualbarrierconvtol;
2798 
2799  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2800  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
2801  if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
2803  {
2804  /* mark the current solution invalid */
2805  lp->solved = FALSE;
2806  lp->dualfeasible = FALSE;
2807  lp->dualchecked = FALSE;
2808  lp->lpobjval = SCIP_INVALID;
2810  }
2811  else
2812  *success = FALSE;
2813  lp->lpibarrierconvtol = actualbarrierconvtol;
2814  }
2815  }
2816  else
2817  *success = FALSE;
2818 
2819  return SCIP_OKAY;
2820 }
2821 
2822 /** sets the FROMSCRATCH setting of the LP solver */
2823 static
2825  SCIP_LP* lp, /**< current LP data */
2826  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2827  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2828  )
2829 {
2830  assert(lp != NULL);
2831  assert(success != NULL);
2832 
2834 
2835  if( fromscratch != lp->lpifromscratch )
2836  {
2837  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2838  if( *success )
2839  lp->lpifromscratch = fromscratch;
2840  }
2841  else
2842  *success = FALSE;
2843 
2844  return SCIP_OKAY;
2845 }
2846 
2847 /** sets the FASTMIP setting of the LP solver */
2848 static
2850  SCIP_LP* lp, /**< current LP data */
2851  int fastmip, /**< new FASTMIP setting */
2852  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2853  )
2854 {
2855  assert(lp != NULL);
2856  assert(success != NULL);
2857  assert(0 <= fastmip && fastmip <= 1);
2858 
2860 
2861  if( fastmip != lp->lpifastmip )
2862  {
2863  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2864  if( *success )
2865  {
2866  lp->lpifastmip = fastmip;
2867  lp->solved = FALSE;
2868  /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
2869  * demanding setting; however, in the current code, this should have not effect. */
2870  }
2871  }
2872  else
2873  *success = FALSE;
2874 
2875  return SCIP_OKAY;
2876 }
2877 
2878 /** sets the SCALING setting of the LP solver */
2879 static
2881  SCIP_LP* lp, /**< current LP data */
2882  int scaling, /**< new SCALING setting */
2883  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2884  )
2885 {
2886  assert(lp != NULL);
2887  assert(success != NULL);
2888 
2890 
2891  if( scaling != lp->lpiscaling )
2892  {
2893  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2894  if( *success )
2895  lp->lpiscaling = scaling;
2896  }
2897  else
2898  *success = FALSE;
2899 
2900  return SCIP_OKAY;
2901 }
2902 
2903 /** sets the number of THREADS of the LP solver */
2904 static
2906  SCIP_LP* lp, /**< current LP data */
2907  int threads, /**< new number of threads used to solve the LP */
2908  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2909  )
2910 {
2911  assert(lp != NULL);
2912  assert(success != NULL);
2913 
2915 
2916  if( threads != lp->lpithreads )
2917  {
2918  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2919  if( *success )
2920  lp->lpithreads = threads;
2921  }
2922  else
2923  *success = FALSE;
2924 
2925  return SCIP_OKAY;
2926 }
2927 
2928 /** sets the PRESOLVING setting of the LP solver */
2929 static
2931  SCIP_LP* lp, /**< current LP data */
2932  SCIP_Bool presolving, /**< new PRESOLVING setting */
2933  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2934  )
2935 {
2936  assert(lp != NULL);
2937  assert(success != NULL);
2938 
2940 
2941  if( presolving != lp->lpipresolving )
2942  {
2943  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2944  if( *success )
2945  lp->lpipresolving = presolving;
2946  }
2947  else
2948  *success = FALSE;
2949 
2950  return SCIP_OKAY;
2951 }
2952 
2953 /** sets the ROWREPSWITCH setting of the LP solver */
2954 static
2956  SCIP_LP* lp, /**< current LP data */
2957  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2958  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2959  )
2960 {
2961  assert(lp != NULL);
2962  assert(success != NULL);
2963 
2965 
2966  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2967  {
2968  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2969  if( *success )
2970  lp->lpirowrepswitch = rowrepswitch;
2971  }
2972  else
2973  *success = FALSE;
2974 
2975  return SCIP_OKAY;
2976 }
2977 
2978 /** sets the iteration limit of the LP solver */
2979 static
2981  SCIP_LP* lp, /**< current LP data */
2982  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2983  )
2984 {
2985  SCIP_Bool success;
2986 
2987  assert(lp != NULL);
2988  assert(itlim >= -1);
2989 
2990  if( itlim == -1 )
2991  itlim = INT_MAX;
2992 
2994 
2995  if( itlim != lp->lpiitlim )
2996  {
2997  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2998  if( success )
2999  {
3000  if( itlim > lp->lpiitlim )
3001  {
3002  /* mark the current solution invalid */
3003  lp->solved = FALSE;
3004  lp->lpobjval = SCIP_INVALID;
3006  }
3007  lp->lpiitlim = itlim;
3008  }
3009  }
3010 
3011  return SCIP_OKAY;
3012 }
3013 
3014 /** sets the pricing strategy of the LP solver */
3015 static
3017  SCIP_LP* lp, /**< current LP data */
3018  SCIP_PRICING pricing /**< pricing strategy */
3019  )
3020 {
3021  SCIP_Bool success;
3022 
3023  assert(lp != NULL);
3024 
3026 
3027  if( pricing != lp->lpipricing )
3028  {
3029  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3030  if( success )
3031  lp->lpipricing = pricing;
3032  }
3033 
3034  return SCIP_OKAY;
3035 }
3036 
3037 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3038 static
3040  SCIP_LP* lp, /**< current LP data */
3041  char pricingchar /**< character representing the pricing strategy */
3042  )
3043 {
3045 
3046  switch( pricingchar )
3047  {
3048  case 'l':
3049  pricing = SCIP_PRICING_LPIDEFAULT;
3050  break;
3051  case 'a':
3052  pricing = SCIP_PRICING_AUTO;
3053  break;
3054  case 'f':
3055  pricing = SCIP_PRICING_FULL;
3056  break;
3057  case 'p':
3058  pricing = SCIP_PRICING_PARTIAL;
3059  break;
3060  case 's':
3061  pricing = SCIP_PRICING_STEEP;
3062  break;
3063  case 'q':
3064  pricing = SCIP_PRICING_STEEPQSTART;
3065  break;
3066  case 'd':
3067  pricing = SCIP_PRICING_DEVEX;
3068  break;
3069  default:
3070  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3071  return SCIP_INVALIDDATA;
3072  }
3073 
3074  SCIP_CALL( lpSetPricing(lp, pricing) );
3075 
3076  return SCIP_OKAY;
3077 }
3078 
3079 /** sets the verbosity of the LP solver */
3080 static
3082  SCIP_LP* lp, /**< current LP data */
3083  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3084  )
3085 {
3086  SCIP_Bool success;
3087 
3088  assert(lp != NULL);
3089 
3091 
3092  if( lpinfo != lp->lpilpinfo )
3093  {
3094  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3095  if( success )
3096  lp->lpilpinfo = lpinfo;
3097  }
3098 
3099  return SCIP_OKAY;
3100 }
3101 
3102 /** sets the CONDITIONLIMIT setting of the LP solver */
3103 static
3105  SCIP_LP* lp, /**< current LP data */
3106  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3107  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3108  )
3109 {
3110  assert(lp != NULL);
3111  assert(success != NULL);
3112 
3114 
3115  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3116  {
3117  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3118  if( *success )
3119  lp->lpiconditionlimit = condlimit;
3120  }
3121  else
3122  *success = FALSE;
3123 
3124  return SCIP_OKAY;
3125 }
3126 
3127 /** sets the MARKOWITZ setting of the LP solver */
3128 static
3130  SCIP_LP* lp, /**< current LP data */
3131  SCIP_Real threshhold, /**< new MARKOWITZ value */
3132  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3133  )
3134 {
3135  assert(lp != NULL);
3136  assert(success != NULL);
3137 
3139 
3140  if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3141  {
3142  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3143  if( *success )
3144  lp->lpimarkowitz = threshhold;
3145  }
3146  else
3147  *success = FALSE;
3148 
3149  return SCIP_OKAY;
3150 }
3151 
3152 /** sets the type of timer of the LP solver */
3153 static
3155  SCIP_LP* lp, /**< current LP data */
3156  SCIP_CLOCKTYPE timing, /**< new timing value */
3157  SCIP_Bool enabled, /**< is timing enabled? */
3158  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3159  )
3160 {
3161  int lptiming;
3162 
3163  assert(lp != NULL);
3164  assert(success != NULL);
3165  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*/
3166 
3168 
3169  if( !enabled )
3170  lptiming = 0;
3171  else
3172  lptiming = (int) timing;
3173 
3174  if( lptiming != lp->lpitiming ) /*lint !e777*/
3175  {
3176  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3177  if( *success )
3178  lp->lpitiming = lptiming;
3179  }
3180  else
3181  *success = FALSE;
3182 
3183  return SCIP_OKAY;
3184 }
3185 
3186 /** sets the initial random seed of the LP solver */
3187 static
3189  SCIP_LP* lp, /**< current LP data */
3190  int randomseed, /**< new initial random seed */
3191  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3192  )
3193 {
3194  assert(lp != NULL);
3195  assert(success != NULL);
3196 
3197  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3198 
3199  if( randomseed == 0 )
3200  {
3201  lp->lpirandomseed = randomseed;
3202  *success = TRUE;
3203  }
3204  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3205  {
3206  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3207  if( *success )
3208  lp->lpirandomseed = randomseed;
3209  }
3210  else
3211  *success = FALSE;
3212 
3213  return SCIP_OKAY;
3214 }
3215 
3216 /** sets the LP solution polishing method */
3217 static
3219  SCIP_LP* lp, /**< current LP data */
3220  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3221  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3222  )
3223 {
3224  assert(lp != NULL);
3225  assert(success != NULL);
3226 
3227  if( polishing != lp->lpisolutionpolishing )
3228  {
3229  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3230  if( *success )
3231  lp->lpisolutionpolishing = polishing;
3232  }
3233  else
3234  *success = FALSE;
3235 
3236  return SCIP_OKAY;
3237 }
3238 
3239 /** sets the LP refactorization interval */
3240 static
3242  SCIP_LP* lp, /**< current LP data */
3243  int refactor, /**< LP refactorization interval (0: automatic) */
3244  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3245  )
3246 {
3247  assert(lp != NULL);
3248  assert(success != NULL);
3249 
3250  if( refactor != lp->lpirefactorinterval )
3251  {
3252  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3253  if( *success )
3254  lp->lpirefactorinterval = refactor;
3255  }
3256  else
3257  *success = FALSE;
3258 
3259  return SCIP_OKAY;
3260 }
3261 
3262 
3263 /*
3264  * Column methods
3265  */
3266 
3267 /** creates an LP column */
3269  SCIP_COL** col, /**< pointer to column data */
3270  BMS_BLKMEM* blkmem, /**< block memory */
3271  SCIP_SET* set, /**< global SCIP settings */
3272  SCIP_STAT* stat, /**< problem statistics */
3273  SCIP_VAR* var, /**< variable, this column represents */
3274  int len, /**< number of nonzeros in the column */
3275  SCIP_ROW** rows, /**< array with rows of column entries */
3276  SCIP_Real* vals, /**< array with coefficients of column entries */
3277  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3278  )
3279 {
3280  int i;
3281 
3282  assert(col != NULL);
3283  assert(blkmem != NULL);
3284  assert(set != NULL);
3285  assert(stat != NULL);
3286  assert(var != NULL);
3287  assert(len >= 0);
3288  assert(len == 0 || (rows != NULL && vals != NULL));
3289 
3290  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3291 
3292  if( len > 0 )
3293  {
3294  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3295  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3296  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3297 
3298  for( i = 0; i < len; ++i )
3299  {
3300  assert(rows[i] != NULL);
3301  assert(!SCIPsetIsZero(set, vals[i]));
3302  (*col)->linkpos[i] = -1;
3303  }
3304  }
3305  else
3306  {
3307  (*col)->rows = NULL;
3308  (*col)->vals = NULL;
3309  (*col)->linkpos = NULL;
3310  }
3311 
3312  (*col)->var = var;
3313  (*col)->obj = SCIPvarGetObj(var);
3314  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3315  (*col)->lb = SCIPvarGetLbLocal(var);
3316  (*col)->ub = SCIPvarGetUbLocal(var);
3317  (*col)->flushedobj = 0.0;
3318  (*col)->flushedlb = 0.0;
3319  (*col)->flushedub = 0.0;
3320  (*col)->index = stat->ncolidx;
3321  SCIPstatIncrement(stat, set, ncolidx);
3322  (*col)->size = len;
3323  (*col)->len = len;
3324  (*col)->nlprows = 0;
3325  (*col)->nunlinked = len;
3326  (*col)->lppos = -1;
3327  (*col)->lpipos = -1;
3328  (*col)->lpdepth = -1;
3329  (*col)->primsol = 0.0;
3330  (*col)->redcost = SCIP_INVALID;
3331  (*col)->farkascoef = SCIP_INVALID;
3332  (*col)->minprimsol = (*col)->ub;
3333  (*col)->maxprimsol = (*col)->lb;
3334  (*col)->sbdown = SCIP_INVALID;
3335  (*col)->sbup = SCIP_INVALID;
3336  (*col)->sbsolval = SCIP_INVALID;
3337  (*col)->sblpobjval = SCIP_INVALID;
3338  (*col)->sbnode = -1;
3339  (*col)->validredcostlp = -1;
3340  (*col)->validfarkaslp = -1;
3341  (*col)->validsblp = -1;
3342  (*col)->sbitlim = -1;
3343  (*col)->nsbcalls = 0;
3344  (*col)->age = 0;
3345  (*col)->obsoletenode = -1;
3346  (*col)->var_probindex = SCIPvarGetProbindex(var);
3347  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3348  (*col)->lprowssorted = TRUE;
3349  (*col)->nonlprowssorted = (len <= 1);
3350  (*col)->objchanged = FALSE;
3351  (*col)->lbchanged = FALSE;
3352  (*col)->ubchanged = FALSE;
3353  (*col)->coefchanged = FALSE;
3354  (*col)->integral = SCIPvarIsIntegral(var);
3355  (*col)->removable = removable;
3356  (*col)->sbdownvalid = FALSE;
3357  (*col)->sbupvalid = FALSE;
3358  (*col)->lazylb = SCIPvarGetLbLazy(var);
3359  (*col)->lazyub = SCIPvarGetUbLazy(var);
3360  (*col)->storedsolvals = NULL;
3361 
3362  return SCIP_OKAY;
3363 }
3364 
3365 /** frees an LP column */
3367  SCIP_COL** col, /**< pointer to LP column */
3368  BMS_BLKMEM* blkmem, /**< block memory */
3369  SCIP_SET* set, /**< global SCIP settings */
3370  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3371  SCIP_LP* lp /**< current LP data */
3372  )
3373 {
3374  assert(blkmem != NULL);
3375  assert(col != NULL);
3376  assert(*col != NULL);
3377  assert((*col)->var != NULL);
3378  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3379  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3380  assert((*col)->lppos == -1);
3381  assert((*col)->lpipos == -1);
3382 
3383  /* remove column indices from corresponding rows */
3384  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3385 
3386  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3387  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3388  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3389  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3390  BMSfreeBlockMemory(blkmem, col);
3391 
3392  return SCIP_OKAY;
3393 }
3394 
3395 /** output column to file stream */
3397  SCIP_COL* col, /**< LP column */
3398  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3399  FILE* file /**< output file (or NULL for standard output) */
3400  )
3401 {
3402  int r;
3403 
3404  assert(col != NULL);
3405  assert(col->var != NULL);
3406 
3407  /* print bounds */
3408  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3409 
3410  /* print coefficients */
3411  if( col->len == 0 )
3412  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3413  for( r = 0; r < col->len; ++r )
3414  {
3415  assert(col->rows[r] != NULL);
3416  assert(col->rows[r]->name != NULL);
3417  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3418  }
3419  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3420 }
3421 
3422 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3423  */
3425  SCIP_COL* col /**< column to be sorted */
3426  )
3427 {
3428  /* sort LP rows */
3429  colSortLP(col);
3430 
3431  /* sort non-LP rows */
3432  colSortNonLP(col);
3433 }
3434 
3435 /** adds a previously non existing coefficient to an LP column */
3437  SCIP_COL* col, /**< LP column */
3438  BMS_BLKMEM* blkmem, /**< block memory */
3439  SCIP_SET* set, /**< global SCIP settings */
3440  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3441  SCIP_LP* lp, /**< current LP data */
3442  SCIP_ROW* row, /**< LP row */
3443  SCIP_Real val /**< value of coefficient */
3444  )
3445 {
3446  assert(lp != NULL);
3447  assert(!lp->diving);
3448 
3449  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3450 
3451  checkLinks(lp);
3452 
3453  return SCIP_OKAY;
3454 }
3455 
3456 /** deletes existing coefficient from column */
3458  SCIP_COL* col, /**< column to be changed */
3459  BMS_BLKMEM* blkmem, /**< block memory */
3460  SCIP_SET* set, /**< global SCIP settings */
3461  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3462  SCIP_LP* lp, /**< current LP data */
3463  SCIP_ROW* row /**< coefficient to be deleted */
3464  )
3465 {
3466  int pos;
3467 
3468  assert(col != NULL);
3469  assert(col->var != NULL);
3470  assert(lp != NULL);
3471  assert(!lp->diving);
3472  assert(row != NULL);
3473 
3474  /* search the position of the row in the column's row vector */
3475  pos = colSearchCoef(col, row);
3476  if( pos == -1 )
3477  {
3478  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3479  return SCIP_INVALIDDATA;
3480  }
3481  assert(0 <= pos && pos < col->len);
3482  assert(col->rows[pos] == row);
3483 
3484  /* if row knows of the column, remove the column from the row's col vector */
3485  if( col->linkpos[pos] >= 0 )
3486  {
3487  assert(row->cols[col->linkpos[pos]] == col);
3488  assert(row->cols_index[col->linkpos[pos]] == col->index);
3489  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3490  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3491  }
3492 
3493  /* delete the row from the column's row vector */
3494  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3495 
3496  checkLinks(lp);
3497 
3498  return SCIP_OKAY;
3499 }
3500 
3501 /** changes or adds a coefficient to an LP column */
3503  SCIP_COL* col, /**< LP column */
3504  BMS_BLKMEM* blkmem, /**< block memory */
3505  SCIP_SET* set, /**< global SCIP settings */
3506  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3507  SCIP_LP* lp, /**< current LP data */
3508  SCIP_ROW* row, /**< LP row */
3509  SCIP_Real val /**< value of coefficient */
3510  )
3511 {
3512  int pos;
3513 
3514  assert(col != NULL);
3515  assert(lp != NULL);
3516  assert(!lp->diving);
3517  assert(row != NULL);
3518 
3519  /* search the position of the row in the column's row vector */
3520  pos = colSearchCoef(col, row);
3521 
3522  /* check, if row already exists in the column's row vector */
3523  if( pos == -1 )
3524  {
3525  /* add previously not existing coefficient */
3526  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3527  }
3528  else
3529  {
3530  /* modify already existing coefficient */
3531  assert(0 <= pos && pos < col->len);
3532  assert(col->rows[pos] == row);
3533 
3534  /* if row knows of the column, change the corresponding coefficient in the row */
3535  if( col->linkpos[pos] >= 0 )
3536  {
3537  assert(row->cols[col->linkpos[pos]] == col);
3538  assert(row->cols_index[col->linkpos[pos]] == col->index);
3539  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3540  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3541  }
3542 
3543  /* change the coefficient in the column */
3544  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3545  }
3546 
3547  checkLinks(lp);
3548 
3549  return SCIP_OKAY;
3550 }
3551 
3552 /** increases value of an existing or non-existing coefficient in an LP column */
3554  SCIP_COL* col, /**< LP column */
3555  BMS_BLKMEM* blkmem, /**< block memory */
3556  SCIP_SET* set, /**< global SCIP settings */
3557  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3558  SCIP_LP* lp, /**< current LP data */
3559  SCIP_ROW* row, /**< LP row */
3560  SCIP_Real incval /**< value to add to the coefficient */
3561  )
3562 {
3563  int pos;
3564 
3565  assert(col != NULL);
3566  assert(lp != NULL);
3567  assert(!lp->diving);
3568  assert(row != NULL);
3569 
3570  if( SCIPsetIsZero(set, incval) )
3571  return SCIP_OKAY;
3572 
3573  /* search the position of the row in the column's row vector */
3574  pos = colSearchCoef(col, row);
3575 
3576  /* check, if row already exists in the column's row vector */
3577  if( pos == -1 )
3578  {
3579  /* add previously not existing coefficient */
3580  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3581  }
3582  else
3583  {
3584  /* modify already existing coefficient */
3585  assert(0 <= pos && pos < col->len);
3586  assert(col->rows[pos] == row);
3587 
3588  /* if row knows of the column, change the corresponding coefficient in the row */
3589  if( col->linkpos[pos] >= 0 )
3590  {
3591  assert(row->cols[col->linkpos[pos]] == col);
3592  assert(row->cols_index[col->linkpos[pos]] == col->index);
3593  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3594  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3595  }
3596 
3597  /* change the coefficient in the column */
3598  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3599  }
3600 
3601  checkLinks(lp);
3602 
3603  return SCIP_OKAY;
3604 }
3605 
3606 /** insert column in the chgcols list (if not already there) */
3607 static
3609  SCIP_COL* col, /**< LP column to change */
3610  SCIP_SET* set, /**< global SCIP settings */
3611  SCIP_LP* lp /**< current LP data */
3612  )
3613 {
3614  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3615  {
3616  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3617  lp->chgcols[lp->nchgcols] = col;
3618  lp->nchgcols++;
3619  }
3620 
3621  /* mark the current LP unflushed */
3622  lp->flushed = FALSE;
3623 
3624  return SCIP_OKAY;
3625 }
3626 
3627 /** Is the new value reliable or may we have cancellation?
3628  *
3629  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3630  * cancellations which can occur during increasing the oldvalue to the newvalue
3631  */
3632 static
3634  SCIP_SET* set, /**< global SCIP settings */
3635  SCIP_Real newvalue, /**< new value */
3636  SCIP_Real oldvalue /**< old reliable value */
3637  )
3638 {
3639  SCIP_Real quotient;
3640 
3641  assert(set != NULL);
3642  assert(oldvalue < SCIP_INVALID);
3643 
3644  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3645 
3646  return SCIPsetIsZero(set, quotient);
3647 }
3648 
3649 /** update norms of objective function vector */
3650 static
3652  SCIP_LP* lp, /**< current LP data */
3653  SCIP_SET* set, /**< global SCIP settings */
3654  SCIP_Real oldobj, /**< old objective value of variable */
3655  SCIP_Real newobj /**< new objective value of variable */
3656  )
3657 {
3658  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3659  {
3660  if( !lp->objsqrnormunreliable )
3661  {
3662  SCIP_Real oldvalue;
3663 
3664  oldvalue = lp->objsqrnorm;
3665  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3666 
3667  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3668  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3669  lp->objsqrnormunreliable = TRUE;
3670  else
3671  {
3672  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3673 
3674  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3675  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3676 
3677  assert(lp->objsqrnorm >= 0.0);
3678  }
3679  }
3680 
3681  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3682  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3683  }
3684 }
3685 
3686 /** changes objective value of column */
3688  SCIP_COL* col, /**< LP column to change */
3689  SCIP_SET* set, /**< global SCIP settings */
3690  SCIP_LP* lp, /**< current LP data */
3691  SCIP_Real newobj /**< new objective value */
3692  )
3693 {
3694  assert(col != NULL);
3695  assert(col->var != NULL);
3696  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3697  assert(SCIPvarGetCol(col->var) == col);
3698  assert(lp != NULL);
3699 
3700  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3701 
3702  /* only add actual changes */
3703  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3704  {
3705  /* only variables with a real position in the LPI can be inserted */
3706  if( col->lpipos >= 0 )
3707  {
3708  /* insert column in the chgcols list (if not already there) */
3709  SCIP_CALL( insertColChgcols(col, set, lp) );
3710 
3711  /* mark objective value change in the column */
3712  col->objchanged = TRUE;
3713 
3714  assert(lp->nchgcols > 0);
3715  }
3716  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3717  * LP and the LP has to be flushed
3718  */
3719  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3720  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3721  {
3722  /* mark the LP unflushed */
3723  lp->flushed = FALSE;
3724  }
3725  }
3726 
3727  /* store new objective function value */
3728  col->obj = newobj;
3729 
3730  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3731  if( !lp->divingobjchg )
3732  {
3733  SCIP_Real oldobj = col->unchangedobj;
3734 
3735  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3736  col->unchangedobj = newobj;
3737 
3738  /* update the objective function vector norms */
3739  lpUpdateObjNorms(lp, set, oldobj, newobj);
3740  }
3741 
3742  return SCIP_OKAY;
3743 }
3744 
3745 /** changes lower bound of column */
3747  SCIP_COL* col, /**< LP column to change */
3748  SCIP_SET* set, /**< global SCIP settings */
3749  SCIP_LP* lp, /**< current LP data */
3750  SCIP_Real newlb /**< new lower bound value */
3751  )
3752 {
3753  assert(col != NULL);
3754  assert(col->var != NULL);
3755  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3756  assert(SCIPvarGetCol(col->var) == col);
3757  assert(lp != NULL);
3758 
3759  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3760 
3761  /* only add actual changes */
3762  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3763  {
3764  /* only variables with a real position in the LPI can be inserted */
3765  if( col->lpipos >= 0 )
3766  {
3767  /* insert column in the chgcols list (if not already there) */
3768  SCIP_CALL( insertColChgcols(col, set, lp) );
3769 
3770  /* mark bound change in the column */
3771  col->lbchanged = TRUE;
3772 
3773  assert(lp->nchgcols > 0);
3774  }
3775  /* 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
3776  * flushed
3777  */
3778  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3779  {
3780  /* mark the LP unflushed */
3781  lp->flushed = FALSE;
3782  }
3783  }
3784 
3785  col->lb = newlb;
3786 
3787  return SCIP_OKAY;
3788 }
3789 
3790 /** changes upper bound of column */
3792  SCIP_COL* col, /**< LP column to change */
3793  SCIP_SET* set, /**< global SCIP settings */
3794  SCIP_LP* lp, /**< current LP data */
3795  SCIP_Real newub /**< new upper bound value */
3796  )
3797 {
3798  assert(col != NULL);
3799  assert(col->var != NULL);
3800  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3801  assert(SCIPvarGetCol(col->var) == col);
3802  assert(lp != NULL);
3803 
3804  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3805 
3806  /* only add actual changes */
3807  if( !SCIPsetIsEQ(set, col->ub, newub) )
3808  {
3809  /* only variables with a real position in the LPI can be inserted */
3810  if( col->lpipos >= 0 )
3811  {
3812  /* insert column in the chgcols list (if not already there) */
3813  SCIP_CALL( insertColChgcols(col, set, lp) );
3814 
3815  /* mark bound change in the column */
3816  col->ubchanged = TRUE;
3817 
3818  assert(lp->nchgcols > 0);
3819  }
3820  /* 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
3821  * flushed
3822  */
3823  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3824  {
3825  /* mark the LP unflushed */
3826  lp->flushed = FALSE;
3827  }
3828  }
3829 
3830  col->ub = newub;
3831 
3832  return SCIP_OKAY;
3833 }
3834 
3835 /** calculates the reduced costs of a column using the given dual solution vector */
3837  SCIP_COL* col, /**< LP column */
3838  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3839  )
3840 {
3841  SCIP_ROW* row;
3842  SCIP_Real redcost;
3843  int i;
3844 
3845  assert(col != NULL);
3846  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3847  assert(SCIPvarGetCol(col->var) == col);
3848  assert(dualsol != NULL);
3849 
3850  redcost = col->obj;
3851  for( i = 0; i < col->nlprows; ++i )
3852  {
3853  row = col->rows[i];
3854  assert(row != NULL);
3855  assert(row->lppos >= 0);
3856  redcost -= col->vals[i] * dualsol[row->lppos];
3857  }
3858 
3859  if( col->nunlinked > 0 )
3860  {
3861  for( i = col->nlprows; i < col->len; ++i )
3862  {
3863  row = col->rows[i];
3864  assert(row != NULL);
3865  assert(row->lppos == -1 || col->linkpos[i] == -1);
3866  if( row->lppos >= 0 )
3867  redcost -= col->vals[i] * dualsol[row->lppos];
3868  }
3869  }
3870 #ifndef NDEBUG
3871  else
3872  {
3873  for( i = col->nlprows; i < col->len; ++i )
3874  {
3875  row = col->rows[i];
3876  assert(row != NULL);
3877  assert(row->lppos == -1);
3878  assert(col->linkpos[i] >= 0);
3879  }
3880  }
3881 #endif
3882 
3883  return redcost;
3884 }
3885 
3886 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3887 static
3889  SCIP_COL* col /**< LP column */
3890  )
3891 {
3892  SCIP_ROW* row;
3893  SCIP_Real redcost;
3894  int i;
3895 
3896  assert(col != NULL);
3897  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3898  assert(SCIPvarGetCol(col->var) == col);
3899 
3900  redcost = col->obj;
3901  for( i = 0; i < col->nlprows; ++i )
3902  {
3903  row = col->rows[i];
3904  assert(row != NULL);
3905  assert(row->dualsol < SCIP_INVALID);
3906  assert(row->lppos >= 0);
3907  assert(col->linkpos[i] >= 0);
3908  redcost -= col->vals[i] * row->dualsol;
3909  }
3910 
3911  if( col->nunlinked > 0 )
3912  {
3913  for( i = col->nlprows; i < col->len; ++i )
3914  {
3915  row = col->rows[i];
3916  assert(row != NULL);
3917  assert(row->lppos >= 0 || row->dualsol == 0.0);
3918  assert(row->lppos == -1 || col->linkpos[i] == -1);
3919  if( row->lppos >= 0 )
3920  redcost -= col->vals[i] * row->dualsol;
3921  }
3922  }
3923 #ifndef NDEBUG
3924  else
3925  {
3926  for( i = col->nlprows; i < col->len; ++i )
3927  {
3928  row = col->rows[i];
3929  assert(row != NULL);
3930  assert(row->dualsol == 0.0);
3931  assert(row->lppos == -1);
3932  assert(col->linkpos[i] >= 0);
3933  }
3934  }
3935 #endif
3936 
3937  return redcost;
3938 }
3939 
3940 /** gets the reduced costs of a column in last LP or after recalculation */
3942  SCIP_COL* col, /**< LP column */
3943  SCIP_STAT* stat, /**< problem statistics */
3944  SCIP_LP* lp /**< current LP data */
3945  )
3946 {
3947  assert(col != NULL);
3948  assert(stat != NULL);
3949  assert(lp != NULL);
3950  assert(col->validredcostlp <= stat->lpcount);
3951  assert(lp->validsollp == stat->lpcount);
3952 
3953  if( col->validredcostlp < stat->lpcount )
3954  {
3955  col->redcost = colCalcInternalRedcost(col);
3956  col->validredcostlp = stat->lpcount;
3957  }
3958  assert(col->validredcostlp == stat->lpcount);
3959  assert(col->redcost < SCIP_INVALID);
3960 
3961  return col->redcost;
3962 }
3963 
3964 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3966  SCIP_COL* col, /**< LP column */
3967  SCIP_SET* set, /**< global SCIP settings */
3968  SCIP_STAT* stat, /**< problem statistics */
3969  SCIP_LP* lp /**< current LP data */
3970  )
3971 {
3972  assert(col != NULL);
3973  assert(set != NULL);
3974  assert(stat != NULL);
3975  assert(lp != NULL);
3976  assert(lp->validsollp == stat->lpcount);
3977 
3978  /* A column's reduced cost is defined as
3979  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3980  * The activity is equal to the activity of the corresponding row in the dual LP.
3981  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3982  * The sides of the dual row depend on the bounds of the column:
3983  * - lb == ub : dual row is a free row with infinite sides
3984  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3985  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3986  * - lb < ub <= 0: obj <= activity => redcost <= 0
3987  */
3988  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3989  {
3990  /* dual row is free */
3991  return SCIPsetInfinity(set);
3992  }
3993  else
3994  {
3995  SCIP_Real redcost;
3996 
3997  /* calculate reduced costs */
3998  redcost = SCIPcolGetRedcost(col, stat, lp);
3999 
4000  if( !SCIPsetIsNegative(set, col->lb) )
4001  {
4002  /* dual row is activity <= obj <=> redcost >= 0 */
4003  return redcost;
4004  }
4005  else if( SCIPsetIsPositive(set, col->ub) )
4006  {
4007  /* dual row is activity == obj <=> redcost == 0 */
4008  return -REALABS(redcost);
4009  }
4010  else
4011  {
4012  /* dual row is activity >= obj <=> redcost <= 0 */
4013  return -redcost;
4014  }
4015  }
4016 }
4017 
4018 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4020  SCIP_COL* col, /**< LP column */
4021  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4022  )
4023 {
4024  SCIP_ROW* row;
4025  SCIP_Real farkas;
4026  int i;
4027 
4028  assert(col != NULL);
4029  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4030  assert(SCIPvarGetCol(col->var) == col);
4031  assert(dualfarkas != NULL);
4032 
4033  farkas = 0.0;
4034  for( i = 0; i < col->nlprows; ++i )
4035  {
4036  row = col->rows[i];
4037  assert(row != NULL);
4038  assert(row->lppos >= 0);
4039  farkas += col->vals[i] * dualfarkas[row->lppos];
4040  }
4041 
4042  if( col->nunlinked > 0 )
4043  {
4044  for( i = col->nlprows; i < col->len; ++i )
4045  {
4046  row = col->rows[i];
4047  assert(row != NULL);
4048  assert(row->lppos == -1 || col->linkpos[i] == -1);
4049  if( row->lppos >= 0 )
4050  farkas += col->vals[i] * dualfarkas[row->lppos];
4051  }
4052  }
4053 #ifndef NDEBUG
4054  else
4055  {
4056  for( i = col->nlprows; i < col->len; ++i )
4057  {
4058  row = col->rows[i];
4059  assert(row != NULL);
4060  assert(row->lppos == -1);
4061  assert(col->linkpos[i] >= 0);
4062  }
4063  }
4064 #endif
4065 
4066  return farkas;
4067 }
4068 
4069 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4070 static
4072  SCIP_COL* col /**< LP column */
4073  )
4074 {
4075  SCIP_ROW* row;
4076  SCIP_Real farkas;
4077  int i;
4078 
4079  assert(col != NULL);
4080  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4081  assert(SCIPvarGetCol(col->var) == col);
4082 
4083  farkas = 0.0;
4084  for( i = 0; i < col->nlprows; ++i )
4085  {
4086  row = col->rows[i];
4087  assert(row != NULL);
4088  assert(row->dualfarkas < SCIP_INVALID);
4089  assert(row->lppos >= 0);
4090  assert(col->linkpos[i] >= 0);
4091  farkas += col->vals[i] * row->dualfarkas;
4092  }
4093 
4094  if( col->nunlinked > 0 )
4095  {
4096  for( i = col->nlprows; i < col->len; ++i )
4097  {
4098  row = col->rows[i];
4099  assert(row != NULL);
4100  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4101  assert(row->lppos == -1 || col->linkpos[i] == -1);
4102  if( row->lppos >= 0 )
4103  farkas += col->vals[i] * row->dualfarkas;
4104  }
4105  }
4106 #ifndef NDEBUG
4107  else
4108  {
4109  for( i = col->nlprows; i < col->len; ++i )
4110  {
4111  row = col->rows[i];
4112  assert(row != NULL);
4113  assert(row->dualfarkas == 0.0);
4114  assert(row->lppos == -1);
4115  assert(col->linkpos[i] >= 0);
4116  }
4117  }
4118 #endif
4119 
4120  return farkas;
4121 }
4122 
4123 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4125  SCIP_COL* col, /**< LP column */
4126  SCIP_STAT* stat, /**< problem statistics */
4127  SCIP_LP* lp /**< current LP data */
4128  )
4129 {
4130  assert(col != NULL);
4131  assert(stat != NULL);
4132  assert(lp != NULL);
4133  assert(col->validfarkaslp <= stat->lpcount);
4134  assert(lp->validfarkaslp == stat->lpcount);
4135 
4136  if( col->validfarkaslp < stat->lpcount )
4137  {
4139  col->validfarkaslp = stat->lpcount;
4140  }
4141  assert(col->validfarkaslp == stat->lpcount);
4142  assert(col->farkascoef < SCIP_INVALID);
4143 
4144  return col->farkascoef;
4145 }
4146 
4147 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4148  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4149  */
4151  SCIP_COL* col, /**< LP column */
4152  SCIP_STAT* stat, /**< problem statistics */
4153  SCIP_LP* lp /**< current LP data */
4154  )
4155 {
4156  SCIP_Real farkascoef;
4157 
4158  assert(col != NULL);
4159 
4160  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4161 
4162  if( farkascoef > 0.0 )
4163  return col->ub * farkascoef;
4164  else
4165  return col->lb * farkascoef;
4166 }
4167 
4168 /** start strong branching - call before any strong branching */
4170  SCIP_LP* lp /**< LP data */
4171  )
4172 {
4173  assert(lp != NULL);
4174  assert(!lp->strongbranching);
4175 
4176  lp->strongbranching = TRUE;
4177  SCIPdebugMessage("starting strong branching ...\n");
4179 
4180  return SCIP_OKAY;
4181 }
4182 
4183 /** end strong branching - call after any strong branching */
4185  SCIP_LP* lp /**< LP data */
4186  )
4187 {
4188  assert(lp != NULL);
4189  assert(lp->strongbranching);
4190 
4191  lp->strongbranching = FALSE;
4192  SCIPdebugMessage("ending strong branching ...\n");
4194 
4195  return SCIP_OKAY;
4196 }
4197 
4198 /** sets strong branching information for a column variable */
4200  SCIP_COL* col, /**< LP column */
4201  SCIP_SET* set, /**< global SCIP settings */
4202  SCIP_STAT* stat, /**< dynamic problem statistics */
4203  SCIP_LP* lp, /**< LP data */
4204  SCIP_Real lpobjval, /**< objective value of the current LP */
4205  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4206  SCIP_Real sbdown, /**< dual bound after branching column down */
4207  SCIP_Real sbup, /**< dual bound after branching column up */
4208  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4209  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4210  SCIP_Longint iter, /**< total number of strong branching iterations */
4211  int itlim /**< iteration limit applied to the strong branching call */
4212  )
4213 {
4214  assert(col != NULL);
4215  assert(col->var != NULL);
4216  assert(SCIPcolIsIntegral(col));
4217  assert(SCIPvarIsIntegral(col->var));
4218  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4219  assert(SCIPvarGetCol(col->var) == col);
4220  assert(col->lpipos >= 0);
4221  assert(col->lppos >= 0);
4222  assert(set != NULL);
4223  assert(stat != NULL);
4224  assert(lp != NULL);
4225  assert(lp->strongbranchprobing);
4226  assert(col->lppos < lp->ncols);
4227  assert(lp->cols[col->lppos] == col);
4228  assert(itlim >= 1);
4229 
4230  col->sblpobjval = lpobjval;
4231  col->sbsolval = primsol;
4232  col->validsblp = stat->nlps;
4233  col->sbnode = stat->nnodes;
4234 
4235  col->sbitlim = itlim;
4236  col->nsbcalls++;
4237 
4238  col->sbdown = MIN(sbdown, lp->cutoffbound);
4239  col->sbup = MIN(sbup, lp->cutoffbound);
4240  col->sbdownvalid = sbdownvalid;
4241  col->sbupvalid = sbupvalid;
4242 
4243  SCIPstatIncrement(stat, set, nstrongbranchs);
4244  SCIPstatAdd(stat, set, nsblpiterations, iter);
4245  if( stat->nnodes == 1 )
4246  {
4247  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4248  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4249  }
4250 }
4251 
4252 /** invalidates strong branching information for a column variable */
4254  SCIP_COL* col, /**< LP column */
4255  SCIP_SET* set, /**< global SCIP settings */
4256  SCIP_STAT* stat, /**< dynamic problem statistics */
4257  SCIP_LP* lp /**< LP data */
4258  )
4259 {
4260  assert(col != NULL);
4261  assert(col->var != NULL);
4262  assert(SCIPcolIsIntegral(col));
4263  assert(SCIPvarIsIntegral(col->var));
4264  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4265  assert(SCIPvarGetCol(col->var) == col);
4266  assert(col->lpipos >= 0);
4267  assert(col->lppos >= 0);
4268  assert(set != NULL);
4269  assert(stat != NULL);
4270  assert(lp != NULL);
4271  assert(lp->strongbranchprobing);
4272  assert(col->lppos < lp->ncols);
4273  assert(lp->cols[col->lppos] == col);
4274 
4275  col->sbdown = SCIP_INVALID;
4276  col->sbup = SCIP_INVALID;
4277  col->sbdownvalid = FALSE;
4278  col->sbupvalid = FALSE;
4279  col->validsblp = -1;
4280  col->sbsolval = SCIP_INVALID;
4281  col->sblpobjval = SCIP_INVALID;
4282  col->sbnode = -1;
4283  col->sbitlim = -1;
4284 }
4285 
4286 
4287 /** gets strong branching information on a column variable */
4289  SCIP_COL* col, /**< LP column */
4290  SCIP_Bool integral, /**< should integral strong branching be performed? */
4291  SCIP_SET* set, /**< global SCIP settings */
4292  SCIP_STAT* stat, /**< dynamic problem statistics */
4293  SCIP_PROB* prob, /**< problem data */
4294  SCIP_LP* lp, /**< LP data */
4295  int itlim, /**< iteration limit for strong branchings */
4296  SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4297  SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4298  SCIP_Real* down, /**< stores dual bound after branching column down */
4299  SCIP_Real* up, /**< stores dual bound after branching column up */
4300  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4301  * otherwise, it can only be used as an estimate value */
4302  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4303  * otherwise, it can only be used as an estimate value */
4304  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4305  )
4306 {
4307  SCIP_Real sbdown;
4308  SCIP_Real sbup;
4309  SCIP_Bool sbdownvalid;
4310  SCIP_Bool sbupvalid;
4311  SCIP_Longint validsblp;
4312  SCIP_Real sbsolval;
4313  SCIP_Real sblpobjval;
4314  SCIP_Longint sbnode;
4315  int sbitlim;
4316  int nsbcalls;
4317 
4318  assert(col != NULL);
4319  assert(col->var != NULL);
4320  assert(SCIPcolIsIntegral(col));
4321  assert(SCIPvarIsIntegral(col->var));
4322  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4323  assert(SCIPvarGetCol(col->var) == col);
4324  assert(col->primsol < SCIP_INVALID);
4325  assert(col->lpipos >= 0);
4326  assert(col->lppos >= 0);
4327  assert(set != NULL);
4328  assert(stat != NULL);
4329  assert(lp != NULL);
4330  assert(lp->flushed);
4331  assert(lp->solved);
4332  assert(lp->strongbranching);
4333  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4334  assert(lp->validsollp == stat->lpcount);
4335  assert(col->lppos < lp->ncols);
4336  assert(lp->cols[col->lppos] == col);
4337  assert(itlim >= 1);
4338  /* assert(down != NULL);
4339  * assert(up != NULL); temporary hack for cloud branching
4340  */
4341  assert(lperror != NULL);
4342 
4343  *lperror = FALSE;
4344 
4345  sbdown = col->sbdown;
4346  sbup = col->sbup;
4347  sbdownvalid = col->sbdownvalid;
4348  sbupvalid = col->sbupvalid;
4349  sbitlim = col->sbitlim;
4350  nsbcalls = col->nsbcalls;
4351 
4352  validsblp = stat->nlps;
4353  sbsolval = col->primsol;
4354  sblpobjval = SCIPlpGetObjval(lp, set, prob);
4355  sbnode = stat->nnodes;
4356  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4357 
4358  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4359  if( lp->looseobjvalinf > 0 )
4360  {
4361  sbdown = -SCIPsetInfinity(set);
4362  sbup = -SCIPsetInfinity(set);
4363  sbdownvalid = FALSE;
4364  sbupvalid = FALSE;
4365  }
4366  else
4367  {
4368  SCIP_RETCODE retcode;
4369  int iter;
4370 
4371  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4372  SCIPvarGetName(col->var), col->primsol, itlim);
4373 
4374  /* start timing */
4375  SCIPclockStart(stat->strongbranchtime, set);
4376 
4377  /* call LPI strong branching */
4378  sbitlim = itlim;
4379  nsbcalls++;
4380 
4381  sbdown = lp->lpobjval;
4382  sbup = lp->lpobjval;
4383 
4384  if( integral )
4385  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4386  else
4387  {
4388  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4389  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4390  }
4391 
4392  /* check return code for errors */
4393  if( retcode == SCIP_LPERROR )
4394  {
4395  *lperror = TRUE;
4396  sbdown = SCIP_INVALID;
4397  sbup = SCIP_INVALID;
4398  sbdownvalid = FALSE;
4399  sbupvalid = FALSE;
4400  validsblp = -1;
4401  sbsolval = SCIP_INVALID;
4402  sblpobjval = SCIP_INVALID;
4403  sbnode = -1;
4404  }
4405  else
4406  {
4407  SCIP_Real looseobjval;
4408 
4409  *lperror = FALSE;
4410  SCIP_CALL( retcode );
4411 
4412  looseobjval = getFiniteLooseObjval(lp, set, prob);
4413  sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4414  sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4415 
4416  /* update strong branching statistics */
4417  if( updatestat )
4418  {
4419  if( iter == -1 )
4420  {
4421  /* calculate average iteration number */
4422  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4423  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4424  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4425  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4426  : 0;
4427  if( iter/2 >= itlim )
4428  iter = 2*itlim;
4429  }
4430  SCIPstatIncrement(stat, set, nstrongbranchs);
4431  SCIPstatAdd(stat, set, nsblpiterations, iter);
4432  if( stat->nnodes == 1 )
4433  {
4434  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4435  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4436  }
4437  }
4438  }
4439 
4440  /* stop timing */
4441  SCIPclockStop(stat->strongbranchtime, set);
4442  }
4443  assert(*lperror || sbdown < SCIP_INVALID);
4444  assert(*lperror || sbup < SCIP_INVALID);
4445 
4446  if( down != NULL)
4447  *down = sbdown;
4448  if( up != NULL )
4449  *up = sbup;
4450  if( downvalid != NULL )
4451  *downvalid = sbdownvalid;
4452  if( upvalid != NULL )
4453  *upvalid = sbupvalid;
4454 
4455  if( updatecol )
4456  {
4457  col->sbdown = sbdown;
4458  col->sbup = sbup;
4459  col->sbdownvalid = sbdownvalid;
4460  col->sbupvalid = sbupvalid;
4461  col->validsblp = validsblp;
4462  col->sbsolval = sbsolval;
4463  col->sblpobjval = sblpobjval;
4464  col->sbnode = sbnode;
4465  col->sbitlim = sbitlim;
4466  col->nsbcalls = nsbcalls;
4467  }
4468 
4469  return SCIP_OKAY;
4470 }
4471 
4472 /** gets strong branching information on column variables */
4474  SCIP_COL** cols, /**< LP columns */
4475  int ncols, /**< number of columns */
4476  SCIP_Bool integral, /**< should integral strong branching be performed? */
4477  SCIP_SET* set, /**< global SCIP settings */
4478  SCIP_STAT* stat, /**< dynamic problem statistics */
4479  SCIP_PROB* prob, /**< problem data */
4480  SCIP_LP* lp, /**< LP data */
4481  int itlim, /**< iteration limit for strong branchings */
4482  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4483  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4484  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4485  * otherwise, they can only be used as an estimate value */
4486  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4487  * otherwise, they can only be used as an estimate value */
4488  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4489  )
4490 {
4491  SCIP_RETCODE retcode;
4492  SCIP_Real* sbdown;
4493  SCIP_Real* sbup;
4494  SCIP_Bool* sbdownvalid;
4495  SCIP_Bool* sbupvalid;
4496  SCIP_Real* primsols;
4497  SCIP_COL** subcols;
4498  int* lpipos;
4499  int* subidx;
4500  int nsubcols;
4501  int iter;
4502  int j;
4503 
4504  assert(cols != NULL);
4505  assert(set != NULL);
4506  assert(stat != NULL);
4507  assert(lp != NULL);
4508  assert(lp->flushed);
4509  assert(lp->solved);
4510  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4511  assert(lp->validsollp == stat->lpcount);
4512  assert(itlim >= 1);
4513  assert(down != NULL);
4514  assert(up != NULL);
4515  assert(lperror != NULL);
4516 
4517  *lperror = FALSE;
4518 
4519  if ( ncols <= 0 )
4520  return SCIP_OKAY;
4521 
4522  /* start timing */
4523  SCIPclockStart(stat->strongbranchtime, set);
4524 
4525  /* initialize storage */
4526  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4527  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4528  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4529  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4530  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4531  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4532  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4533  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4534 
4535  nsubcols = 0;
4536  for( j = 0; j < ncols; ++j )
4537  {
4538  SCIP_COL* col;
4539  col = cols[j];
4540 
4541  assert(col->lppos < lp->ncols);
4542  assert(lp->cols[col->lppos] == col);
4543  assert(SCIPcolIsIntegral(col));
4544  assert(SCIPvarIsIntegral(col->var));
4545  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4546  assert(SCIPvarGetCol(col->var) == col);
4547  assert(col->primsol < SCIP_INVALID);
4548  assert(col->lpipos >= 0);
4549  assert(col->lppos >= 0);
4550 
4551  col->validsblp = stat->nlps;
4552  col->sbsolval = col->primsol;
4553  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4554  col->sbnode = stat->nnodes;
4555  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4556 
4557  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4558  if( lp->looseobjvalinf > 0 )
4559  {
4560  /* directly set up column and result vectors*/
4561  col->sbdown = -SCIPsetInfinity(set);
4562  col->sbup = -SCIPsetInfinity(set);
4563  col->sbdownvalid = FALSE;
4564  col->sbupvalid = FALSE;
4565  down[j] = col->sbdown;
4566  up[j] = col->sbup;
4567  if( downvalid != NULL )
4568  downvalid[j] = col->sbdownvalid;
4569  if( upvalid != NULL )
4570  upvalid[j] = col->sbupvalid;
4571  }
4572  else
4573  {
4574  col->sbitlim = itlim;
4575  col->nsbcalls++;
4576 
4577  lpipos[nsubcols] = col->lpipos;
4578  primsols[nsubcols] = col->primsol;
4579  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4580  subidx[nsubcols] = j;
4581  subcols[nsubcols++] = col;
4582  }
4583  }
4584 
4585  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4586 
4587  /* call LPI strong branching */
4588  if ( integral )
4589  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4590  else
4591  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4592 
4593  /* check return code for errors */
4594  if( retcode == SCIP_LPERROR )
4595  {
4596  *lperror = TRUE;
4597 
4598  for( j = 0; j < nsubcols; ++j )
4599  {
4600  SCIP_COL* col;
4601  int idx;
4602 
4603  col = subcols[j];
4604  idx = subidx[j];
4605 
4606  col->sbdown = SCIP_INVALID;
4607  col->sbup = SCIP_INVALID;
4608  col->sbdownvalid = FALSE;
4609  col->sbupvalid = FALSE;
4610  col->validsblp = -1;
4611  col->sbsolval = SCIP_INVALID;
4612  col->sblpobjval = SCIP_INVALID;
4613  col->sbnode = -1;
4614 
4615  down[idx] = col->sbdown;
4616  up[idx] = col->sbup;
4617  if( downvalid != NULL )
4618  downvalid[idx] = col->sbdownvalid;
4619  if( upvalid != NULL )
4620  upvalid[idx] = col->sbupvalid;
4621  }
4622  }
4623  else
4624  {
4625  SCIP_Real looseobjval;
4626 
4627  *lperror = FALSE;
4628  SCIP_CALL( retcode );
4629 
4630  looseobjval = getFiniteLooseObjval(lp, set, prob);
4631 
4632  for( j = 0; j < nsubcols; ++j )
4633  {
4634  SCIP_COL* col;
4635  int idx;
4636 
4637  col = subcols[j];
4638  idx = subidx[j];
4639 
4640  assert( col->sbdown < SCIP_INVALID);
4641  assert( col->sbup < SCIP_INVALID);
4642 
4643  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4644  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4645  col->sbdownvalid = sbdownvalid[j];
4646  col->sbupvalid = sbupvalid[j];
4647 
4648  down[idx] = col->sbdown;
4649  up[idx] = col->sbup;
4650  if( downvalid != NULL )
4651  downvalid[idx] = col->sbdownvalid;
4652  if( upvalid != NULL )
4653  upvalid[idx] = col->sbupvalid;
4654  }
4655 
4656  /* update strong branching statistics */
4657  if( iter == -1 )
4658  {
4659  /* calculate average iteration number */
4660  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4661  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4662  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4663  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4664  : 0;
4665  if( iter/2 >= itlim )
4666  iter = 2*itlim;
4667  }
4668  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4669  SCIPstatAdd(stat, set, nsblpiterations, iter);
4670  if( stat->nnodes == 1 )
4671  {
4672  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4673  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4674  }
4675  }
4676 
4677  SCIPsetFreeBufferArray(set, &sbupvalid);
4678  SCIPsetFreeBufferArray(set, &sbdownvalid);
4679  SCIPsetFreeBufferArray(set, &sbup);
4680  SCIPsetFreeBufferArray(set, &sbdown);
4681  SCIPsetFreeBufferArray(set, &primsols);
4682  SCIPsetFreeBufferArray(set, &lpipos);
4683  SCIPsetFreeBufferArray(set, &subidx);
4684  SCIPsetFreeBufferArray(set, &subcols);
4685 
4686  /* stop timing */
4687  SCIPclockStop(stat->strongbranchtime, set);
4688 
4689  return SCIP_OKAY;
4690 }
4691 
4692 /** gets last strong branching information available for a column variable;
4693  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4694  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4695  */
4697  SCIP_COL* col, /**< LP column */
4698  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4699  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4700  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4701  * otherwise, it can only be used as an estimate value */
4702  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4703  * otherwise, it can only be used as an estimate value */
4704  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4705  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4706  )
4707 {
4708  assert(col != NULL);
4709 
4710  if( down != NULL )
4711  *down = col->sbdown;
4712  if( up != NULL )
4713  *up = col->sbup;
4714  if( downvalid != NULL )
4715  *downvalid = col->sbdownvalid;
4716  if( upvalid != NULL )
4717  *upvalid = col->sbupvalid;
4718  if( solval != NULL )
4719  *solval = col->sbsolval;
4720  if( lpobjval != NULL )
4721  *lpobjval = col->sblpobjval;
4722 }
4723 
4724 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4725  * the LP where the strong branching on this column was applied;
4726  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4727  */
4729  SCIP_COL* col, /**< LP column */
4730  SCIP_STAT* stat /**< dynamic problem statistics */
4731  )
4732 {
4733  assert(col != NULL);
4734  assert(stat != NULL);
4735 
4736  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4737 }
4738 
4739 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4741  SCIP_COL* col, /**< LP column */
4742  SCIP_STAT* stat /**< problem statistics */
4743  )
4744 {
4745  assert(col != NULL);
4746  assert(stat != NULL);
4747  assert(stat->nnodes > 0);
4748 
4749  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4750  col->obsoletenode = stat->nnodes;
4751 }
4752 
4753 
4754 /*
4755  * Row methods
4756  */
4757 
4758 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4759 static
4761  SCIP_ROW* row, /**< LP row */
4762  SCIP_SET* set /**< global SCIP settings */
4763  )
4764 {
4765  int i;
4766 
4767  assert(row != NULL);
4768  assert(set != NULL);
4769 
4770  row->sqrnorm = 0.0;
4771  row->sumnorm = 0.0;
4772  row->objprod = 0.0;
4773  row->maxval = 0.0;
4774  row->nummaxval = 1;
4775  row->minval = SCIPsetInfinity(set);
4776  row->numminval = 1;
4777  row->minidx = INT_MAX;
4778  row->maxidx = INT_MIN;
4779  row->validminmaxidx = TRUE;
4780  row->lpcolssorted = TRUE;
4781  row->nonlpcolssorted = TRUE;
4782 
4783  /* check, if row is sorted
4784  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4785  */
4786  for( i = 0; i < row->nlpcols; ++i )
4787  {
4788  assert(row->cols[i] != NULL);
4789  assert(!SCIPsetIsZero(set, row->vals[i]));
4790  assert(row->cols[i]->lppos >= 0);
4791  assert(row->linkpos[i] >= 0);
4792  assert(row->cols[i]->index == row->cols_index[i]);
4793 
4794  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4795  if( i > 0 )
4796  {
4797  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4798  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4799  }
4800  }
4801  for( i = row->nlpcols; i < row->len; ++i )
4802  {
4803  assert(row->cols[i] != NULL);
4804  assert(!SCIPsetIsZero(set, row->vals[i]));
4805  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4806  assert(row->cols[i]->index == row->cols_index[i]);
4807 
4808  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4809  if( i > row->nlpcols )
4810  {
4811  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4812  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4813  }
4814  }
4815 }
4816 
4817 /** calculates min/maxval and min/maxidx from scratch */
4818 static
4820  SCIP_ROW* row, /**< LP row */
4821  SCIP_SET* set /**< global SCIP settings */
4822  )
4823 {
4824  SCIP_COL* col;
4825  SCIP_Real absval;
4826  int i;
4827 
4828  assert(row != NULL);
4829  assert(set != NULL);
4830 
4831  row->maxval = 0.0;
4832  row->nummaxval = 1;
4833  row->numintcols = 0;
4834  row->minval = SCIPsetInfinity(set);
4835  row->numminval = 1;
4836  row->minidx = INT_MAX;
4837  row->maxidx = INT_MIN;
4838  row->validminmaxidx = TRUE;
4839 
4840  /* calculate maxval, minval, minidx, and maxidx */
4841  for( i = 0; i < row->len; ++i )
4842  {
4843  col = row->cols[i];
4844  assert(col != NULL);
4845  assert(!SCIPsetIsZero(set, row->vals[i]));
4846 
4847  absval = REALABS(row->vals[i]);
4848  assert(!SCIPsetIsZero(set, absval));
4849 
4850  /* update min/maxidx */
4851  row->minidx = MIN(row->minidx, col->index);
4852  row->maxidx = MAX(row->maxidx, col->index);
4853  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4854 
4855  /* update maximal and minimal non-zero value */
4856  if( row->nummaxval > 0 )
4857  {
4858  if( SCIPsetIsGT(set, absval, row->maxval) )
4859  {
4860  row->maxval = absval;
4861  row->nummaxval = 1;
4862  }
4863  else if( SCIPsetIsGE(set, absval, row->maxval) )
4864  {
4865  /* make sure the maxval is always exactly the same */
4866  row->maxval = MAX(absval, row->maxval);
4867  row->nummaxval++;
4868  }
4869  }
4870  if( row->numminval > 0 )
4871  {
4872  if( SCIPsetIsLT(set, absval, row->minval) )
4873  {
4874  row->minval = absval;
4875  row->numminval = 1;
4876  }
4877  else if( SCIPsetIsLE(set, absval, row->minval) )
4878  {
4879  /* make sure the minval is always exactly the same */
4880  row->minval = MIN(absval, row->minval);
4881  row->numminval++;
4882  }
4883  }
4884  }
4885 }
4886 
4887 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4888 static
4890  SCIP_Real val, /**< value that should be scaled to an integral value */
4891  SCIP_Real scalar, /**< scalar that should be tried */
4892  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4893  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4894  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4895  )
4896 {
4897  SCIP_Real sval;
4898  SCIP_Real downval;
4899  SCIP_Real upval;
4900 
4901  assert(mindelta <= 0.0);
4902  assert(maxdelta >= 0.0);
4903 
4904  sval = val * scalar;
4905  downval = floor(sval);
4906  upval = ceil(sval);
4907 
4908  if( SCIPrelDiff(sval, downval) <= maxdelta )
4909  {
4910  if( intval != NULL )
4911  *intval = downval;
4912  return TRUE;
4913  }
4914  else if( SCIPrelDiff(sval, upval) >= mindelta )
4915  {
4916  if( intval != NULL )
4917  *intval = upval;
4918  return TRUE;
4919  }
4920 
4921  return FALSE;
4922 }
4923 
4924 /** scales row with given factor, and rounds coefficients to integers if close enough;
4925  * the constant is automatically moved to the sides;
4926  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4927  */
4928 static
4930  SCIP_ROW* row, /**< LP row */
4931  BMS_BLKMEM* blkmem, /**< block memory */
4932  SCIP_SET* set, /**< global SCIP settings */
4933  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4934  SCIP_STAT* stat, /**< problem statistics */
4935  SCIP_LP* lp, /**< current LP data */
4936  SCIP_Real scaleval, /**< value to scale row with */
4937  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4938  * if they are close to integral values? */
4939  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4940  * upto which the integral is used instead of the scaled real coefficient */
4941  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4942  * upto which the integral is used instead of the scaled real coefficient */
4943  )
4944 {
4945  SCIP_COL* col;
4946  SCIP_Real val;
4947  SCIP_Real newval;
4948  SCIP_Real intval;
4949  SCIP_Real mindelta;
4950  SCIP_Real maxdelta;
4951  SCIP_Real lb;
4952  SCIP_Real ub;
4953  SCIP_Bool mindeltainf;
4954  SCIP_Bool maxdeltainf;
4955  int oldlen;
4956  int c;
4957 
4958  assert(row != NULL);
4959  assert(row->len == 0 || row->cols != NULL);
4960  assert(row->len == 0 || row->vals != NULL);
4961  assert(SCIPsetIsPositive(set, scaleval));
4962  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4963  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4964 
4965  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4966 
4967  mindelta = 0.0;
4968  maxdelta = 0.0;
4969  mindeltainf = FALSE;
4970  maxdeltainf = FALSE;
4971  oldlen = row->len;
4972 
4973  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4974  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4975  * this rounding can lead to
4976  */
4977  row->integral = TRUE;
4978 
4979  c = 0;
4980  while( c < row->len )
4981  {
4982  col = row->cols[c];
4983  val = row->vals[c];
4984  assert(!SCIPsetIsZero(set, val));
4985 
4986  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4987  if( row->local )
4988  {
4989  lb = col->lb;
4990  ub = col->ub;
4991  }
4992  else
4993  {
4994  lb = SCIPvarGetLbGlobal(col->var);
4995  ub = SCIPvarGetUbGlobal(col->var);
4996  }
4997 
4998  /* calculate scaled coefficient */
4999  newval = val * scaleval;
5000  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5001  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5002  {
5003  if( !SCIPsetIsEQ(set, intval, newval) )
5004  {
5005  if( intval < newval )
5006  {
5007  mindelta += (intval - newval)*ub;
5008  maxdelta += (intval - newval)*lb;
5009  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5010  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5011  }
5012  else
5013  {
5014  mindelta += (intval - newval)*lb;
5015  maxdelta += (intval - newval)*ub;
5016  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5017  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5018  }
5019  }
5020  newval = intval;
5021  }
5022 
5023  if( !SCIPsetIsEQ(set, val, newval) )
5024  {
5025  /* if column knows of the row, change the corresponding coefficient in the column */
5026  if( row->linkpos[c] >= 0 )
5027  {
5028  assert(col->rows[row->linkpos[c]] == row);
5029  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5030  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5031  }
5032 
5033  /* change the coefficient in the row, and update the norms and integrality status */
5034  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5035 
5036  /* current coefficient has been deleted from the row because it was almost zero */
5037  if( oldlen != row->len )
5038  {
5039  assert(row->len == oldlen - 1);
5040  c--;
5041  oldlen = row->len;
5042  }
5043  }
5044  else
5045  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5046 
5047  ++c;
5048  }
5049 
5050  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5051  * to not destroy feasibility due to rounding
5052  */
5053  /**@todo ensure that returned cut does not have infinite lhs and rhs */
5054  if( !SCIPsetIsInfinity(set, -row->lhs) )
5055  {
5056  if( mindeltainf )
5057  newval = -SCIPsetInfinity(set);
5058  else
5059  {
5060  newval = (row->lhs - row->constant) * scaleval + mindelta;
5061  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5062  newval = SCIPsetSumCeil(set, newval);
5063  }
5064  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5065  }
5066  if( !SCIPsetIsInfinity(set, row->rhs) )
5067  {
5068  if( maxdeltainf )
5069  newval = SCIPsetInfinity(set);
5070  else
5071  {
5072  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5073  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5074  newval = SCIPsetSumFloor(set, newval);
5075  }
5076  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5077  }
5078 
5079  /* clear the row constant */
5080  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5081 
5082  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5083  debugRowPrint(set, row);
5084 
5085 #ifdef SCIP_DEBUG
5086  /* check integrality status of row */
5087  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5088  {}
5089  assert(row->integral == (c == row->len));
5090 #endif
5091 
5092  /* invalid the activity */
5093  row->validactivitylp = -1;
5094 
5095  return SCIP_OKAY;
5096 }
5097 
5098 /** creates and captures an LP row */
5100  SCIP_ROW** row, /**< pointer to LP row data */
5101  BMS_BLKMEM* blkmem, /**< block memory */
5102  SCIP_SET* set, /**< global SCIP settings */
5103  SCIP_STAT* stat, /**< problem statistics */
5104  const char* name, /**< name of row */
5105  int len, /**< number of nonzeros in the row */
5106  SCIP_COL** cols, /**< array with columns of row entries */
5107  SCIP_Real* vals, /**< array with coefficients of row entries */
5108  SCIP_Real lhs, /**< left hand side of row */
5109  SCIP_Real rhs, /**< right hand side of row */
5110  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5111  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5112  SCIP_Bool local, /**< is row only valid locally? */
5113  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5114  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5115  )
5116 {
5117  assert(row != NULL);
5118  assert(blkmem != NULL);
5119  assert(stat != NULL);
5120  assert(len >= 0);
5121  assert(len == 0 || (cols != NULL && vals != NULL));
5122  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5123  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5124  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5125  */
5126  assert(lhs <= rhs);
5127 
5128  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5129 
5130  (*row)->integral = TRUE;
5131  if( len > 0 )
5132  {
5133  SCIP_VAR* var;
5134  int i;
5135 
5136  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5137  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5138  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5139  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5140 
5141  for( i = 0; i < len; ++i )
5142  {
5143  assert(cols[i] != NULL);
5144  assert(!SCIPsetIsZero(set, vals[i]));
5145 
5146  var = cols[i]->var;
5147  (*row)->cols_index[i] = cols[i]->index;
5148  (*row)->linkpos[i] = -1;
5149  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5150  {
5151  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5152  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5153  }
5154  else
5155  {
5156  (*row)->integral = FALSE;
5157  }
5158  }
5159  }
5160  else
5161  {
5162  (*row)->cols = NULL;
5163  (*row)->cols_index = NULL;
5164  (*row)->vals = NULL;
5165  (*row)->linkpos = NULL;
5166  }
5167 
5168  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5169  (*row)->constant = 0.0;
5170  (*row)->lhs = lhs;
5171  (*row)->rhs = rhs;
5172  (*row)->flushedlhs = -SCIPsetInfinity(set);
5173  (*row)->flushedrhs = SCIPsetInfinity(set);
5174  (*row)->sqrnorm = 0.0;
5175  (*row)->sumnorm = 0.0;
5176  (*row)->objprod = 0.0;
5177  (*row)->maxval = 0.0;
5178  (*row)->minval = SCIPsetInfinity(set);
5179  (*row)->dualsol = 0.0;
5180  (*row)->activity = SCIP_INVALID;
5181  (*row)->dualfarkas = 0.0;
5182  (*row)->pseudoactivity = SCIP_INVALID;
5183  (*row)->minactivity = SCIP_INVALID;
5184  (*row)->maxactivity = SCIP_INVALID;
5185  (*row)->origin = origin;
5186  (*row)->eventfilter = NULL;
5187  (*row)->index = stat->nrowidx;
5188  SCIPstatIncrement(stat, set, nrowidx);
5189  (*row)->size = len;
5190  (*row)->len = len;
5191  (*row)->nlpcols = 0;
5192  (*row)->nunlinked = len;
5193  (*row)->nuses = 0;
5194  (*row)->lppos = -1;
5195  (*row)->lpipos = -1;
5196  (*row)->lpdepth = -1;
5197  (*row)->minidx = INT_MAX;
5198  (*row)->maxidx = INT_MIN;
5199  (*row)->nummaxval = 0;
5200  (*row)->numminval = 0;
5201  (*row)->numintcols = -1;
5202  (*row)->validactivitylp = -1;
5203  (*row)->validpsactivitydomchg = -1;
5204  (*row)->validactivitybdsdomchg = -1;
5205  (*row)->nlpsaftercreation = 0L;
5206  (*row)->activeinlpcounter = 0L;
5207  (*row)->age = 0;
5208  (*row)->rank = 0;
5209  (*row)->obsoletenode = -1;
5210  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5211  (*row)->lpcolssorted = TRUE;
5212  (*row)->nonlpcolssorted = (len <= 1);
5213  (*row)->delaysort = FALSE;
5214  (*row)->validminmaxidx = FALSE;
5215  (*row)->lhschanged = FALSE;
5216  (*row)->rhschanged = FALSE;
5217  (*row)->coefchanged = FALSE;
5218  (*row)->local = local;
5219  (*row)->modifiable = modifiable;
5220  (*row)->nlocks = 0;
5221  (*row)->origintype = origintype; /*lint !e641*/
5222  (*row)->removable = removable;
5223  (*row)->inglobalcutpool = FALSE;
5224  (*row)->storedsolvals = NULL;
5225 
5226  /* calculate row norms and min/maxidx, and check if row is sorted */
5227  rowCalcNorms(*row, set);
5228 
5229  /* capture the row */
5230  SCIProwCapture(*row);
5231 
5232  /* create event filter */
5233  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5234 
5235  /* capture origin constraint if available */
5236  if( origintype == SCIP_ROWORIGINTYPE_CONS )
5237  {
5238  SCIP_CONS* cons = (SCIP_CONS*) origin;
5239  assert(cons != NULL);
5240  SCIPconsCapture(cons);
5241  }
5242 
5243  return SCIP_OKAY;
5244 } /*lint !e715*/
5245 
5246 /** frees an LP row */
5248  SCIP_ROW** row, /**< pointer to LP row */
5249  BMS_BLKMEM* blkmem, /**< block memory */
5250  SCIP_SET* set, /**< global SCIP settings */
5251  SCIP_LP* lp /**< current LP data */
5252  )
5253 {
5254  assert(blkmem != NULL);
5255  assert(row != NULL);
5256  assert(*row != NULL);
5257  assert((*row)->nuses == 0);
5258  assert((*row)->lppos == -1);
5259  assert((*row)->eventfilter != NULL);
5260 
5261  /* release constraint that has been used for creating the row */
5262  if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5263  {
5264  SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5265  assert(cons != NULL);
5266  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5267  }
5268 
5269  /* remove column indices from corresponding rows */
5270  SCIP_CALL( rowUnlink(*row, set, lp) );
5271 
5272  /* free event filter */
5273  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5274 
5275  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5276  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5277  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5278  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5279  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5280  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5281  BMSfreeBlockMemory(blkmem, row);
5282 
5283  return SCIP_OKAY;
5284 }
5285 
5286 /** output row to file stream */
5288  SCIP_ROW* row, /**< LP row */
5289  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5290  FILE* file /**< output file (or NULL for standard output) */
5291  )
5292 {
5293  int i;
5294 
5295  assert(row != NULL);
5296 
5297  /* print row name */
5298  if( row->name != NULL && row->name[0] != '\0' )
5299  {
5300  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5301  }
5302 
5303  /* print left hand side */
5304  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5305 
5306  /* print coefficients */
5307  if( row->len == 0 )
5308  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5309  for( i = 0; i < row->len; ++i )
5310  {
5311  assert(row->cols[i] != NULL);
5312  assert(row->cols[i]->var != NULL);
5313  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5314  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5315  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5316  }
5317 
5318  /* print constant */
5319  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5320  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5321 
5322  /* print right hand side */
5323  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5324 }
5325 
5326 /** increases usage counter of LP row */
5328  SCIP_ROW* row /**< LP row */
5329  )
5330 {
5331  assert(row != NULL);
5332  assert(row->nuses >= 0);
5333  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5334 
5335  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5336  row->nuses++;
5337 }
5338 
5339 /** decreases usage counter of LP row, and frees memory if necessary */
5341  SCIP_ROW** row, /**< pointer to LP row */
5342  BMS_BLKMEM* blkmem, /**< block memory */
5343  SCIP_SET* set, /**< global SCIP settings */
5344  SCIP_LP* lp /**< current LP data */
5345  )
5346 {
5347  assert(blkmem != NULL);
5348  assert(row != NULL);
5349  assert(*row != NULL);
5350  assert((*row)->nuses >= 1);
5351  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5352 
5353  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5354  (*row)->nuses--;
5355  if( (*row)->nuses == 0 )
5356  {
5357  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5358  }
5359 
5360  *row = NULL;
5361 
5362  return SCIP_OKAY;
5363 }
5364 
5365 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5367  SCIP_ROW* row /**< LP row */
5368  )
5369 {
5370  assert(row != NULL);
5371 
5372  /* check, if row is modifiable */
5373  if( !row->modifiable )
5374  {
5375  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5376  row->nlocks++;
5377  }
5378 }
5379 
5380 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5382  SCIP_ROW* row /**< LP row */
5383  )
5384 {
5385  assert(row != NULL);
5386 
5387  /* check, if row is modifiable */
5388  if( !row->modifiable )
5389  {
5390  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5391  assert(row->nlocks > 0);
5392  row->nlocks--;
5393  }
5394 }
5395 
5396 /** adds a previously non existing coefficient to an LP row */
5398  SCIP_ROW* row, /**< LP row */
5399  BMS_BLKMEM* blkmem, /**< block memory */
5400  SCIP_SET* set, /**< global SCIP settings */
5401  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5402  SCIP_LP* lp, /**< current LP data */
5403  SCIP_COL* col, /**< LP column */
5404  SCIP_Real val /**< value of coefficient */
5405  )
5406 {
5407  assert(lp != NULL);
5408  assert(!lp->diving || row->lppos == -1);
5409 
5410  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5411 
5412  checkLinks(lp);
5413 
5414  return SCIP_OKAY;
5415 }
5416 
5417 /** deletes coefficient from row */
5419  SCIP_ROW* row, /**< row to be changed */
5420  BMS_BLKMEM* blkmem, /**< block memory */
5421  SCIP_SET* set, /**< global SCIP settings */
5422  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5423  SCIP_LP* lp, /**< current LP data */
5424  SCIP_COL* col /**< coefficient to be deleted */
5425  )
5426 {
5427  int pos;
5428 
5429  assert(row != NULL);
5430  assert(!row->delaysort);
5431  assert(lp != NULL);
5432  assert(!lp->diving || row->lppos == -1);
5433  assert(col != NULL);
5434  assert(col->var != NULL);
5435 
5436  /* search the position of the column in the row's col vector */
5437  pos = rowSearchCoef(row, col);
5438  if( pos == -1 )
5439  {
5440  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5441  return SCIP_INVALIDDATA;
5442  }
5443  assert(0 <= pos && pos < row->len);
5444  assert(row->cols[pos] == col);
5445  assert(row->cols_index[pos] == col->index);
5446 
5447  /* if column knows of the row, remove the row from the column's row vector */
5448  if( row->linkpos[pos] >= 0 )
5449  {
5450  assert(col->rows[row->linkpos[pos]] == row);
5451  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5452  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5453  }
5454 
5455  /* delete the column from the row's col vector */
5456  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5457 
5458  checkLinks(lp);
5459 
5460  return SCIP_OKAY;
5461 }
5462 
5463 /** changes or adds a coefficient to an LP row */
5465  SCIP_ROW* row, /**< LP row */
5466  BMS_BLKMEM* blkmem, /**< block memory */
5467  SCIP_SET* set, /**< global SCIP settings */
5468  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5469  SCIP_LP* lp, /**< current LP data */
5470  SCIP_COL* col, /**< LP column */
5471  SCIP_Real val /**< value of coefficient */
5472  )
5473 {
5474  int pos;
5475 
5476  assert(row != NULL);
5477  assert(!row->delaysort);
5478  assert(lp != NULL);
5479  assert(!lp->diving || row->lppos == -1);
5480  assert(col != NULL);
5481 
5482  /* search the position of the column in the row's col vector */
5483  pos = rowSearchCoef(row, col);
5484 
5485  /* check, if column already exists in the row's col vector */
5486  if( pos == -1 )
5487  {
5488  /* add previously not existing coefficient */
5489  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5490  }
5491  else
5492  {
5493  /* modify already existing coefficient */
5494  assert(0 <= pos && pos < row->len);
5495  assert(row->cols[pos] == col);
5496  assert(row->cols_index[pos] == col->index);
5497 
5498  /* if column knows of the row, change the corresponding coefficient in the column */
5499  if( row->linkpos[pos] >= 0 )
5500  {
5501  assert(col->rows[row->linkpos[pos]] == row);
5502  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5503  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5504  }
5505 
5506  /* change the coefficient in the row */
5507  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5508  }
5509 
5510  checkLinks(lp);
5511 
5512  return SCIP_OKAY;
5513 }
5514 
5515 /** increases value of an existing or non-existing coefficient in an LP row */
5517  SCIP_ROW* row, /**< LP row */
5518  BMS_BLKMEM* blkmem, /**< block memory */
5519  SCIP_SET* set, /**< global SCIP settings */
5520  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5521  SCIP_LP* lp, /**< current LP data */
5522  SCIP_COL* col, /**< LP column */
5523  SCIP_Real incval /**< value to add to the coefficient */
5524  )
5525 {
5526  int pos;
5527 
5528  assert(row != NULL);
5529  assert(lp != NULL);
5530  assert(!lp->diving || row->lppos == -1);
5531  assert(col != NULL);
5532 
5533  if( SCIPsetIsZero(set, incval) )
5534  return SCIP_OKAY;
5535 
5536  /* search the position of the column in the row's col vector */
5537  pos = rowSearchCoef(row, col);
5538 
5539  /* check, if column already exists in the row's col vector */
5540  if( pos == -1 )
5541  {
5542  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5543  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5544  }
5545  else
5546  {
5547  /* modify already existing coefficient */
5548  assert(0 <= pos && pos < row->len);
5549  assert(row->cols[pos] == col);
5550  assert(row->cols_index[pos] == col->index);
5551 
5552  /* if column knows of the row, change the corresponding coefficient in the column */
5553  if( row->linkpos[pos] >= 0 )
5554  {
5555  assert(col->rows[row->linkpos[pos]] == row);
5556  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5557  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5558  }
5559 
5560  /* change the coefficient in the row */
5561  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5562  }
5563 
5564  checkLinks(lp);
5565 
5566  /* invalid the activity */
5567  row->validactivitylp = -1;
5568 
5569  return SCIP_OKAY;
5570 }
5571 
5572 /** changes constant value of a row */
5574  SCIP_ROW* row, /**< LP row */
5575  BMS_BLKMEM* blkmem, /**< block memory */
5576  SCIP_SET* set, /**< global SCIP settings */
5577  SCIP_STAT* stat, /**< problem statistics */
5578  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5579  SCIP_LP* lp, /**< current LP data */
5580  SCIP_Real constant /**< new constant value */
5581  )
5582 {
5583  assert(row != NULL);
5584  assert(row->lhs <= row->rhs);
5585  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5586  assert(stat != NULL);
5587  assert(lp != NULL);
5588  assert(!lp->diving || row->lppos == -1);
5589 
5590  if( !SCIPsetIsEQ(set, constant, row->constant) )
5591  {
5592  SCIP_Real oldconstant;
5593 
5594  if( row->validpsactivitydomchg == stat->domchgcount )
5595  {
5596  assert(row->pseudoactivity < SCIP_INVALID);
5597  row->pseudoactivity += constant - row->constant;
5598  }
5599  if( row->validactivitybdsdomchg == stat->domchgcount )
5600  {
5601  assert(row->minactivity < SCIP_INVALID);
5602  assert(row->maxactivity < SCIP_INVALID);
5603  row->minactivity += constant - row->constant;
5604  row->maxactivity += constant - row->constant;
5605  }
5606 
5607  if( !SCIPsetIsInfinity(set, -row->lhs) )
5608  {
5609  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5610  }
5611  if( !SCIPsetIsInfinity(set, row->rhs) )
5612  {
5613  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5614  }
5615 
5616  oldconstant = row->constant;
5617 
5618  row->constant = constant;
5619 
5620  /* issue row constant changed event */
5621  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5622  }
5623 
5624  return SCIP_OKAY;
5625 }
5626 
5627 /** add constant value to a row */
5629  SCIP_ROW* row, /**< LP row */
5630  BMS_BLKMEM* blkmem, /**< block memory */
5631  SCIP_SET* set, /**< global SCIP settings */
5632  SCIP_STAT* stat, /**< problem statistics */
5633  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5634  SCIP_LP* lp, /**< current LP data */
5635  SCIP_Real addval /**< constant value to add to the row */
5636  )
5637 {
5638  assert(row != NULL);
5639  assert(row->lhs <= row->rhs);
5640  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5641  assert(stat != NULL);
5642  assert(lp != NULL);
5643  assert(!lp->diving || row->lppos == -1);
5644 
5645  if( !SCIPsetIsZero(set, addval) )
5646  {
5647  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5648  }
5649 
5650  return SCIP_OKAY;
5651 }
5652 
5653 /** changes left hand side of LP row */
5655  SCIP_ROW* row, /**< LP row */
5656  BMS_BLKMEM* blkmem, /**< block memory */
5657  SCIP_SET* set, /**< global SCIP settings */
5658  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5659  SCIP_LP* lp, /**< current LP data */
5660  SCIP_Real lhs /**< new left hand side */
5661  )
5662 {
5663  assert(row != NULL);
5664  assert(lp != NULL);
5665 
5666  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5667  {
5668  SCIP_Real oldlhs;
5669 
5670  oldlhs = row->lhs;
5671 
5672  row->lhs = lhs;
5673  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5674 
5675  if( !lp->diving )
5676  {
5677  /* issue row side changed event */
5678  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5679  }
5680  }
5681 
5682  return SCIP_OKAY;
5683 }
5684 
5685 /** changes right hand side of LP row */
5687  SCIP_ROW* row, /**< LP row */
5688  BMS_BLKMEM* blkmem, /**< block memory */
5689  SCIP_SET* set, /**< global SCIP settings */
5690  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5691  SCIP_LP* lp, /**< current LP data */
5692  SCIP_Real rhs /**< new right hand side */
5693  )
5694 {
5695  assert(row != NULL);
5696  assert(lp != NULL);
5697 
5698  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5699  {
5700  SCIP_Real oldrhs;
5701 
5702  oldrhs = row->rhs;
5703 
5704  row->rhs = rhs;
5705  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5706 
5707  if( !lp->diving )
5708  {
5709  /* issue row side changed event */
5710  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5711  }
5712  }
5713 
5714  return SCIP_OKAY;
5715 }
5716 
5717 /** changes the local flag of LP row */
5719  SCIP_ROW* row, /**< LP row */
5720  SCIP_Bool local /**< new value for local flag */
5721  )
5722 {
5723  assert(row != NULL);
5724 
5725  row->local = local;
5726 
5727  return SCIP_OKAY;
5728 }
5729 
5730 /** additional scalars that are tried in integrality scaling */
5731 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5732 static const int nscalars = 9;
5733 
5734 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5736  SCIP_ROW* row, /**< LP row */
5737  SCIP_SET* set, /**< global SCIP settings */
5738  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5739  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5740  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5741  SCIP_Real maxscale, /**< maximal allowed scalar */
5742  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5743  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5744  SCIP_Bool* success /**< stores whether returned value is valid */
5745  )
5746 {
5747 #ifndef NDEBUG
5748  SCIP_COL* col;
5749 #endif
5750  SCIP_Longint gcd;
5751  SCIP_Longint scm;
5752  SCIP_Longint nominator;
5753  SCIP_Longint denominator;
5754  SCIP_Real val;
5755  SCIP_Real absval;
5756  SCIP_Real minval;
5757  SCIP_Real scaleval;
5758  SCIP_Real twomultval;
5759  SCIP_Bool scalable;
5760  SCIP_Bool twomult;
5761  SCIP_Bool rational;
5762  int c;
5763  int s;
5764 
5765  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5766  assert(row != NULL);
5767  assert(row->len == 0 || row->cols != NULL);
5768  assert(row->len == 0 || row->cols_index != NULL);
5769  assert(row->len == 0 || row->vals != NULL);
5770  assert(maxdnom >= 1);
5771  assert(mindelta < 0.0);
5772  assert(maxdelta > 0.0);
5773  assert(success != NULL);
5774 
5775  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5776  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5777 
5778  if( intscalar != NULL )
5779  *intscalar = SCIP_INVALID;
5780  *success = FALSE;
5781 
5782  /* get minimal absolute non-zero value */
5783  minval = SCIP_REAL_MAX;
5784  for( c = 0; c < row->len; ++c )
5785  {
5786 #ifndef NDEBUG
5787  col = row->cols[c];
5788  assert(col != NULL);
5789  assert(col->var != NULL);
5790  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5791  assert(SCIPvarGetCol(col->var) == col);
5792 #endif
5793  val = row->vals[c];
5794  assert(!SCIPsetIsZero(set, val));
5795 
5796  if( val < mindelta || val > maxdelta )
5797  {
5798  absval = REALABS(val);
5799  minval = MIN(minval, absval);
5800  }
5801  }
5802  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5803  {
5804  /* all coefficients are zero (inside tolerances) */
5805  if( intscalar != NULL )
5806  *intscalar = 1.0;
5807  *success = TRUE;
5808  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5809 
5810  return SCIP_OKAY;
5811  }
5812  assert(minval > MIN(-mindelta, maxdelta));
5813  assert(SCIPsetIsPositive(set, minval));
5814  assert(!SCIPsetIsInfinity(set, minval));
5815 
5816  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5817  * and a power of 2
5818  */
5819  scaleval = 1.0/minval;
5820  scalable = (scaleval <= maxscale);
5821  for( c = 0; c < row->len && scalable; ++c )
5822  {
5823  /* don't look at continuous variables, if we don't have to */
5824  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5825  continue;
5826 
5827  /* check, if the coefficient can be scaled with a simple scalar */
5828  val = row->vals[c];
5829  absval = REALABS(val);
5830  while( scaleval <= maxscale
5831  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5832  {
5833  for( s = 0; s < nscalars; ++s )
5834  {
5835  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5836  {
5837  scaleval *= scalars[s];
5838  break;
5839  }
5840  }
5841  if( s >= nscalars )
5842  scaleval *= 2.0;
5843  }
5844  scalable = (scaleval <= maxscale);
5845  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5846  }
5847  if( scalable )
5848  {
5849  /* make row coefficients integral by dividing them by the smallest coefficient
5850  * (and multiplying them with a power of 2)
5851  */
5852  assert(scaleval <= maxscale);
5853  if( intscalar != NULL )
5854  *intscalar = scaleval;
5855  *success = TRUE;
5856  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5857 
5858  return SCIP_OKAY;
5859  }
5860 
5861  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5862  twomultval = 1.0;
5863  twomult = (twomultval <= maxscale);
5864  for( c = 0; c < row->len && twomult; ++c )
5865  {
5866  /* don't look at continuous variables, if we don't have to */
5867  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5868  continue;
5869 
5870  /* check, if the coefficient can be scaled with a simple scalar */
5871  val = row->vals[c];
5872  absval = REALABS(val);
5873  while( twomultval <= maxscale
5874  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5875  {
5876  for( s = 0; s < nscalars; ++s )
5877  {
5878  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5879  {
5880  twomultval *= scalars[s];
5881  break;
5882  }
5883  }
5884  if( s >= nscalars )
5885  twomultval *= 2.0;
5886  }
5887  twomult = (twomultval <= maxscale);
5888  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5889  val, twomultval, val*twomultval, twomult);
5890  }
5891  if( twomult )
5892  {
5893  /* make row coefficients integral by multiplying them with a power of 2 */
5894  assert(twomultval <= maxscale);
5895  if( intscalar != NULL )
5896  *intscalar = twomultval;
5897  *success = TRUE;
5898  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5899 
5900  return SCIP_OKAY;
5901  }
5902 
5903  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5904  * and the smallest common multiple of the denominators
5905  */
5906  gcd = 1;
5907  scm = 1;
5908  rational = (maxdnom > 1);
5909 
5910  /* first coefficient (to initialize gcd) */
5911  for( c = 0; c < row->len && rational; ++c )
5912  {
5913  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5914  {
5915  val = row->vals[c];
5916  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5917  if( rational && nominator != 0 )
5918  {
5919  assert(denominator > 0);
5920  gcd = ABS(nominator);
5921  scm = denominator;
5922  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5923  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5924  val, nominator, denominator, gcd, scm, rational);
5925  break;
5926  }
5927  }
5928  }
5929 
5930  /* remaining coefficients */
5931  for( ++c; c < row->len && rational; ++c )
5932  {
5933  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5934  {
5935  val = row->vals[c];
5936  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5937  if( rational && nominator != 0 )
5938  {
5939  assert(denominator > 0);
5940  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5941  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5942  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5943  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5944  val, nominator, denominator, gcd, scm, rational);
5945  }
5946  }
5947  }
5948 
5949  if( rational )
5950  {
5951  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5952  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5953  if( intscalar != NULL )
5954  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5955  *success = TRUE;
5956  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5957  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5958  }
5959  else
5960  {
5961  assert(!(*success));
5962  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5963  }
5964 
5965  return SCIP_OKAY;
5966 }
5967 
5968 /** tries to scale row, s.t. all coefficients become integral */
5970  SCIP_ROW* row, /**< LP row */
5971  BMS_BLKMEM* blkmem, /**< block memory */
5972  SCIP_SET* set, /**< global SCIP settings */
5973  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5974  SCIP_STAT* stat, /**< problem statistics */
5975  SCIP_LP* lp, /**< current LP data */
5976  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5977  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5978  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5979  SCIP_Real maxscale, /**< maximal value to scale row with */
5980  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5981  SCIP_Bool* success /**< stores whether row could be made rational */
5982  )
5983 {
5984  SCIP_Real intscalar;
5985 
5986  assert(success != NULL);
5987 
5988  /* calculate scalar to make coefficients integral */
5989  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5990  &intscalar, success) );
5991 
5992  if( *success )
5993  {
5994  /* scale the row */
5995  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
5996  }
5997 
5998  return SCIP_OKAY;
5999 }
6000 
6001 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6002  * higher ones
6003  */
6005  SCIP_ROW* row /**< row to be sorted */
6006  )
6007 {
6008  assert(row != NULL);
6009 
6010  /* sort LP columns */
6011  rowSortLP(row);
6012 
6013  /* sort non-LP columns */
6014  rowSortNonLP(row);
6015 
6016 #ifdef SCIP_MORE_DEBUG
6017  /* check the sorting */
6018  {
6019  int c;
6020  if( !row->delaysort )
6021  {
6022  for( c = 1; c < row->nlpcols; ++c )
6023  assert(row->cols[c]->index >= row->cols[c-1]->index);
6024  for( c = row->nlpcols + 1; c < row->len; ++c )
6025  assert(row->cols[c]->index >= row->cols[c-1]->index);
6026  }
6027  }
6028 #endif
6029 }
6030 
6031 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6032  * zero entries from row
6033  * the row must not be linked to the columns; otherwise, we would need to update the columns as
6034  * well, which is too expensive
6035  */
6036 static
6038  SCIP_ROW* row, /**< row to be sorted */
6039  SCIP_SET* set /**< global SCIP settings */
6040  )
6041 {
6042  assert(row != NULL);
6043  assert(!row->delaysort);
6044  assert(row->nunlinked == row->len);
6045  assert(row->nlpcols == 0);
6046 
6047  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6048 
6049  /* do nothing on empty rows; if row is sorted, nothing has to be done */
6050  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6051  {
6052  SCIP_COL** cols;
6053  int* cols_index;
6054  SCIP_Real* vals;
6055  int s;
6056  int t;
6057 
6058  /* make sure, the row is sorted */
6059  SCIProwSort(row);
6060  assert(row->lpcolssorted);
6061  assert(row->nonlpcolssorted);
6062 
6063  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6064  cols = row->cols;
6065  cols_index = row->cols_index;
6066  vals = row->vals;
6067  assert(cols != NULL);
6068  assert(cols_index != NULL);
6069  assert(vals != NULL);
6070 
6071  t = 0;
6072  row->integral = TRUE;
6073  assert(!SCIPsetIsZero(set, vals[0]));
6074  assert(row->linkpos[0] == -1);
6075 
6076  for( s = 1; s < row->len; ++s )
6077  {
6078  assert(!SCIPsetIsZero(set, vals[s]));
6079  assert(row->linkpos[s] == -1);
6080 
6081  if( cols[s] == cols[t] )
6082  {
6083  /* merge entries with equal column */
6084  vals[t] += vals[s];
6085  }
6086  else
6087  {
6088  /* go to the next entry, overwriting current entry if coefficient is zero */
6089  if( !SCIPsetIsZero(set, vals[t]) )
6090  {
6091  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6092  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6093 
6094  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6095  t++;
6096  }
6097  cols[t] = cols[s];
6098  cols_index[t] = cols_index[s];
6099  vals[t] = vals[s];
6100  }
6101  }
6102  if( !SCIPsetIsZero(set, vals[t]) )
6103  {
6104  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6105  t++;
6106  }
6107  assert(s == row->len);
6108  assert(t <= row->len);
6109 
6110  row->len = t;
6111  row->nunlinked = t;
6112 
6113  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6114  if( t < s )
6115  rowCalcNorms(row, set);
6116  }
6117 
6118 #ifndef NDEBUG
6119  /* check for double entries */
6120  {
6121  int i;
6122  int j;
6123 
6124  for( i = 0; i < row->len; ++i )
6125  {
6126  assert(row->cols[i] != NULL);
6127  assert(row->cols[i]->index == row->cols_index[i]);
6128  for( j = i+1; j < row->len; ++j )
6129  assert(row->cols[i] != row->cols[j]);
6130  }
6131  }
6132 #endif
6133 }
6134 
6135 /** enables delaying of row sorting */
6137  SCIP_ROW* row /**< LP row */
6138  )
6139 {
6140  assert(row != NULL);
6141  assert(!row->delaysort);
6142 
6143  row->delaysort = TRUE;
6144 }
6145 
6146 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6148  SCIP_ROW* row, /**< LP row */
6149  SCIP_SET* set /**< global SCIP settings */
6150  )
6151 {
6152  assert(row != NULL);
6153  assert(row->delaysort);
6154 
6155  row->delaysort = FALSE;
6156  rowMerge(row, set);
6157 }
6158 
6159 /** recalculates the current activity of a row */
6161  SCIP_ROW* row, /**< LP row */
6162  SCIP_STAT* stat /**< problem statistics */
6163  )
6164 {
6165  SCIP_COL* col;
6166  int c;
6167 
6168  assert(row != NULL);
6169  assert(stat != NULL);
6170 
6171  row->activity = row->constant;
6172  for( c = 0; c < row->nlpcols; ++c )
6173  {
6174  col = row->cols[c];
6175  assert(col != NULL);
6176  assert(col->primsol < SCIP_INVALID);
6177  assert(col->lppos >= 0);
6178  assert(row->linkpos[c] >= 0);
6179  row->activity += row->vals[c] * col->primsol;
6180  }
6181 
6182  if( row->nunlinked > 0 )
6183  {
6184  for( c = row->nlpcols; c < row->len; ++c )
6185  {
6186  col = row->cols[c];
6187  assert(col != NULL);
6188  assert(col->lppos >= 0 || col->primsol == 0.0);
6189  assert(col->lppos == -1 || row->linkpos[c] == -1);
6190  if( col->lppos >= 0 )
6191  row->activity += row->vals[c] * col->primsol;
6192  }
6193  }
6194 #ifndef NDEBUG
6195  else
6196  {
6197  for( c = row->nlpcols; c < row->len; ++c )
6198  {
6199  col = row->cols[c];
6200  assert(col != NULL);
6201  assert(col->primsol == 0.0);
6202  assert(col->lppos == -1);
6203  assert(row->linkpos[c] >= 0);
6204  }
6205  }
6206 #endif
6207 
6208  row->validactivitylp = stat->lpcount;
6209 }
6210 
6211 /** returns the activity of a row in the current LP solution */
6213  SCIP_ROW* row, /**< LP row */
6214  SCIP_SET* set, /**< global SCIP settings */
6215  SCIP_STAT* stat, /**< problem statistics */
6216  SCIP_LP* lp /**< current LP data */
6217  )
6218 {
6219  SCIP_Real inf;
6220  SCIP_Real activity;
6221 
6222  assert(row != NULL);
6223  assert(stat != NULL);
6224  assert(lp != NULL);
6225  assert(row->validactivitylp <= stat->lpcount);
6226  assert(lp->validsollp == stat->lpcount);
6227 
6228  if( row->validactivitylp != stat->lpcount )
6229  SCIProwRecalcLPActivity(row, stat);
6230  assert(row->validactivitylp == stat->lpcount);
6231  assert(row->activity < SCIP_INVALID);
6232 
6233  activity = row->activity;
6234  inf = SCIPsetInfinity(set);
6235  activity = MAX(activity, -inf);
6236  activity = MIN(activity, +inf);
6237 
6238  return activity;
6239 }
6240 
6241 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6243  SCIP_ROW* row, /**< LP row */
6244  SCIP_SET* set, /**< global SCIP settings */
6245  SCIP_STAT* stat, /**< problem statistics */
6246  SCIP_LP* lp /**< current LP data */
6247  )
6248 {
6249  SCIP_Real activity;
6250 
6251  assert(row != NULL);
6252 
6253  activity = SCIProwGetLPActivity(row, set, stat, lp);
6254 
6255  return MIN(row->rhs - activity, activity - row->lhs);
6256 }
6257 
6258 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6259  *
6260  * @todo Implement calculation of activities similar to LPs.
6261  */
6263  SCIP_ROW* row, /**< LP row */
6264  SCIP_SET* set, /**< global SCIP settings */
6265  SCIP_STAT* stat /**< problem statistics */
6266  )
6267 {
6268  SCIP_Real inf;
6269  SCIP_Real activity;
6270  SCIP_COL* col;
6271  int c;
6272 
6273  assert( row != NULL );
6274  assert( stat != NULL );
6275 
6276  activity = row->constant;
6277  for (c = 0; c < row->nlpcols; ++c)
6278  {
6279  col = row->cols[c];
6280  assert( col != NULL );
6281  assert( col->lppos >= 0 );
6282  assert( col->var != NULL );
6283  assert( row->linkpos[c] >= 0 );
6284  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6285  }
6286 
6287  if ( row->nunlinked > 0 )
6288  {
6289  for (c = row->nlpcols; c < row->len; ++c)
6290  {
6291  col = row->cols[c];
6292  assert( col != NULL );
6293  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6294  if ( col->lppos >= 0 )
6295  {
6296  assert( col->var != NULL );
6297  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6298  }
6299  }
6300  }
6301 #ifndef NDEBUG
6302  else
6303  {
6304  for (c = row->nlpcols; c < row->len; ++c)
6305  {
6306  col = row->cols[c];
6307  assert( col != NULL );
6308  assert( col->lppos == -1 );
6309  assert( row->linkpos[c] >= 0 );
6310  }
6311  }
6312 #endif
6313  inf = SCIPsetInfinity(set);
6314  activity = MAX(activity, -inf);
6315  activity = MIN(activity, +inf);
6316 
6317  return MIN(row->rhs - activity, activity - row->lhs);
6318 }
6319 
6320 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6321  *
6322  * @todo Implement calculation of activities similar to LPs.
6323  */
6325  SCIP_ROW* row, /**< LP row */
6326  SCIP_SET* set, /**< global SCIP settings */
6327  SCIP_STAT* stat /**< problem statistics */
6328  )
6329 {
6330  SCIP_Real inf;
6331  SCIP_Real activity;
6332  SCIP_COL* col;
6333  int c;
6334 
6335  assert( row != NULL );
6336  assert( stat != NULL );
6337 
6338  activity = row->constant;
6339  for (c = 0; c < row->nlpcols; ++c)
6340  {
6341  col = row->cols[c];
6342  assert( col != NULL );
6343  assert( col->lppos >= 0 );
6344  assert( col->var != NULL );
6345  assert( row->linkpos[c] >= 0 );
6346  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6347  }
6348 
6349  if ( row->nunlinked > 0 )
6350  {
6351  for (c = row->nlpcols; c < row->len; ++c)
6352  {
6353  col = row->cols[c];
6354  assert( col != NULL );
6355  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6356  if ( col->lppos >= 0 )
6357  {
6358  assert( col->var != NULL );
6359  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6360  }
6361  }
6362  }
6363 #ifndef NDEBUG
6364  else
6365  {
6366  for (c = row->nlpcols; c < row->len; ++c)
6367  {
6368  col = row->cols[c];
6369  assert( col != NULL );
6370  assert( col->lppos == -1 );
6371  assert( row->linkpos[c] >= 0 );
6372  }
6373  }
6374 #endif
6375  inf = SCIPsetInfinity(set);
6376  activity = MAX(activity, -inf);
6377  activity = MIN(activity, +inf);
6378 
6379  return MIN(row->rhs - activity, activity - row->lhs);
6380 }
6381 
6382 /** calculates the current pseudo activity of a row */
6384  SCIP_ROW* row, /**< row data */
6385  SCIP_STAT* stat /**< problem statistics */
6386  )
6387 {
6388  SCIP_COL* col;
6389  int i;
6390 
6391  assert(row != NULL);
6392  assert(stat != NULL);
6393 
6394  row->pseudoactivity = row->constant;
6395  for( i = 0; i < row->len; ++i )
6396  {
6397  col = row->cols[i];
6398  assert(col != NULL);
6399  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6400  assert(col->var != NULL);
6401  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6402 
6403  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6404  }
6405  row->validpsactivitydomchg = stat->domchgcount;
6406  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6407 }
6408 
6409 /** returns the pseudo activity of a row in the current pseudo solution */
6411  SCIP_ROW* row, /**< LP row */
6412  SCIP_SET* set, /**< global SCIP settings */
6413  SCIP_STAT* stat /**< problem statistics */
6414  )
6415 {
6416  SCIP_Real inf;
6417  SCIP_Real activity;
6418 
6419  assert(row != NULL);
6420  assert(stat != NULL);
6421  assert(row->validpsactivitydomchg <= stat->domchgcount);
6422 
6423  /* check, if pseudo activity has to be calculated */
6424  if( row->validpsactivitydomchg != stat->domchgcount )
6425  SCIProwRecalcPseudoActivity(row, stat);
6426  assert(row->validpsactivitydomchg == stat->domchgcount);
6427  assert(row->pseudoactivity < SCIP_INVALID);
6428 
6429  activity = row->pseudoactivity;
6430  inf = SCIPsetInfinity(set);
6431  activity = MAX(activity, -inf);
6432  activity = MIN(activity, +inf);
6433 
6434  return activity;
6435 }
6436 
6437 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6439  SCIP_ROW* row, /**< LP row */
6440  SCIP_SET* set, /**< global SCIP settings */
6441  SCIP_STAT* stat /**< problem statistics */
6442  )
6443 {
6444  SCIP_Real pseudoactivity;
6445 
6446  assert(row != NULL);
6447 
6448  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6449 
6450  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6451 }
6452 
6453 /** returns the activity of a row for a given solution */
6455  SCIP_ROW* row, /**< LP row */
6456  SCIP_SET* set, /**< global SCIP settings */
6457  SCIP_STAT* stat, /**< problem statistics data */
6458  SCIP_SOL* sol /**< primal CIP solution */
6459  )
6460 {
6461  SCIP_COL* col;
6462  SCIP_Real inf;
6463  SCIP_Real activity;
6464  SCIP_Real solval;
6465  int i;
6466 
6467  assert(row != NULL);
6468 
6469  activity = row->constant;
6470  for( i = 0; i < row->len; ++i )
6471  {
6472  col = row->cols[i];
6473  assert(col != NULL);
6474  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6475  solval = SCIPsolGetVal(sol, set, stat, col->var);
6476  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6477  {
6478  if( SCIPsetIsInfinity(set, -row->lhs) )
6479  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6480  else if( SCIPsetIsInfinity(set, row->rhs) )
6481  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6482  else
6483  solval = (col->lb + col->ub)/2.0;
6484  }
6485  activity += row->vals[i] * solval;
6486  }
6487 
6488  inf = SCIPsetInfinity(set);
6489  activity = MAX(activity, -inf);
6490  activity = MIN(activity, +inf);
6491 
6492  return activity;
6493 }
6494 
6495 /** returns the feasibility of a row for the given solution */
6497  SCIP_ROW* row, /**< LP row */
6498  SCIP_SET* set, /**< global SCIP settings */
6499  SCIP_STAT* stat, /**< problem statistics data */
6500  SCIP_SOL* sol /**< primal CIP solution */
6501  )
6502 {
6503  SCIP_Real activity;
6504 
6505  assert(row != NULL);
6506 
6507  activity = SCIProwGetSolActivity(row, set, stat, sol);
6508 
6509  return MIN(row->rhs - activity, activity - row->lhs);
6510 }
6511 
6512 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6513 static
6515  SCIP_ROW* row, /**< row data */
6516  SCIP_SET* set, /**< global SCIP settings */
6517  SCIP_STAT* stat /**< problem statistics data */
6518  )
6519 {
6520  SCIP_COL* col;
6521  SCIP_Real val;
6522  SCIP_Bool mininfinite;
6523  SCIP_Bool maxinfinite;
6524  int i;
6525 
6526  assert(row != NULL);
6527  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6528  assert(stat != NULL);
6529 
6530  /* calculate activity bounds */
6531  mininfinite = FALSE;
6532  maxinfinite = FALSE;
6533  row->minactivity = row->constant;
6534  row->maxactivity = row->constant;
6535  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6536  {
6537  col = row->cols[i];
6538  assert(col != NULL);
6539  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6540  val = row->vals[i];
6541  if( val >= 0.0 )
6542  {
6543  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6544  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6545  if( !mininfinite )
6546  row->minactivity += val * col->lb;
6547  if( !maxinfinite )
6548  row->maxactivity += val * col->ub;
6549  }
6550  else
6551  {
6552  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6553  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6554  if( !mininfinite )
6555  row->minactivity += val * col->ub;
6556  if( !maxinfinite )
6557  row->maxactivity += val * col->lb;
6558  }
6559  }
6560 
6561  if( mininfinite )
6562  row->minactivity = -SCIPsetInfinity(set);
6563  if( maxinfinite )
6564  row->maxactivity = SCIPsetInfinity(set);
6565  row->validactivitybdsdomchg = stat->domchgcount;
6566 
6567 #ifndef NDEBUG
6568  {
6569  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6570 
6571  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6572  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6573  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6574  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6575  * tolerance as a proxy to account for the accumulation effect
6576  */
6577  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6578  || EPSISINT(row->minactivity - row->constant, inttol));
6579  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6580  || EPSISINT(row->maxactivity - row->constant, inttol));
6581  }
6582 #endif
6583 }
6584 
6585 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6587  SCIP_ROW* row, /**< LP row */
6588  SCIP_SET* set, /**< global SCIP settings */
6589  SCIP_STAT* stat /**< problem statistics data */
6590  )
6591 {
6592  assert(row != NULL);
6593  assert(stat != NULL);
6594  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6595 
6596  /* check, if activity bounds has to be calculated */
6597  if( row->validactivitybdsdomchg != stat->domchgcount )
6598  rowCalcActivityBounds(row, set, stat);
6599  assert(row->validactivitybdsdomchg == stat->domchgcount);
6600  assert(row->minactivity < SCIP_INVALID);
6601  assert(row->maxactivity < SCIP_INVALID);
6602 
6603  return row->minactivity;
6604 }
6605 
6606 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6608  SCIP_ROW* row, /**< LP row */
6609  SCIP_SET* set, /**< global SCIP settings */
6610  SCIP_STAT* stat /**< problem statistics data */
6611  )
6612 {
6613  assert(row != NULL);
6614  assert(stat != NULL);
6615  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6616 
6617  /* check, if activity bounds has to be calculated */
6618  if( row->validactivitybdsdomchg != stat->domchgcount )
6619  rowCalcActivityBounds(row, set, stat);
6620  assert(row->validactivitybdsdomchg == stat->domchgcount);
6621  assert(row->minactivity < SCIP_INVALID);
6622  assert(row->maxactivity < SCIP_INVALID);
6623 
6624  return row->maxactivity;
6625 }
6626 
6627 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6629  SCIP_ROW* row, /**< LP row */
6630  SCIP_SET* set, /**< global SCIP settings */
6631  SCIP_STAT* stat /**< problem statistics data */
6632  )
6633 {
6634  assert(row != NULL);
6635 
6636  if( row->modifiable )
6637  return FALSE;
6638  if( !SCIPsetIsInfinity(set, -row->lhs) )
6639  {
6640  SCIP_Real minactivity;
6641 
6642  minactivity = SCIProwGetMinActivity(row, set, stat);
6643  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6644  return FALSE;
6645  }
6646  if( !SCIPsetIsInfinity(set, row->rhs) )
6647  {
6648  SCIP_Real maxactivity;
6649 
6650  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6651  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6652  return FALSE;
6653  }
6654 
6655  return TRUE;
6656 }
6657 
6658 /** gets maximal absolute value of row vector coefficients */
6660  SCIP_ROW* row, /**< LP row */
6661  SCIP_SET* set /**< global SCIP settings */
6662  )
6663 {
6664  assert(row != NULL);
6665 
6666  if( row->nummaxval == 0 )
6667  rowCalcIdxsAndVals(row, set);
6668  assert(row->nummaxval > 0);
6669  assert(row->maxval >= 0.0 || row->len == 0);
6670 
6671  return row->maxval;
6672 }
6673 
6674 /** gets minimal absolute value of row vector's non-zero coefficients */
6676  SCIP_ROW* row, /**< LP row */
6677  SCIP_SET* set /**< global SCIP settings */
6678  )
6679 {
6680  assert(row != NULL);
6681 
6682  if( row->numminval == 0 )
6683  rowCalcIdxsAndVals(row, set);
6684  assert(row->numminval > 0);
6685  assert(row->minval >= 0.0 || row->len == 0);
6686 
6687  return row->minval;
6688 }
6689 
6690 /** gets maximal column index of row entries */
6692  SCIP_ROW* row, /**< LP row */
6693  SCIP_SET* set /**< global SCIP settings */
6694  )
6695 {
6696  assert(row != NULL);
6697 
6698  if( row->validminmaxidx == 0 )
6699  rowCalcIdxsAndVals(row, set);
6700  assert(row->maxidx >= 0 || row->len == 0);
6701  assert(row->validminmaxidx);
6702 
6703  return row->maxidx;
6704 }
6705 
6706 /** gets minimal column index of row entries */
6708  SCIP_ROW* row, /**< LP row */
6709  SCIP_SET* set /**< global SCIP settings */
6710  )
6711 {
6712  assert(row != NULL);
6713 
6714  if( row->validminmaxidx == 0 )
6715  rowCalcIdxsAndVals(row, set);
6716  assert(row->minidx >= 0 || row->len == 0);
6717  assert(row->validminmaxidx);
6718 
6719  return row->minidx;
6720 }
6721 
6722 /** gets number of integral columns in row */
6724  SCIP_ROW* row, /**< LP row */
6725  SCIP_SET* set /**< global SCIP settings */
6726  )
6727 {
6728  assert(row != NULL);
6729 
6730  if( row->numintcols == -1 )
6731  rowCalcIdxsAndVals(row, set);
6732 
6733  assert(row->numintcols <= row->len && row->numintcols >= 0);
6734 
6735  return row->numintcols;
6736 }
6737 
6738 /** returns row's cutoff distance in the direction of the given primal solution */
6740  SCIP_ROW* row, /**< LP row */
6741  SCIP_SET* set, /**< global SCIP settings */
6742  SCIP_STAT* stat, /**< problem statistics data */
6743  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6744  SCIP_LP* lp /**< current LP data */
6745  )
6746 {
6747  SCIP_Real solcutoffdist;
6748  int k;
6749 
6750  assert(sol != NULL);
6751 
6752  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6753  {
6754  SCIP_Real scale = 0.0;
6755 
6756  lp->validsoldirlp = stat->lpcount;
6757  lp->validsoldirsol = sol;
6758 
6760 
6761  for( k = 0; k < lp->ncols; ++k )
6762  {
6763  assert(lp->cols[k]->lppos == k);
6764  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6765  scale += SQR(lp->soldirection[k]);
6766  }
6767 
6768  if( scale > 0.0 )
6769  {
6770  scale = 1.0 / SQRT(scale);
6771 
6772  for( k = 0; k < lp->ncols; ++k )
6773  lp->soldirection[k] *= scale;
6774  }
6775  }
6776 
6777  solcutoffdist = 0.0;
6778  for( k = 0; k < row->nlpcols; ++k )
6779  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6780 
6781  for( k = row->nlpcols; k < row->len; ++k )
6782  {
6783  if( row->cols[k]->lppos >= 0 )
6784  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6785  }
6786 
6787  if( SCIPsetIsSumZero(set, solcutoffdist) )
6788  solcutoffdist = set->num_sumepsilon;
6789 
6790  solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
6791 
6792  return solcutoffdist;
6793 }
6794 
6795 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6797  SCIP_ROW* row, /**< LP row */
6798  SCIP_SET* set, /**< global SCIP settings */
6799  SCIP_STAT* stat, /**< problem statistics data */
6800  SCIP_LP* lp /**< current LP data */
6801  )
6802 {
6803  SCIP_Real norm;
6804  SCIP_Real feasibility;
6805  SCIP_Real eps;
6806 
6807  assert(set != NULL);
6808 
6809  switch( set->sepa_efficacynorm )
6810  {
6811  case 'e':
6812  norm = SCIProwGetNorm(row);
6813  break;
6814  case 'm':
6815  norm = SCIProwGetMaxval(row, set);
6816  break;
6817  case 's':
6818  norm = SCIProwGetSumNorm(row);
6819  break;
6820  case 'd':
6821  norm = (row->len == 0 ? 0.0 : 1.0);
6822  break;
6823  default:
6824  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6825  SCIPABORT();
6826  norm = 0.0; /*lint !e527*/
6827  }
6828 
6829  eps = SCIPsetSumepsilon(set);
6830  norm = MAX(norm, eps);
6831  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6832 
6833  return -feasibility / norm;
6834 }
6835 
6836 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6838  SCIP_ROW* row, /**< LP row */
6839  SCIP_SET* set, /**< global SCIP settings */
6840  SCIP_STAT* stat, /**< problem statistics data */
6841  SCIP_LP* lp, /**< current LP data */
6842  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6843  )
6844 {
6845  SCIP_Real efficacy;
6846 
6847  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6848 
6849  return SCIPsetIsEfficacious(set, root, efficacy);
6850 }
6851 
6852 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6854  SCIP_ROW* row, /**< LP row */
6855  SCIP_SET* set, /**< global SCIP settings */
6856  SCIP_STAT* stat, /**< problem statistics data */
6857  SCIP_SOL* sol /**< primal CIP solution */
6858  )
6859 {
6860  SCIP_Real norm;
6861  SCIP_Real feasibility;
6862  SCIP_Real eps;
6863 
6864  assert(set != NULL);
6865 
6866  switch( set->sepa_efficacynorm )
6867  {
6868  case 'e':
6869  norm = SCIProwGetNorm(row);
6870  break;
6871  case 'm':
6872  norm = SCIProwGetMaxval(row, set);
6873  break;
6874  case 's':
6875  norm = SCIProwGetSumNorm(row);
6876  break;
6877  case 'd':
6878  norm = (row->len == 0 ? 0.0 : 1.0);
6879  break;
6880  default:
6881  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6882  SCIPABORT();
6883  norm = 0.0; /*lint !e527*/
6884  }
6885 
6886  eps = SCIPsetSumepsilon(set);
6887  norm = MAX(norm, eps);
6888  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6889 
6890  return -feasibility / norm;
6891 }
6892 
6893 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6894  * efficacy
6895  */
6897  SCIP_ROW* row, /**< LP row */
6898  SCIP_SET* set, /**< global SCIP settings */
6899  SCIP_STAT* stat, /**< problem statistics data */
6900  SCIP_SOL* sol, /**< primal CIP solution */
6901  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6902  )
6903 {
6904  SCIP_Real efficacy;
6905 
6906  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6907 
6908  return SCIPsetIsEfficacious(set, root, efficacy);
6909 }
6910 
6911 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6913  SCIP_ROW* row, /**< LP row */
6914  SCIP_SET* set, /**< global SCIP settings */
6915  SCIP_STAT* stat /**< problem statistics data */
6916  )
6917 {
6918  SCIP_Real norm;
6919  SCIP_Real feasibility;
6920  SCIP_Real eps;
6921 
6922  assert(set != NULL);
6923 
6924  switch( set->sepa_efficacynorm )
6925  {
6926  case 'e':
6927  norm = SCIProwGetNorm(row);
6928  break;
6929  case 'm':
6930  norm = SCIProwGetMaxval(row, set);
6931  break;
6932  case 's':
6933  norm = SCIProwGetSumNorm(row);
6934  break;
6935  case 'd':
6936  norm = (row->len == 0 ? 0.0 : 1.0);
6937  break;
6938  default:
6939  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6940  SCIPABORT();
6941  norm = 0.0; /*lint !e527*/
6942  }
6943 
6944  eps = SCIPsetSumepsilon(set);
6945  norm = MAX(norm, eps);
6946  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6947 
6948  return -feasibility / norm;
6949 }
6950 
6951 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6953  SCIP_ROW* row, /**< LP row */
6954  SCIP_SET* set, /**< global SCIP settings */
6955  SCIP_STAT* stat /**< problem statistics data */
6956  )
6957 {
6958  SCIP_Real norm;
6959  SCIP_Real feasibility;
6960  SCIP_Real eps;
6961 
6962  assert(set != NULL);
6963 
6964  switch( set->sepa_efficacynorm )
6965  {
6966  case 'e':
6967  norm = SCIProwGetNorm(row);
6968  break;
6969  case 'm':
6970  norm = SCIProwGetMaxval(row, set);
6971  break;
6972  case 's':
6973  norm = SCIProwGetSumNorm(row);
6974  break;
6975  case 'd':
6976  norm = (row->len == 0 ? 0.0 : 1.0);
6977  break;
6978  default:
6979  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6980  SCIPABORT();
6981  norm = 0.0; /*lint !e527*/
6982  }
6983 
6984  eps = SCIPsetSumepsilon(set);
6985  norm = MAX(norm, eps);
6986  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6987 
6988  return -feasibility / norm;
6989 }
6990 
6991 /** returns the scalar product of the coefficient vectors of the two given rows
6992  *
6993  * @note the scalar product is computed w.r.t. the current LP columns only
6994  * @todo also consider non-LP columns for the computation?
6995  */
6997  SCIP_ROW* row1, /**< first LP row */
6998  SCIP_ROW* row2 /**< second LP row */
6999  )
7000 {
7001  SCIP_Real scalarprod;
7002  int* row1colsidx;
7003  int* row2colsidx;
7004  int i1;
7005  int i2;
7006 
7007  assert(row1 != NULL);
7008  assert(row2 != NULL);
7009 
7010  /* Sort the column indices of both rows.
7011  *
7012  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7013  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7014  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7015  * for both or one of the non-LP columns for both.
7016  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7017  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7018  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7019  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7020  *
7021  * We distinguish the following cases:
7022  *
7023  * 1) both rows have no unlinked columns
7024  * -> we just check the LP partitions
7025  *
7026  * 2) exactly one row is completely unlinked, the other one is completely linked
7027  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7028  * (thus all common LP columns are regarded)
7029  *
7030  * 3) we have unlinked and LP columns in both rows
7031  * -> we need to compare four partitions at once
7032  *
7033  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7034  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7035  * other row
7036  *
7037  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7038  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7039  *
7040  * 5) both rows are completely unlinked
7041  * -> we need to compare two partitions: both complete rows
7042  */
7043  SCIProwSort(row1);
7044  assert(row1->lpcolssorted);
7045  assert(row1->nonlpcolssorted);
7046  SCIProwSort(row2);
7047  assert(row2->lpcolssorted);
7048  assert(row2->nonlpcolssorted);
7049 
7050  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7051  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7052 
7053  row1colsidx = row1->cols_index;
7054  row2colsidx = row2->cols_index;
7055 
7056 #ifndef NDEBUG
7057  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7058  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7059  {
7060  i1 = 0;
7061  i2 = row2->nlpcols;
7062  while( i1 < row1->nlpcols && i2 < row2->len )
7063  {
7064  assert(row1->cols[i1] != row2->cols[i2]);
7065  if( row1->cols[i1]->index < row2->cols[i2]->index )
7066  ++i1;
7067  else
7068  {
7069  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7070  ++i2;
7071  }
7072  }
7073  assert(i1 == row1->nlpcols || i2 == row2->len);
7074 
7075  i1 = row1->nlpcols;
7076  i2 = 0;
7077  while( i1 < row1->len && i2 < row2->nlpcols )
7078  {
7079  assert(row1->cols[i1] != row2->cols[i2]);
7080  if( row1->cols[i1]->index < row2->cols[i2]->index )
7081  ++i1;
7082  else
7083  {
7084  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7085  ++i2;
7086  }
7087  }
7088  assert(i1 == row1->len || i2 == row2->nlpcols);
7089  }
7090 #endif
7091 
7092  /* The "easy" cases 1) and 2) */
7093  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7094  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7095  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7096  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7097  {
7098  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7099  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7100 
7101  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7102  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7103  */
7104  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7105  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7106  scalarprod = 0.0;
7107 
7108  /* calculate the scalar product */
7109  while( i1 >= 0 && i2 >= 0 )
7110  {
7111  assert(row1->cols[i1]->index == row1colsidx[i1]);
7112  assert(row2->cols[i2]->index == row2colsidx[i2]);
7113  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7114  if( row1colsidx[i1] < row2colsidx[i2] )
7115  --i2;
7116  else if( row1colsidx[i1] > row2colsidx[i2] )
7117  --i1;
7118  else
7119  {
7120  scalarprod += row1->vals[i1] * row2->vals[i2];
7121  --i1;
7122  --i2;
7123  }
7124  }
7125  }
7126  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7127  else
7128  {
7129  SCIP_Bool lpcols;
7130  int ilp1;
7131  int inlp1;
7132  int ilp2;
7133  int inlp2;
7134  int end1;
7135  int end2;
7136 
7137  scalarprod = 0;
7138  ilp1 = 0;
7139  ilp2 = 0;
7140 
7141  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7142  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7143  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7144 
7145  /* handle the case of four partitions (case 3) until one partition is finished;
7146  * cases 4a), 4b), and 5) will fail the while-condition
7147  */
7148  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7149  {
7150  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7151  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7152  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7153  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7154  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7155  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7156  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7157  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7158 
7159  /* rows have the same linked LP columns */
7160  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7161  {
7162  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7163  ++ilp1;
7164  ++ilp2;
7165  }
7166  /* LP column of row1 is the same as unlinked column of row2 */
7167  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7168  {
7169  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7170  ++ilp1;
7171  ++inlp2;
7172  }
7173  /* unlinked column of row1 is the same as LP column of row2 */
7174  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7175  {
7176  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7177  ++inlp1;
7178  ++ilp2;
7179  }
7180  /* two unlinked LP columns are the same */
7181  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7182  {
7183  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7184  ++inlp1;
7185  ++inlp2;
7186  }
7187  /* increase smallest counter */
7188  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7189  {
7190  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7191  {
7192  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7193  ++ilp1;
7194  else
7195  ++ilp2;
7196  }
7197  else
7198  {
7199  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7200  ++ilp1;
7201  else
7202  ++inlp2;
7203  }
7204  }
7205  else
7206  {
7207  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7208  {
7209  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7210  ++inlp1;
7211  else
7212  ++ilp2;
7213  }
7214  else
7215  {
7216  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7217  ++inlp1;
7218  else
7219  ++inlp2;
7220  }
7221  }
7222  }
7223 
7224  /* One partition was completely handled, we just have to handle the three remaining partitions:
7225  * the remaining partition of this row and the two partitions of the other row.
7226  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7227  */
7228  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7229  {
7230  int tmpilp;
7231  int tmpinlp;
7232 
7233  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7234 
7235  SCIPswapPointers((void**) &row1, (void**) &row2);
7236  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7237  tmpilp = ilp1;
7238  tmpinlp = inlp1;
7239  ilp1 = ilp2;
7240  inlp1 = inlp2;
7241  ilp2 = tmpilp;
7242  inlp2 = tmpinlp;
7243  }
7244 
7245  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7246  * -> this merges cases 4a) and 4b)
7247  */
7248  if( ilp1 == row1->nlpcols )
7249  {
7250  i1 = inlp1;
7251  end1 = row1->len;
7252  lpcols = FALSE;
7253  }
7254  else
7255  {
7256  assert(inlp1 == row1->len);
7257 
7258  i1 = ilp1;
7259  end1 = row1->nlpcols;
7260  lpcols = TRUE;
7261  }
7262 
7263  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7264  * case 5) will fail the while-condition
7265  */
7266  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7267  {
7268  assert(row1->cols[i1]->index == row1colsidx[i1]);
7269  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7270  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7271  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7272  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7273 
7274  /* current column in row 1 is the same as the current LP column in row 2 */
7275  if( row1colsidx[i1] == row2colsidx[ilp2] )
7276  {
7277  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7278  ++i1;
7279  ++ilp2;
7280  }
7281  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7282  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7283  {
7284  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7285  ++i1;
7286  ++inlp2;
7287  }
7288  /* increase smallest counter */
7289  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7290  {
7291  if( row1colsidx[i1] < row2colsidx[ilp2] )
7292  ++i1;
7293  else
7294  ++ilp2;
7295  }
7296  else
7297  {
7298  if( row1colsidx[i1] < row2colsidx[inlp2] )
7299  ++i1;
7300  else
7301  ++inlp2;
7302  }
7303  }
7304 
7305  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7306  * the two rows
7307  */
7308  if( i1 < end1 )
7309  {
7310  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7311  if( ilp2 == row2->nlpcols )
7312  {
7313  i2 = inlp2;
7314  end2 = row2->len;
7315  lpcols = FALSE;
7316  }
7317  else
7318  {
7319  assert(inlp2 == row2->len);
7320 
7321  i2 = ilp2;
7322  end2 = row2->nlpcols;
7323  }
7324 
7325  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7326  while( i1 < end1 && i2 < end2 )
7327  {
7328  assert(row1->cols[i1]->index == row1colsidx[i1]);
7329  assert(row2->cols[i2]->index == row2colsidx[i2]);
7330  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7331 
7332  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7333  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7334  {
7335  scalarprod += row1->vals[i1] * row2->vals[i2];
7336  ++i1;
7337  ++i2;
7338  }
7339  /* increase smallest counter */
7340  else if( row1colsidx[i1] < row2colsidx[i2] )
7341  ++i1;
7342  else
7343  ++i2;
7344  }
7345  }
7346  }
7347 
7348  return scalarprod;
7349 }
7350 
7351 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7352 static
7354  SCIP_ROW* row1, /**< first LP row */
7355  SCIP_ROW* row2 /**< second LP row */
7356  )
7357 {
7358  int prod;
7359  int* row1colsidx;
7360  int* row2colsidx;
7361  int i1;
7362  int i2;
7363 
7364  assert(row1 != NULL);
7365  assert(row2 != NULL);
7366 
7367  /* Sort the column indices of both rows.
7368  *
7369  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7370  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7371  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7372  * for both or one of the non-LP columns for both.
7373  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7374  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7375  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7376  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7377  *
7378  * We distinguish the following cases:
7379  *
7380  * 1) both rows have no unlinked columns
7381  * -> we just check the LP partitions
7382  *
7383  * 2) exactly one row is completely unlinked, the other one is completely linked
7384  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7385  * (thus all common LP columns are regarded)
7386  *
7387  * 3) we have unlinked and LP columns in both rows
7388  * -> we need to compare four partitions at once
7389  *
7390  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7391  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7392  * other row
7393  *
7394  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7395  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7396  *
7397  * 5) both rows are completely unlinked
7398  * -> we need to compare two partitions: both complete rows
7399  */
7400  SCIProwSort(row1);
7401  assert(row1->lpcolssorted);
7402  assert(row1->nonlpcolssorted);
7403  SCIProwSort(row2);
7404  assert(row2->lpcolssorted);
7405  assert(row2->nonlpcolssorted);
7406 
7407  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7408  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7409 
7410  row1colsidx = row1->cols_index;
7411  row2colsidx = row2->cols_index;
7412 
7413 #ifndef NDEBUG
7414  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7415  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7416  {
7417  i1 = 0;
7418  i2 = row2->nlpcols;
7419  while( i1 < row1->nlpcols && i2 < row2->len )
7420  {
7421  assert(row1->cols[i1] != row2->cols[i2]);
7422  if( row1->cols[i1]->index < row2->cols[i2]->index )
7423  ++i1;
7424  else
7425  {
7426  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7427  ++i2;
7428  }
7429  }
7430  assert(i1 == row1->nlpcols || i2 == row2->len);
7431 
7432  i1 = row1->nlpcols;
7433  i2 = 0;
7434  while( i1 < row1->len && i2 < row2->nlpcols )
7435  {
7436  assert(row1->cols[i1] != row2->cols[i2]);
7437  if( row1->cols[i1]->index < row2->cols[i2]->index )
7438  ++i1;
7439  else
7440  {
7441  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7442  ++i2;
7443  }
7444  }
7445  assert(i1 == row1->len || i2 == row2->nlpcols);
7446  }
7447 #endif
7448 
7449  /* The "easy" cases 1) and 2) */
7450  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7451  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7452  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7453  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7454  {
7455  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7456  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7457 
7458  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7459  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7460  */
7461  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7462  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7463  prod = 0;
7464 
7465  /* calculate the scalar product */
7466  while( i1 >= 0 && i2 >= 0 )
7467  {
7468  assert(row1->cols[i1]->index == row1colsidx[i1]);
7469  assert(row2->cols[i2]->index == row2colsidx[i2]);
7470  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7471  if( row1colsidx[i1] < row2colsidx[i2] )
7472  --i2;
7473  else if( row1colsidx[i1] > row2colsidx[i2] )
7474  --i1;
7475  else
7476  {
7477  ++prod;
7478  --i1;
7479  --i2;
7480  }
7481  }
7482  }
7483  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7484  else
7485  {
7486  SCIP_Bool lpcols;
7487  int ilp1;
7488  int inlp1;
7489  int ilp2;
7490  int inlp2;
7491  int end1;
7492  int end2;
7493 
7494  prod = 0;
7495  ilp1 = 0;
7496  ilp2 = 0;
7497 
7498  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7499  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7500  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7501 
7502  /* handle the case of four partitions (case 3) until one partition is finished;
7503  * cases 4a), 4b), and 5) will fail the while-condition
7504  */
7505  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7506  {
7507  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7508  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7509  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7510  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7511  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7512  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7513  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7514  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7515 
7516  /* rows have the same linked LP columns */
7517  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7518  {
7519  ++prod;
7520  ++ilp1;
7521  ++ilp2;
7522  }
7523  /* LP column of row1 is the same as unlinked column of row2 */
7524  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7525  {
7526  ++prod;
7527  ++ilp1;
7528  ++inlp2;
7529  }
7530  /* unlinked column of row1 is the same as LP column of row2 */
7531  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7532  {
7533  ++prod;
7534  ++inlp1;
7535  ++ilp2;
7536  }
7537  /* two unlinked LP columns are the same */
7538  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7539  {
7540  ++prod;
7541  ++inlp1;
7542  ++inlp2;
7543  }
7544  /* increase smallest counter */
7545  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7546  {
7547  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7548  {
7549  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7550  ++ilp1;
7551  else
7552  ++ilp2;
7553  }
7554  else
7555  {
7556  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7557  ++ilp1;
7558  else
7559  ++inlp2;
7560  }
7561  }
7562  else
7563  {
7564  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7565  {
7566  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7567  ++inlp1;
7568  else
7569  ++ilp2;
7570  }
7571  else
7572  {
7573  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7574  ++inlp1;
7575  else
7576  ++inlp2;
7577  }
7578  }
7579  }
7580 
7581  /* One partition was completely handled, we just have to handle the three remaining partitions:
7582  * the remaining partition of this row and the two partitions of the other row.
7583  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7584  */
7585  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7586  {
7587  int tmpilp;
7588  int tmpinlp;
7589 
7590  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7591 
7592  SCIPswapPointers((void**) &row1, (void**) &row2);
7593  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7594  tmpilp = ilp1;
7595  tmpinlp = inlp1;
7596  ilp1 = ilp2;
7597  inlp1 = inlp2;
7598  ilp2 = tmpilp;
7599  inlp2 = tmpinlp;
7600  }
7601 
7602  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7603  * -> this merges cases 4a) and 4b)
7604  */
7605  if( ilp1 == row1->nlpcols )
7606  {
7607  i1 = inlp1;
7608  end1 = row1->len;
7609  lpcols = FALSE;
7610  }
7611  else
7612  {
7613  assert(inlp1 == row1->len);
7614 
7615  i1 = ilp1;
7616  end1 = row1->nlpcols;
7617  lpcols = TRUE;
7618  }
7619 
7620  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7621  * case 5) will fail the while-condition
7622  */
7623  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7624  {
7625  assert(row1->cols[i1]->index == row1colsidx[i1]);
7626  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7627  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7628  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7629  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7630 
7631  /* current column in row 1 is the same as the current LP column in row 2 */
7632  if( row1colsidx[i1] == row2colsidx[ilp2] )
7633  {
7634  ++prod;
7635  ++i1;
7636  ++ilp2;
7637  }
7638  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7639  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7640  {
7641  ++prod;
7642  ++i1;
7643  ++inlp2;
7644  }
7645  /* increase smallest counter */
7646  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7647  {
7648  if( row1colsidx[i1] < row2colsidx[ilp2] )
7649  ++i1;
7650  else
7651  ++ilp2;
7652  }
7653  else
7654  {
7655  if( row1colsidx[i1] < row2colsidx[inlp2] )
7656  ++i1;
7657  else
7658  ++inlp2;
7659  }
7660  }
7661 
7662  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7663  * the two rows
7664  */
7665  if( i1 < end1 )
7666  {
7667  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7668  if( ilp2 == row2->nlpcols )
7669  {
7670  i2 = inlp2;
7671  end2 = row2->len;
7672  lpcols = FALSE;
7673  }
7674  else
7675  {
7676  assert(inlp2 == row2->len);
7677 
7678  i2 = ilp2;
7679  end2 = row2->nlpcols;
7680  }
7681 
7682  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7683  while( i1 < end1 && i2 < end2 )
7684  {
7685  assert(row1->cols[i1]->index == row1colsidx[i1]);
7686  assert(row2->cols[i2]->index == row2colsidx[i2]);
7687  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7688 
7689  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7690  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7691  {
7692  ++prod;
7693  ++i1;
7694  ++i2;
7695  }
7696  /* increase smallest counter */
7697  else if( row1colsidx[i1] < row2colsidx[i2] )
7698  ++i1;
7699  else
7700  ++i2;
7701  }
7702  }
7703  }
7704 
7705  return prod;
7706 }
7707 
7708 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7709  * p = |v*w|/(|v|*|w|);
7710  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7711  */
7713  SCIP_ROW* row1, /**< first LP row */
7714  SCIP_ROW* row2, /**< second LP row */
7715  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7716  )
7717 {
7718  SCIP_Real parallelism;
7719  SCIP_Real scalarprod;
7720 
7721  switch( orthofunc )
7722  {
7723  case 'e':
7724  scalarprod = SCIProwGetScalarProduct(row1, row2);
7725  if( scalarprod == 0.0 )
7726  {
7727  parallelism = 0.0;
7728  break;
7729  }
7730 
7731  if( SCIProwGetNorm(row1) == 0.0 )
7732  {
7733  /* In theory, this should not happen if the scalarproduct is not zero
7734  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7735  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7736  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7737  */
7738  int i;
7739  for( i = 0; i < row1->len; ++i )
7740  if( row1->cols[i]->lppos >= 0 )
7741  row1->sqrnorm += SQR(row1->vals[i]);
7742  assert(SCIProwGetNorm(row1) != 0.0);
7743  }
7744 
7745  if( SCIProwGetNorm(row2) == 0.0 )
7746  {
7747  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7748  int i;
7749  for( i = 0; i < row2->len; ++i )
7750  if( row2->cols[i]->lppos >= 0 )
7751  row2->sqrnorm += SQR(row2->vals[i]);
7752  assert(SCIProwGetNorm(row2) != 0.0);
7753  }
7754 
7755  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7756  break;
7757 
7758  case 'd':
7759  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7760  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7761  break;
7762 
7763  default:
7764  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7765  SCIPABORT();
7766  parallelism = 0.0; /*lint !e527*/
7767  }
7768 
7769  return parallelism;
7770 }
7771 
7772 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7773  * o = 1 - |v*w|/(|v|*|w|);
7774  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7775  */
7777  SCIP_ROW* row1, /**< first LP row */
7778  SCIP_ROW* row2, /**< second LP row */
7779  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7780  )
7781 {
7782  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7783 }
7784 
7785 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7786  * function, if the value is 0, it is orthogonal to the objective function
7787  */
7789  SCIP_ROW* row, /**< LP row */
7790  SCIP_SET* set, /**< global SCIP settings */
7791  SCIP_LP* lp /**< current LP data */
7792  )
7793 {
7794  SCIP_Real prod;
7795  SCIP_Real parallelism;
7796 
7797  assert(row != NULL);
7798  assert(lp != NULL);
7799 
7800  if( lp->objsqrnormunreliable )
7801  SCIPlpRecalculateObjSqrNorm(set, lp);
7802 
7803  assert(!lp->objsqrnormunreliable);
7804  assert(lp->objsqrnorm >= 0.0);
7805 
7806  checkRowSqrnorm(row);
7807  checkRowObjprod(row);
7808 
7809  prod = row->sqrnorm * lp->objsqrnorm;
7810 
7811  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7812  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7813  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7814  parallelism = MIN(parallelism, 1.0);
7815  parallelism = MAX(parallelism, 0.0);
7816 
7817  return parallelism;
7818 }
7819 
7820 /** includes event handler with given data in row's event filter */
7822  SCIP_ROW* row, /**< row */
7823  BMS_BLKMEM* blkmem, /**< block memory */
7824  SCIP_SET* set, /**< global SCIP settings */
7825  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7826  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7827  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7828  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7829  )
7830 {
7831  assert(row != NULL);
7832  assert(row->eventfilter != NULL);
7833  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7834  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7835 
7836  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7837  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7838 
7839  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7840 
7841  return SCIP_OKAY;
7842 }
7843 
7844 /** deletes event handler with given data from row's event filter */
7846  SCIP_ROW* row, /**< row */
7847  BMS_BLKMEM* blkmem, /**< block memory */
7848  SCIP_SET* set, /**< global SCIP settings */
7849  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7850  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7851  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7852  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7853  )
7854 {
7855  assert(row != NULL);
7856  assert(row->eventfilter != NULL);
7857 
7858  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7859 
7860  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7861 
7862  return SCIP_OKAY;
7863 }
7864 
7865 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7867  SCIP_ROW* row, /**< LP row */
7868  SCIP_STAT* stat /**< problem statistics */
7869  )
7870 {
7871  assert(row != NULL);
7872  assert(stat != NULL);
7873  assert(stat->nnodes > 0);
7874 
7875  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7876  row->obsoletenode = stat->nnodes;
7877 }
7878 
7879 /*
7880  * LP solver data update
7881  */
7882 
7883 /** resets column data to represent a column not in the LP solver */
7884 static
7886  SCIP_COL* col /**< column to be marked deleted */
7887  )
7888 {
7889  assert(col != NULL);
7890 
7891  col->lpipos = -1;
7892  col->primsol = 0.0;
7893  col->redcost = SCIP_INVALID;
7894  col->farkascoef = SCIP_INVALID;
7895  col->sbdown = SCIP_INVALID;
7896  col->sbup = SCIP_INVALID;
7897  col->sbdownvalid = FALSE;
7898  col->sbupvalid = FALSE;
7899  col->validredcostlp = -1;
7900  col->validfarkaslp = -1;
7901  col->sbitlim = -1;
7902  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7903 }
7904 
7905 /** applies all cached column removals to the LP solver */
7906 static
7908  SCIP_LP* lp /**< current LP data */
7909  )
7910 {
7911  assert(lp != NULL);
7912  assert(lp->lpifirstchgcol <= lp->nlpicols);
7913  assert(lp->lpifirstchgcol <= lp->ncols);
7914 
7915  /* find the first column to change */
7916  while( lp->lpifirstchgcol < lp->nlpicols
7917  && lp->lpifirstchgcol < lp->ncols
7918  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7919  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7920  {
7921  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7922  lp->lpifirstchgcol++;
7923  }
7924 
7925  /* shrink LP to the part which didn't change */
7926  if( lp->lpifirstchgcol < lp->nlpicols )
7927  {
7928  int i;
7929 
7930  assert(!lp->diving);
7931  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7932  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7933  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7934  {
7935  markColDeleted(lp->lpicols[i]);
7936  }
7937  lp->nlpicols = lp->lpifirstchgcol;
7938  lp->flushdeletedcols = TRUE;
7939  lp->updateintegrality = TRUE;
7940 
7941  /* mark the LP unsolved */
7942  lp->solved = FALSE;
7943  lp->primalfeasible = FALSE;
7944  lp->primalchecked = FALSE;
7945  lp->lpobjval = SCIP_INVALID;
7947  }
7948  assert(lp->nlpicols == lp->lpifirstchgcol);
7949 
7950  return SCIP_OKAY;
7951 }
7952 
7953 /** computes for the given column the lower and upper bound that should be flushed into the LP
7954  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7955  * the bounds are explicitly added to the LP in any case
7956  */
7957 static
7959  SCIP_LP* lp, /**< current LP data */
7960  SCIP_SET* set, /**< global SCIP settings */
7961  SCIP_COL* col, /**< column to compute bounds for */
7962  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7963  SCIP_Real* lb, /**< pointer to store the new lower bound */
7964  SCIP_Real* ub /**< pointer to store the new upper bound */
7965  )
7966 {
7967  assert(lp != NULL);
7968  assert(set != NULL);
7969  assert(col != NULL);
7970  assert(lb != NULL);
7971  assert(ub != NULL);
7972 
7973  /* get the correct new lower bound:
7974  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7975  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7976  */
7977  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7978  (*lb) = -lpiinf;
7979  else
7980  (*lb) = col->lb;
7981  /* get the correct new upper bound:
7982  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7983  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7984  */
7985  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7986  (*ub) = lpiinf;
7987  else
7988  (*ub) = col->ub;
7989 }
7990 
7991 /** applies all cached column additions to the LP solver */
7992 static
7994  SCIP_LP* lp, /**< current LP data */
7995  BMS_BLKMEM* blkmem, /**< block memory */
7996  SCIP_SET* set, /**< global SCIP settings */
7997  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7998  )
7999 {
8000  SCIP_Real* obj;
8001  SCIP_Real* lb;
8002  SCIP_Real* ub;
8003  int* beg;
8004  int* ind;
8005  SCIP_Real* val;
8006  char** name;
8007  SCIP_COL* col;
8008  SCIP_Real lpiinf;
8009  int c;
8010  int pos;
8011  int nnonz;
8012  int naddcols;
8013  int naddcoefs;
8014  int i;
8015  int lpipos;
8016 
8017  assert(lp != NULL);
8018  assert(lp->lpifirstchgcol == lp->nlpicols);
8019  assert(blkmem != NULL);
8020  assert(set != NULL);
8021 
8022  /* if there are no columns to add, we are ready */
8023  if( lp->ncols == lp->nlpicols )
8024  return SCIP_OKAY;
8025 
8026  /* add the additional columns */
8027  assert(!lp->diving);
8028  assert(lp->ncols > lp->nlpicols);
8029  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8030 
8031  /* get the solver's infinity value */
8032  lpiinf = SCIPlpiInfinity(lp->lpi);
8033 
8034  /* count the (maximal) number of added coefficients, calculate the number of added columns */
8035  naddcols = lp->ncols - lp->nlpicols;
8036  naddcoefs = 0;
8037  for( c = lp->nlpicols; c < lp->ncols; ++c )
8038  naddcoefs += lp->cols[c]->len;
8039  assert(naddcols > 0);
8040 
8041  /* get temporary memory for changes */
8042  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8043  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8044  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8045  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8046  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8047  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8048  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8049 
8050  /* fill temporary memory with column data */
8051  nnonz = 0;
8052  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8053  {
8054  col = lp->cols[c];
8055  assert(col != NULL);
8056  assert(col->var != NULL);
8057  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8058  assert(SCIPvarGetCol(col->var) == col);
8059  assert(col->lppos == c);
8060  assert(nnonz + col->nlprows <= naddcoefs);
8061 
8062  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8063  debugColPrint(set, col);
8064 
8065  /* Because the column becomes a member of the LP solver, it now can take values
8066  * different from zero. That means, we have to include the column in the corresponding
8067  * row vectors.
8068  */
8069  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8070 
8071  lp->lpicols[c] = col;
8072  col->lpipos = c;
8073  col->primsol = SCIP_INVALID;
8074  col->redcost = SCIP_INVALID;
8075  col->farkascoef = SCIP_INVALID;
8076  col->sbdown = SCIP_INVALID;
8077  col->sbup = SCIP_INVALID;
8078  col->sbdownvalid = FALSE;
8079  col->sbupvalid = FALSE;
8080  col->validredcostlp = -1;
8081  col->validfarkaslp = -1;
8082  col->sbitlim = -1;
8083  col->objchanged = FALSE;
8084  col->lbchanged = FALSE;
8085  col->ubchanged = FALSE;
8086  col->coefchanged = FALSE;
8087  obj[pos] = col->obj;
8088 
8089  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8090  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8091 
8092  beg[pos] = nnonz;
8093  name[pos] = (char*)SCIPvarGetName(col->var);
8094 
8095  col->flushedobj = obj[pos];
8096  col->flushedlb = lb[pos];
8097  col->flushedub = ub[pos];
8098 
8099  for( i = 0; i < col->nlprows; ++i )
8100  {
8101  assert(col->rows[i] != NULL);
8102  lpipos = col->rows[i]->lpipos;
8103  if( lpipos >= 0 )
8104  {
8105  assert(lpipos < lp->nrows);
8106  assert(nnonz < naddcoefs);
8107  ind[nnonz] = lpipos;
8108  val[nnonz] = col->vals[i];
8109  nnonz++;
8110  }
8111  }
8112 #ifndef NDEBUG
8113  for( i = col->nlprows; i < col->len; ++i )
8114  {
8115  assert(col->rows[i] != NULL);
8116  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8117  }
8118 #endif
8119  }
8120 
8121  /* call LP interface */
8122  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8123  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8124  lp->nlpicols = lp->ncols;
8125  lp->lpifirstchgcol = lp->nlpicols;
8126 
8127  /* free temporary memory */
8128  SCIPsetFreeBufferArray(set, &name);
8129  SCIPsetFreeBufferArray(set, &val);
8130  SCIPsetFreeBufferArray(set, &ind);
8131  SCIPsetFreeBufferArray(set, &beg);
8132  SCIPsetFreeBufferArray(set, &ub);
8133  SCIPsetFreeBufferArray(set, &lb);
8134  SCIPsetFreeBufferArray(set, &obj);
8135 
8136  lp->flushaddedcols = TRUE;
8137  lp->updateintegrality = TRUE;
8138 
8139  /* mark the LP unsolved */
8140  lp->solved = FALSE;
8141  lp->dualfeasible = FALSE;
8142  lp->dualchecked = FALSE;
8143  lp->lpobjval = SCIP_INVALID;
8145 
8146  return SCIP_OKAY;
8147 }
8148 
8149 /** resets row data to represent a row not in the LP solver */
8150 static
8152  SCIP_ROW* row /**< row to be marked deleted */
8153  )
8154 {
8155  assert(row != NULL);
8156 
8157  row->lpipos = -1;
8158  row->dualsol = 0.0;
8159  row->activity = SCIP_INVALID;
8160  row->dualfarkas = 0.0;
8161  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8162  row->validactivitylp = -1;
8163 }
8164 
8165 /** applies all cached row removals to the LP solver */
8166 static
8168  SCIP_LP* lp, /**< current LP data */
8169  BMS_BLKMEM* blkmem, /**< block memory */
8170  SCIP_SET* set /**< global SCIP settings */
8171  )
8172 {
8173  assert(lp != NULL);
8174  assert(lp->lpifirstchgrow <= lp->nlpirows);
8175  assert(lp->lpifirstchgrow <= lp->nrows);
8176 
8177  /* find the first row to change */
8178  while( lp->lpifirstchgrow < lp->nlpirows
8179  && lp->lpifirstchgrow < lp->nrows
8180  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8181  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8182  {
8183  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8184  lp->lpifirstchgrow++;
8185  }
8186 
8187  /* shrink LP to the part which didn't change */
8188  if( lp->lpifirstchgrow < lp->nlpirows )
8189  {
8190  int i;
8191 
8192  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8193  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8194  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8195  {
8196  markRowDeleted(lp->lpirows[i]);
8197  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8198  }
8199  lp->nlpirows = lp->lpifirstchgrow;
8200  lp->flushdeletedrows = TRUE;
8201 
8202  /* mark the LP unsolved */
8203  lp->solved = FALSE;
8204  lp->dualfeasible = FALSE;
8205  lp->dualchecked = FALSE;
8206  lp->lpobjval = SCIP_INVALID;
8208  }
8209  assert(lp->nlpirows == lp->lpifirstchgrow);
8210 
8211  return SCIP_OKAY;
8212 }
8213 
8214 /** applies all cached row additions and removals to the LP solver */
8215 static
8217  SCIP_LP* lp, /**< current LP data */
8218  BMS_BLKMEM* blkmem, /**< block memory */
8219  SCIP_SET* set, /**< global SCIP settings */
8220  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8221  )
8222 {
8223  SCIP_Real* lhs;
8224  SCIP_Real* rhs;
8225  int* beg;
8226  int* ind;
8227  SCIP_Real* val;
8228  char** name;
8229  SCIP_ROW* row;
8230  SCIP_Real lpiinf;
8231  int r;
8232  int pos;
8233  int nnonz;
8234  int naddrows;
8235  int naddcoefs;
8236  int i;
8237  int lpipos;
8238 
8239  assert(lp != NULL);
8240  assert(lp->lpifirstchgrow == lp->nlpirows);
8241  assert(blkmem != NULL);
8242 
8243  /* if there are no rows to add, we are ready */
8244  if( lp->nrows == lp->nlpirows )
8245  return SCIP_OKAY;
8246 
8247  /* add the additional rows */
8248  assert(lp->nrows > lp->nlpirows);
8249  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8250 
8251  /* get the solver's infinity value */
8252  lpiinf = SCIPlpiInfinity(lp->lpi);
8253 
8254  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8255  naddrows = lp->nrows - lp->nlpirows;
8256  naddcoefs = 0;
8257  for( r = lp->nlpirows; r < lp->nrows; ++r )
8258  naddcoefs += lp->rows[r]->len;
8259  assert(naddrows > 0);
8260 
8261  /* get temporary memory for changes */
8262  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8263  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8264  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8265  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8266  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8267  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8268 
8269  /* fill temporary memory with row data */
8270  nnonz = 0;
8271  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8272  {
8273  row = lp->rows[r];
8274  assert(row != NULL);
8275  assert(row->lppos == r);
8276  assert(nnonz + row->nlpcols <= naddcoefs);
8277 
8278  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8279  debugRowPrint(set, row);
8280 
8281  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8282  * different from zero. That means, we have to include the row in the corresponding
8283  * column vectors.
8284  */
8285  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8286 
8287  SCIProwCapture(row);
8288  lp->lpirows[r] = row;
8289  row->lpipos = r;
8290  row->dualsol = SCIP_INVALID;
8291  row->activity = SCIP_INVALID;
8292  row->dualfarkas = SCIP_INVALID;
8293  row->validactivitylp = -1;
8294  row->lhschanged = FALSE;
8295  row->rhschanged = FALSE;
8296  row->coefchanged = FALSE;
8297  if( SCIPsetIsInfinity(set, -row->lhs) )
8298  lhs[pos] = -lpiinf;
8299  else
8300  lhs[pos] = row->lhs - row->constant;
8301  if( SCIPsetIsInfinity(set, row->rhs) )
8302  rhs[pos] = lpiinf;
8303  else
8304  rhs[pos] = row->rhs - row->constant;
8305  beg[pos] = nnonz;
8306  name[pos] = row->name;
8307 
8308  row->flushedlhs = lhs[pos];
8309  row->flushedrhs = rhs[pos];
8310 
8311  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8312  for( i = 0; i < row->nlpcols; ++i )
8313  {
8314  assert(row->cols[i] != NULL);
8315  lpipos = row->cols[i]->lpipos;
8316  if( lpipos >= 0 )
8317  {
8318  assert(lpipos < lp->ncols);
8319  assert(nnonz < naddcoefs);
8320  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8321  ind[nnonz] = lpipos;
8322  val[nnonz] = row->vals[i];
8323  nnonz++;
8324  }
8325  }
8326  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8327 #ifndef NDEBUG
8328  for( i = row->nlpcols; i < row->len; ++i )
8329  {
8330  assert(row->cols[i] != NULL);
8331  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8332  }
8333 #endif
8334  }
8335 
8336  /* call LP interface */
8337  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8338  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8339  lp->nlpirows = lp->nrows;
8340  lp->lpifirstchgrow = lp->nlpirows;
8341 
8342  /* free temporary memory */
8343  SCIPsetFreeBufferArray(set, &name);
8344  SCIPsetFreeBufferArray(set, &val);
8345  SCIPsetFreeBufferArray(set, &ind);
8346  SCIPsetFreeBufferArray(set, &beg);
8347  SCIPsetFreeBufferArray(set, &rhs);
8348  SCIPsetFreeBufferArray(set, &lhs);
8349 
8350  lp->flushaddedrows = TRUE;
8351 
8352  /* mark the LP unsolved */
8353  lp->solved = FALSE;
8354  lp->primalfeasible = FALSE;
8355  lp->primalchecked = FALSE;
8356  lp->lpobjval = SCIP_INVALID;
8358 
8359  return SCIP_OKAY;
8360 }
8361 
8362 /** applies all cached column bound and objective changes to the LP */
8363 static
8365  SCIP_LP* lp, /**< current LP data */
8366  SCIP_SET* set /**< global SCIP settings */
8367  )
8368 {
8369 #ifndef NDEBUG
8370  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8371 #endif
8372  SCIP_COL* col;
8373  int* objind;
8374  int* bdind;
8375  SCIP_Real* obj;
8376  SCIP_Real* lb;
8377  SCIP_Real* ub;
8378  SCIP_Real lpiinf;
8379  int nobjchg;
8380  int nbdchg;
8381  int i;
8382 
8383  assert(lp != NULL);
8384 
8385  if( lp->nchgcols == 0 )
8386  return SCIP_OKAY;
8387 
8388  /* get the solver's infinity value */
8389  lpiinf = SCIPlpiInfinity(lp->lpi);
8390 
8391  /* get temporary memory for changes */
8392  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8393  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8394  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8395  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8396  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8397 
8398  /* collect all cached bound and objective changes */
8399  nobjchg = 0;
8400  nbdchg = 0;
8401  for( i = 0; i < lp->nchgcols; ++i )
8402  {
8403  col = lp->chgcols[i];
8404  assert(col != NULL);
8405  assert(col->var != NULL);
8406  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8407  assert(SCIPvarGetCol(col->var) == col);
8408 
8409  if( col->lpipos >= 0 )
8410  {
8411 #ifndef NDEBUG
8412  /* do not check consistency of data with LPI in case of LPI=none */
8413  if( !lpinone )
8414  {
8415  SCIP_Real lpiobj;
8416  SCIP_Real lpilb;
8417  SCIP_Real lpiub;
8418 
8419  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8420  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8421  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8422  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8423  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8424  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8425  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8426  }
8427 #endif
8428 
8429  if( col->objchanged )
8430  {
8431  SCIP_Real newobj;
8432 
8433  newobj = col->obj;
8434  if( col->flushedobj != newobj ) /*lint !e777*/
8435  {
8436  assert(nobjchg < lp->ncols);
8437  objind[nobjchg] = col->lpipos;
8438  obj[nobjchg] = newobj;
8439  nobjchg++;
8440  col->flushedobj = newobj;
8441  }
8442  col->objchanged = FALSE;
8443  }
8444 
8445  if( col->lbchanged || col->ubchanged )
8446  {
8447  SCIP_Real newlb;
8448  SCIP_Real newub;
8449 
8450  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8451  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8452 
8453  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8454  {
8455  assert(nbdchg < lp->ncols);
8456  bdind[nbdchg] = col->lpipos;
8457  lb[nbdchg] = newlb;
8458  ub[nbdchg] = newub;
8459  nbdchg++;
8460  col->flushedlb = newlb;
8461  col->flushedub = newub;
8462  }
8463  col->lbchanged = FALSE;
8464  col->ubchanged = FALSE;
8465  }
8466  }
8467  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8468  }
8469 
8470  /* change objective values in LP */
8471  if( nobjchg > 0 )
8472  {
8473  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8474  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8475 
8476  /* mark the LP unsolved */
8477  lp->solved = FALSE;
8478  lp->dualfeasible = FALSE;
8479  lp->dualchecked = FALSE;
8480  lp->lpobjval = SCIP_INVALID;
8482  }
8483 
8484  /* change bounds in LP */
8485  if( nbdchg > 0 )
8486  {
8487  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8488  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8489 
8490  /* mark the LP unsolved */
8491  lp->solved = FALSE;
8492  lp->primalfeasible = FALSE;
8493  lp->primalchecked = FALSE;
8494  lp->lpobjval = SCIP_INVALID;
8496  }
8497 
8498  lp->nchgcols = 0;
8499 
8500  /* free temporary memory */
8501  SCIPsetFreeBufferArray(set, &ub);
8502  SCIPsetFreeBufferArray(set, &lb);
8503  SCIPsetFreeBufferArray(set, &bdind);
8504  SCIPsetFreeBufferArray(set, &obj);
8505  SCIPsetFreeBufferArray(set, &objind);
8506 
8507  return SCIP_OKAY;
8508 }
8509 
8510 /** applies all cached row side changes to the LP */
8511 static
8513  SCIP_LP* lp, /**< current LP data */
8514  SCIP_SET* set /**< global SCIP settings */
8515  )
8516 {
8517 #ifndef NDEBUG
8518  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8519 #endif
8520  SCIP_ROW* row;
8521  int* ind;
8522  SCIP_Real* lhs;
8523  SCIP_Real* rhs;
8524  SCIP_Real lpiinf;
8525  int i;
8526  int nchg;
8527 
8528  assert(lp != NULL);
8529 
8530  if( lp->nchgrows == 0 )
8531  return SCIP_OKAY;
8532 
8533  /* get the solver's infinity value */
8534  lpiinf = SCIPlpiInfinity(lp->lpi);
8535 
8536  /* get temporary memory for changes */
8537  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8538  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8539  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8540 
8541  /* collect all cached left and right hand side changes */
8542  nchg = 0;
8543  for( i = 0; i < lp->nchgrows; ++i )
8544  {
8545  row = lp->chgrows[i];
8546  assert(row != NULL);
8547 
8548  if( row->lpipos >= 0 )
8549  {
8550 #ifndef NDEBUG
8551  /* do not check consistency of data with LPI in case of LPI=none */
8552  if( !lpinone )
8553  {
8554  SCIP_Real lpilhs;
8555  SCIP_Real lpirhs;
8556 
8557  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8558  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8559  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8560  }
8561 #endif
8562  if( row->lhschanged || row->rhschanged )
8563  {
8564  SCIP_Real newlhs;
8565  SCIP_Real newrhs;
8566 
8567  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8568  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8569  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8570  {
8571  assert(nchg < lp->nrows);
8572  ind[nchg] = row->lpipos;
8573  lhs[nchg] = newlhs;
8574  rhs[nchg] = newrhs;
8575  nchg++;
8576  row->flushedlhs = newlhs;
8577  row->flushedrhs = newrhs;
8578  }
8579  row->lhschanged = FALSE;
8580  row->rhschanged = FALSE;
8581  }
8582  }
8583  }
8584 
8585  /* change left and right hand sides in LP */
8586  if( nchg > 0 )
8587  {
8588  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8589  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8590 
8591  /* mark the LP unsolved */
8592  lp->solved = FALSE;
8593  lp->primalfeasible = FALSE;
8594  lp->primalchecked = FALSE;
8595  lp->lpobjval = SCIP_INVALID;
8597  }
8598 
8599  lp->nchgrows = 0;
8600 
8601  /* free temporary memory */
8602  SCIPsetFreeBufferArray(set, &rhs);
8603  SCIPsetFreeBufferArray(set, &lhs);
8604  SCIPsetFreeBufferArray(set, &ind);
8605 
8606  return SCIP_OKAY;
8607 }
8608 
8609 /** copy integrality information to the LP */
8610 static
8612  SCIP_LP* lp, /**< current LP data */
8613  SCIP_SET* set /**< global SCIP settings */
8614  )
8615 {
8616  int i;
8617  int nintegers;
8618  int* integerInfo;
8619  SCIP_VAR* var;
8620 
8621  assert(lp != NULL);
8622 
8623  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8624 
8625  /* count total number of integralities */
8626  nintegers = 0;
8627 
8628  for( i = 0; i < lp->ncols; ++i )
8629  {
8630  var = SCIPcolGetVar(lp->cols[i]);
8631  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8632  {
8633  integerInfo[i] = 1;
8634  ++nintegers;
8635  }
8636  else
8637  integerInfo[i] = 0;
8638  }
8639 
8640  /* only pass integrality information if integer variables are present */
8641  if( nintegers > 0 )
8642  {
8643  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8644  }
8645  else
8646  {
8648  }
8649 
8650  SCIPsetFreeBufferArray(set, &integerInfo);
8651 
8652  /* mark integralities to be updated */
8653  lp->updateintegrality = FALSE;
8654 
8655  return SCIP_OKAY;
8656 }
8657 
8658 /** applies all cached changes to the LP solver */
8660  SCIP_LP* lp, /**< current LP data */
8661  BMS_BLKMEM* blkmem, /**< block memory */
8662  SCIP_SET* set, /**< global SCIP settings */
8663  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8664  )
8665 {
8666  assert(lp != NULL);
8667  assert(blkmem != NULL);
8668 
8669  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",
8670  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8671 
8672  if( !lp->flushed )
8673  {
8674  lp->flushdeletedcols = FALSE;
8675  lp->flushaddedcols = FALSE;
8676  lp->flushdeletedrows = FALSE;
8677  lp->flushaddedrows = FALSE;
8678 
8679  SCIP_CALL( lpFlushDelCols(lp) );
8680  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8681  SCIP_CALL( lpFlushChgCols(lp, set) );
8682  SCIP_CALL( lpFlushChgRows(lp, set) );
8683  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8684  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8685 
8686  lp->flushed = TRUE;
8687 
8688  checkLinks(lp);
8689  }
8690 
8691  /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8692  * we want to re-optimize the LP even if nothing else has changed */
8693  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 && ! lpCutoffDisabled(set) ) /*lint !e777*/
8694  {
8695  lp->solved = FALSE;
8697  }
8698 
8699  assert(lp->nlpicols == lp->ncols);
8700  assert(lp->lpifirstchgcol == lp->nlpicols);
8701  assert(lp->nlpirows == lp->nrows);
8702  assert(lp->lpifirstchgrow == lp->nlpirows);
8703  assert(lp->nchgcols == 0);
8704  assert(lp->nchgrows == 0);
8705 #ifndef NDEBUG
8706  {
8707  int ncols;
8708  int nrows;
8709 
8710  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8711  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8712  assert(ncols == lp->ncols);
8713  assert(nrows == lp->nrows);
8714  }
8715 #endif
8716 
8717  return SCIP_OKAY;
8718 }
8719 
8720 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8722  SCIP_LP* lp, /**< current LP data */
8723  SCIP_SET* set /**< global SCIP settings */
8724  )
8725 {
8726 #ifndef NDEBUG
8727  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8728 #endif
8729  int i;
8730 
8731  assert(lp != NULL);
8732 
8733 #ifndef NDEBUG
8734  /* check, if there are really no column or row deletions or coefficient changes left */
8735  while( lp->lpifirstchgcol < lp->nlpicols
8736  && lp->lpifirstchgcol < lp->ncols
8737  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8738  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8739  {
8740  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8741  lp->lpifirstchgcol++;
8742  }
8743  assert(lp->nlpicols == lp->lpifirstchgcol);
8744 
8745  while( lp->lpifirstchgrow < lp->nlpirows
8746  && lp->lpifirstchgrow < lp->nrows
8747  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8748  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8749  {
8750  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8751  lp->lpifirstchgrow++;
8752  }
8753  assert(lp->nlpirows == lp->lpifirstchgrow);
8754 #endif
8755 
8756  lp->lpifirstchgcol = lp->nlpicols;
8757  lp->lpifirstchgrow = lp->nlpirows;
8758 
8759  /* check, if there are really no column or row additions left */
8760  assert(lp->ncols == lp->nlpicols);
8761  assert(lp->nrows == lp->nlpirows);
8762 
8763  /* mark the changed columns to be unchanged, and check, if this is really correct */
8764  for( i = 0; i < lp->nchgcols; ++i )
8765  {
8766  SCIP_COL* col;
8767 
8768  col = lp->chgcols[i];
8769  assert(col != NULL);
8770  assert(col->var != NULL);
8771  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8772  assert(SCIPvarGetCol(col->var) == col);
8773 
8774  if( col->lpipos >= 0 )
8775  {
8776 #ifndef NDEBUG
8777  /* do not check consistency of data with LPI in case of LPI=none */
8778  if( !lpinone )
8779  {
8780  SCIP_Real lpiobj;
8781  SCIP_Real lpilb;
8782  SCIP_Real lpiub;
8783 
8784  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8785  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8786  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8787  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8788  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8789  assert(col->flushedobj == col->obj); /*lint !e777*/
8790  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8791  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8792  }
8793 #endif
8794  col->objchanged = FALSE;
8795  col->lbchanged = FALSE;
8796  col->ubchanged = FALSE;
8797  }
8798  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8799  }
8800  lp->nchgcols = 0;
8801 
8802  /* mark the changed rows to be unchanged, and check, if this is really correct */
8803  for( i = 0; i < lp->nchgrows; ++i )
8804  {
8805  SCIP_ROW* row;
8806 
8807  row = lp->chgrows[i];
8808  assert(row != NULL);
8809 
8810  if( row->lpipos >= 0 )
8811  {
8812 #ifndef NDEBUG
8813  /* do not check consistency of data with LPI in case of LPI=none */
8814  if( !lpinone )
8815  {
8816  SCIP_Real lpilhs;
8817  SCIP_Real lpirhs;
8818 
8819  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8820  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8821  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8822  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8823  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8824  }
8825 #endif
8826  row->lhschanged = FALSE;
8827  row->rhschanged = FALSE;
8828  }
8829  }
8830  lp->nchgrows = 0;
8831 
8832  /* mark the LP to be flushed */
8833  lp->flushed = TRUE;
8834 
8835  checkLinks(lp);
8836 
8837  return SCIP_OKAY;
8838 }
8839 
8840 
8841 
8842 
8843 /*
8844  * LP methods
8845  */
8846 
8847 /** updates link data after addition of column */
8848 static
8850  SCIP_COL* col, /**< LP column */
8851  SCIP_SET* set /**< global SCIP settings */
8852  )
8853 {
8854  SCIP_ROW* row;
8855  int i;
8856  int pos;
8857 
8858  assert(col != NULL);
8859  assert(col->lppos >= 0);
8860 
8861  /* update column arrays of all linked rows */
8862  for( i = 0; i < col->len; ++i )
8863  {
8864  pos = col->linkpos[i];
8865  if( pos >= 0 )
8866  {
8867  row = col->rows[i];
8868  assert(row != NULL);
8869  assert(row->linkpos[pos] == i);
8870  assert(row->cols[pos] == col);
8871  assert(row->nlpcols <= pos && pos < row->len);
8872 
8873  row->nlpcols++;
8874  rowSwapCoefs(row, pos, row->nlpcols-1);
8875  assert(row->cols[row->nlpcols-1] == col);
8876 
8877  /* if no swap was necessary, mark lpcols to be unsorted */
8878  if( pos == row->nlpcols-1 )
8879  row->lpcolssorted = FALSE;
8880 
8881  /* update norms */
8882  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8883  }
8884  }
8885 }
8886 
8887 /** updates link data after addition of row */
8888 static
8890  SCIP_ROW* row /**< LP row */
8891  )
8892 {
8893  SCIP_COL* col;
8894  int i;
8895  int pos;
8896 
8897  assert(row != NULL);
8898  assert(row->lppos >= 0);
8899 
8900  /* update row arrays of all linked columns */
8901  for( i = 0; i < row->len; ++i )
8902  {
8903  pos = row->linkpos[i];
8904  if( pos >= 0 )
8905  {
8906  col = row->cols[i];
8907  assert(col != NULL);
8908  assert(col->linkpos[pos] == i);
8909  assert(col->rows[pos] == row);
8910  assert(col->nlprows <= pos && pos < col->len);
8911 
8912  col->nlprows++;
8913  colSwapCoefs(col, pos, col->nlprows-1);
8914 
8915  /* if no swap was necessary, mark lprows to be unsorted */
8916  if( pos == col->nlprows-1 )
8917  col->lprowssorted = FALSE;
8918  }
8919  }
8920 }
8921 
8922 /** updates link data after removal of column */
8923 static
8925  SCIP_COL* col, /**< LP column */
8926  SCIP_SET* set /**< global SCIP settings */
8927  )
8928 {
8929  SCIP_ROW* row;
8930  int i;
8931  int pos;
8932 
8933  assert(col != NULL);
8934  assert(col->lppos == -1);
8935 
8936  /* update column arrays of all linked rows */
8937  for( i = 0; i < col->len; ++i )
8938  {
8939  pos = col->linkpos[i];
8940  if( pos >= 0 )
8941  {
8942  row = col->rows[i];
8943  assert(row != NULL);
8944  assert(row->linkpos[pos] == i);
8945  assert(row->cols[pos] == col);
8946  assert(0 <= pos && pos < row->nlpcols);
8947 
8948  /* update norms */
8949  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8950 
8951  row->nlpcols--;
8952  rowSwapCoefs(row, pos, row->nlpcols);
8953 
8954  /* if no swap was necessary, mark nonlpcols to be unsorted */
8955  if( pos == row->nlpcols )
8956  row->nonlpcolssorted = FALSE;
8957  }
8958  }
8959 }
8960 
8961 /** updates link data after removal of row */
8962 static
8964  SCIP_ROW* row /**< LP row */
8965  )
8966 {
8967  SCIP_COL* col;
8968  int i;
8969  int pos;
8970 
8971  assert(row != NULL);
8972  assert(row->lppos == -1);
8973 
8974  /* update row arrays of all linked columns */
8975  for( i = 0; i < row->len; ++i )
8976  {
8977  pos = row->linkpos[i];
8978  if( pos >= 0 )
8979  {
8980  col = row->cols[i];
8981  assert(col != NULL);
8982  assert(0 <= pos && pos < col->nlprows);
8983  assert(col->linkpos[pos] == i);
8984  assert(col->rows[pos] == row);
8985 
8986  col->nlprows--;
8987  colSwapCoefs(col, pos, col->nlprows);
8988 
8989  /* if no swap was necessary, mark lprows to be unsorted */
8990  if( pos == col->nlprows )
8991  col->nonlprowssorted = FALSE;
8992  }
8993  }
8994 }
8995 
8996 static
8998  SCIP_LP* lp, /**< LP data object */
8999  int initsize /**< initial size of the arrays */
9000  )
9001 {
9002  assert(lp != NULL);
9003  assert(lp->divechgsides == NULL);
9004  assert(lp->divechgsidetypes == NULL);
9005  assert(lp->divechgrows == NULL);
9006  assert(lp->ndivechgsides == 0);
9007  assert(lp->divechgsidessize == 0);
9008  assert(initsize > 0);
9009 
9010  lp->divechgsidessize = initsize;
9014 
9015  return SCIP_OKAY;
9016 }
9017 
9018 static
9020  SCIP_LP* lp, /**< LP data object */
9021  int minsize, /**< minimal number of elements */
9022  SCIP_Real growfact /**< growing factor */
9023  )
9024 {
9025  assert(lp != NULL);
9026  assert(lp->divechgsides != NULL);
9027  assert(lp->divechgsidetypes != NULL);
9028  assert(lp->divechgrows != NULL);
9029  assert(lp->ndivechgsides > 0);
9030  assert(lp->divechgsidessize > 0);
9031  assert(minsize > 0);
9032 
9033  if( minsize <= lp->divechgsidessize )
9034  return SCIP_OKAY;
9035 
9036  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9040 
9041  return SCIP_OKAY;
9042 }
9043 
9044 static
9046  SCIP_LP* lp /**< LP data object */
9047  )
9048 {
9049  assert(lp != NULL);
9050  assert(lp->divechgsides != NULL);
9051  assert(lp->divechgsidetypes != NULL);
9052  assert(lp->divechgrows != NULL);
9053  assert(lp->ndivechgsides == 0);
9054  assert(lp->divechgsidessize > 0);
9055 
9059  lp->divechgsidessize = 0;
9060 }
9061 
9062 #define DIVESTACKINITSIZE 100
9063 
9064 /** creates empty LP data object */
9066  SCIP_LP** lp, /**< pointer to LP data object */
9067  SCIP_SET* set, /**< global SCIP settings */
9068  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9069  SCIP_STAT* stat, /**< problem statistics */
9070  const char* name /**< problem name */
9071  )
9072 {
9073  SCIP_Bool success;
9074 
9075  assert(lp != NULL);
9076  assert(set != NULL);
9077  assert(stat != NULL);
9078  assert(name != NULL);
9079 
9080  SCIP_ALLOC( BMSallocMemory(lp) );
9081 
9082  /* open LP Solver interface */
9083  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9084 
9085  (*lp)->lpicols = NULL;
9086  (*lp)->lpirows = NULL;
9087  (*lp)->chgcols = NULL;
9088  (*lp)->chgrows = NULL;
9089  (*lp)->cols = NULL;
9090  (*lp)->soldirection = NULL;
9091  (*lp)->lazycols = NULL;
9092  (*lp)->rows = NULL;
9093  (*lp)->lpobjval = 0.0;
9094  (*lp)->glbpseudoobjval = 0.0;
9095  (*lp)->relglbpseudoobjval = 0.0;
9096  (*lp)->glbpseudoobjvalid = TRUE;
9097  (*lp)->glbpseudoobjvalinf = 0;
9098  (*lp)->pseudoobjval = 0.0;
9099  (*lp)->relpseudoobjval = 0.0;
9100  (*lp)->pseudoobjvalid = TRUE;
9101  (*lp)->pseudoobjvalinf = 0;
9102  (*lp)->looseobjval = 0.0;
9103  (*lp)->rellooseobjval = 0.0;
9104  (*lp)->looseobjvalid = TRUE;
9105  (*lp)->looseobjvalinf = 0;
9106  (*lp)->nloosevars = 0;
9107  (*lp)->rootlpobjval = SCIP_INVALID;
9108  (*lp)->rootlooseobjval = SCIP_INVALID;
9109  (*lp)->cutoffbound = SCIPsetInfinity(set);
9110  (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9111  SCIPlpResetFeastol(*lp, set);
9112  (*lp)->validdegeneracylp = -1;
9113  (*lp)->objsqrnorm = 0.0;
9114  (*lp)->objsumnorm = 0.0;
9115  (*lp)->lpicolssize = 0;
9116  (*lp)->nlpicols = 0;
9117  (*lp)->lpirowssize = 0;
9118  (*lp)->nlpirows = 0;
9119  (*lp)->lpifirstchgcol = 0;
9120  (*lp)->lpifirstchgrow = 0;
9121  (*lp)->colssize = 0;
9122  (*lp)->soldirectionsize = 0;
9123  (*lp)->ncols = 0;
9124  (*lp)->lazycolssize = 0;
9125  (*lp)->nlazycols = 0;
9126  (*lp)->rowssize = 0;
9127  (*lp)->nrows = 0;
9128  (*lp)->chgcolssize = 0;
9129  (*lp)->nchgcols = 0;
9130  (*lp)->chgrowssize = 0;
9131  (*lp)->nchgrows = 0;
9132  (*lp)->firstnewcol = 0;
9133  (*lp)->firstnewrow = 0;
9134  (*lp)->nremovablecols = 0;
9135  (*lp)->nremovablerows = 0;
9136  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9137  (*lp)->validfarkaslp = -1;
9138  (*lp)->validsoldirlp = -1;
9139  (*lp)->validsoldirsol = NULL;
9140  (*lp)->objsqrnormunreliable = FALSE;
9141  (*lp)->flushdeletedcols = FALSE;
9142  (*lp)->flushaddedcols = FALSE;
9143  (*lp)->flushdeletedrows = FALSE;
9144  (*lp)->flushaddedrows = FALSE;
9145  (*lp)->updateintegrality = TRUE;
9146  (*lp)->flushed = TRUE;
9147  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9148  (*lp)->solved = TRUE;
9149  (*lp)->primalfeasible = TRUE;
9150  (*lp)->primalchecked = TRUE;
9151  (*lp)->dualfeasible = TRUE;
9152  (*lp)->dualchecked = TRUE;
9153  (*lp)->solisbasic = FALSE;
9154  (*lp)->rootlpisrelax = TRUE;
9155  (*lp)->isrelax = TRUE;
9156  (*lp)->installing = FALSE;
9157  (*lp)->strongbranching = FALSE;
9158  (*lp)->strongbranchprobing = FALSE;
9159  (*lp)->probing = FALSE;
9160  (*lp)->diving = FALSE;
9161  (*lp)->divingobjchg = FALSE;
9162  (*lp)->divinglazyapplied = FALSE;
9163  (*lp)->divelpistate = NULL;
9164  (*lp)->divelpwasprimfeas = TRUE;
9165  (*lp)->divelpwasprimchecked = TRUE;
9166  (*lp)->divelpwasdualfeas = TRUE;
9167  (*lp)->divelpwasdualchecked = TRUE;
9168  (*lp)->divechgsides = NULL;
9169  (*lp)->divechgsidetypes = NULL;
9170  (*lp)->divechgrows = NULL;
9171  (*lp)->ndivechgsides = 0;
9172  (*lp)->divechgsidessize = 0;
9173  (*lp)->ndivingrows = 0;
9174  (*lp)->divinglpiitlim = INT_MAX;
9175  (*lp)->resolvelperror = FALSE;
9176  (*lp)->divenolddomchgs = 0;
9177  (*lp)->adjustlpval = FALSE;
9178  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9179  (*lp)->lpifeastol = (*lp)->feastol;
9180  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9181  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9182  (*lp)->lpifromscratch = FALSE;
9183  (*lp)->lpifastmip = set->lp_fastmip;
9184  (*lp)->lpiscaling = set->lp_scaling;
9185  (*lp)->lpipresolving = set->lp_presolving;
9186  (*lp)->lpilpinfo = set->disp_lpinfo;
9187  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9188  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9189  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9190  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9191  (*lp)->lpimarkowitz = set->lp_markowitz;
9192  (*lp)->lpiitlim = INT_MAX;
9193  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9194  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9195  (*lp)->lpithreads = set->lp_threads;
9196  (*lp)->lpitiming = (int) set->time_clocktype;
9197  (*lp)->lpirandomseed = set->random_randomseed;
9198  (*lp)->storedsolvals = NULL;
9199 
9200  /* allocate arrays for diving */
9202 
9203  /* set default parameters in LP solver */
9204  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9205  if( !success )
9206  {
9207  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9208  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9210  }
9211  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9212  (*lp)->lpihasfeastol = success;
9213  if( !success )
9214  {
9215  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9216  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9218  }
9219  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9220  (*lp)->lpihasdualfeastol = success;
9221  if( !success )
9222  {
9223  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9224  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9226  }
9227  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9228  (*lp)->lpihasbarrierconvtol = success;
9229  if( !success )
9230  {
9231  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9232  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9234  }
9235  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9236  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9237  (*lp)->lpihasfastmip = success;
9238  if( !success )
9239  {
9240  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9241  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9243  }
9244  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9245  (*lp)->lpihasscaling = success;
9246  if( !success )
9247  {
9248  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9249  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9251  }
9252  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9253  (*lp)->lpihaspresolving = success;
9254  if( !success )
9255  {
9256  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9257  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9259  }
9260  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9261  if( !success )
9262  {
9263  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9264  "LP Solver <%s>: clock type cannot be set\n",
9266  }
9267  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9268  if( !success )
9269  {
9270  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9271  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9273  }
9274  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9275  if( !success )
9276  {
9277  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9278  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9280  }
9281  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9282  if( !success )
9283  {
9284  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9285  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9287  }
9288  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9289  (*lp)->lpihasrowrep = success;
9290  if( !success )
9291  {
9292  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9293  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9295  }
9296  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9297  (*lp)->lpihaspolishing = success;
9298  if( !success )
9299  {
9300  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9301  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9303  }
9304  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9305  (*lp)->lpihasrefactor = success;
9306  if( !success )
9307  {
9308  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9309  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9311  }
9312  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9313  if( !success )
9314  {
9315  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9316  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9318  }
9319  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9320  if( !success )
9321  {
9322  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9323  "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9325  }
9326  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9327  if( !success )
9328  {
9329  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9330  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9332  }
9333  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9334  if( (*lp)->lpirandomseed != 0 )
9335  {
9336  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9337  if( !success )
9338  {
9339  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9340  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9342  }
9343  }
9344 
9345  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9346  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9347  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9348  {
9349  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9350  return SCIP_PARAMETERWRONGVAL;
9351  }
9352 
9353  return SCIP_OKAY;
9354 }
9355 
9356 /** frees LP data object */
9358  SCIP_LP** lp, /**< pointer to LP data object */
9359  BMS_BLKMEM* blkmem, /**< block memory */
9360  SCIP_SET* set, /**< global SCIP settings */
9361  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9362  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9363  )
9364 {
9365  int i;
9366 
9367  assert(lp != NULL);
9368  assert(*lp != NULL);
9369 
9370  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9371 
9372  freeDiveChgSideArrays(*lp);
9373 
9374  /* release LPI rows */
9375  for( i = 0; i < (*lp)->nlpirows; ++i )
9376  {
9377  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9378  }
9379 
9380  if( (*lp)->lpi != NULL )
9381  {
9382  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9383  }
9384 
9385  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9386  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9387  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9388  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9389  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9390  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9391  BMSfreeMemoryArrayNull(&(*lp)->cols);
9392  BMSfreeMemoryArrayNull(&(*lp)->rows);
9393  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9394  BMSfreeMemory(lp);
9395 
9396  return SCIP_OKAY;
9397 }
9398 
9399 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9400  * changes to the LP solver
9401  */
9403  SCIP_LP* lp, /**< LP data */
9404  BMS_BLKMEM* blkmem, /**< block memory */
9405  SCIP_SET* set, /**< global SCIP settings */
9406  SCIP_STAT* stat, /**< problem statistics */
9407  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9408  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9409  )
9410 {
9411  assert(stat != NULL);
9412 
9413  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9414  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9415 
9416  /* mark the empty LP to be solved */
9418  lp->lpobjval = 0.0;
9419  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9420  lp->validfarkaslp = -1;
9421  lp->validdegeneracylp = -1;
9422  lp->validsoldirlp = -1;
9423  lp->validsoldirsol = NULL;
9424  lp->solved = TRUE;
9425  lp->primalfeasible = TRUE;
9426  lp->primalchecked = TRUE;
9427  lp->dualfeasible = TRUE;
9428  lp->dualchecked = TRUE;
9429  lp->solisbasic = FALSE;
9431 
9432  return SCIP_OKAY;
9433 }
9434 
9435 /** adds a column to the LP */
9437  SCIP_LP* lp, /**< LP data */
9438  SCIP_SET* set, /**< global SCIP settings */
9439  SCIP_COL* col, /**< LP column */
9440  int depth /**< depth in the tree where the column addition is performed */
9441  )
9442 {
9443  assert(lp != NULL);
9444  assert(!lp->diving);
9445  assert(col != NULL);
9446  assert(col->len == 0 || col->rows != NULL);
9447  assert(col->lppos == -1);
9448  assert(col->var != NULL);
9449  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9450  assert(SCIPvarGetCol(col->var) == col);
9451  assert(SCIPvarIsIntegral(col->var) == col->integral);
9452 
9453  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9454 #ifdef SCIP_DEBUG
9455  {
9456  int i;
9457  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9458  for( i = 0; i < col->len; ++i )
9459  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9460  SCIPsetDebugMsgPrint(set, "\n");
9461  }
9462 #endif
9463 
9464  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9465  lp->cols[lp->ncols] = col;
9466  col->lppos = lp->ncols;
9467  col->lpdepth = depth;
9468  col->age = 0;
9469  lp->ncols++;
9470  if( col->removable )
9471  lp->nremovablecols++;
9472 
9473  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9474  {
9475  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9476  lp->lazycols[lp->nlazycols] = col;
9477  lp->nlazycols++;
9478  }
9479 
9480  /* mark the current LP unflushed */
9481  lp->flushed = FALSE;
9482 
9483  /* update column arrays of all linked rows */
9484  colUpdateAddLP(col, set);
9485 
9486  /* update the objective function vector norms */
9487  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9488 
9489  checkLinks(lp);
9490 
9491  return SCIP_OKAY;
9492 }
9493 
9494 /** adds a row to the LP and captures it */
9496  SCIP_LP* lp, /**< LP data */
9497  BMS_BLKMEM* blkmem, /**< block memory buffers */
9498  SCIP_SET* set, /**< global SCIP settings */
9499  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9500  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9501  SCIP_ROW* row, /**< LP row */
9502  int depth /**< depth in the tree where the row addition is performed */
9503  )
9504 {
9505  assert(lp != NULL);
9506  assert(row != NULL);
9507  assert(row->len == 0 || row->cols != NULL);
9508  assert(row->lppos == -1);
9509 
9510  SCIProwCapture(row);
9511  SCIProwLock(row);
9512 
9513  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9514 #ifdef SCIP_DEBUG
9515  {
9516  int i;
9517  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9518  for( i = 0; i < row->len; ++i )
9519  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9520  if( !SCIPsetIsZero(set, row->constant) )
9521  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9522  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9523  }
9524 #endif
9525 
9526  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9527  lp->rows[lp->nrows] = row;
9528  row->lppos = lp->nrows;
9529  row->lpdepth = depth;
9530  row->age = 0;
9531  lp->nrows++;
9532  if( row->removable )
9533  lp->nremovablerows++;
9534 
9535  /* mark the current LP unflushed */
9536  lp->flushed = FALSE;
9537 
9538  /* update row arrays of all linked columns */
9539  rowUpdateAddLP(row);
9540 
9541  checkLinks(lp);
9542 
9543  rowCalcNorms(row, set);
9544 
9545  /* check, if row addition to LP events are tracked
9546  * if so, issue ROWADDEDLP event
9547  */
9548  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9549  {
9550  SCIP_EVENT* event;
9551 
9552  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9553  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9554  }
9555 
9556  return SCIP_OKAY;
9557 }
9558 
9559 
9560 #ifndef NDEBUG
9561 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9562  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9563  * the lazycols array
9564  */
9565 static
9567  SCIP_LP* lp, /**< LP data */
9568  SCIP_SET* set /**< global SCIP settings */
9569  )
9570 {
9571  SCIP_Bool contained;
9572  int c;
9573  int i;
9574 
9575  assert(lp != NULL);
9576 
9577  /* check if each column in the lazy column array has a counter part in the column array */
9578  for( i = 0; i < lp->nlazycols; ++i )
9579  {
9580  /* check if each lazy column has at least on lazy bound */
9581  assert(lp->lazycols[i] != NULL);
9582  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9583 
9584  contained = FALSE;
9585  for( c = 0; c < lp->ncols; ++c )
9586  {
9587  if( lp->lazycols[i] == lp->cols[c] )
9588  {
9589  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9590  contained = TRUE;
9591  }
9592  }
9593  assert(contained);
9594  }
9595 
9596  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9597  * array */
9598  for( c = 0; c < lp->ncols; ++c )
9599  {
9600  contained = FALSE;
9601  assert(lp->cols[c] != NULL);
9602 
9603  for( i = 0; i < lp->nlazycols; ++i )
9604  {
9605  if( lp->lazycols[i] == lp->cols[c] )
9606  {
9607  contained = TRUE;
9608  }
9609  }
9610 
9611  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9612  }
9613 }
9614 #else
9615 #define checkLazyColArray(lp, set) /**/
9616 #endif
9617 
9618 /** removes all columns after the given number of cols from the LP */
9620  SCIP_LP* lp, /**< LP data */
9621  SCIP_SET* set, /**< global SCIP settings */
9622  int newncols /**< new number of columns in the LP */
9623  )
9624 {
9625  SCIP_COL* col;
9626  int c;
9627 
9628  assert(lp != NULL);
9629 
9630  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9631  assert(0 <= newncols);
9632  assert(newncols <= lp->ncols);
9633 
9634  if( newncols < lp->ncols )
9635  {
9636  assert(!lp->diving);
9637 
9638  for( c = lp->ncols-1; c >= newncols; --c )
9639  {
9640  col = lp->cols[c];
9641  assert(col != NULL);
9642  assert(col->len == 0 || col->rows != NULL);
9643  assert(col->var != NULL);
9644  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9645  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9646  assert(col->lppos == c);
9647 
9648  /* mark column to be removed from the LP */
9649  col->lppos = -1;
9650  col->lpdepth = -1;
9651  lp->ncols--;
9652 
9653  /* count removable columns */
9654  if( col->removable )
9655  lp->nremovablecols--;
9656 
9657  /* update column arrays of all linked rows */
9658  colUpdateDelLP(col, set);
9659 
9660  /* update the objective function vector norms */
9661  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9662  }
9663  assert(lp->ncols == newncols);
9664  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9665 
9666  /* remove columns which are deleted from the lazy column array */
9667  c = 0;
9668  while( c < lp->nlazycols )
9669  {
9670  if( lp->lazycols[c]->lppos < 0 )
9671  {
9672  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9673  lp->nlazycols--;
9674  }
9675  else
9676  c++;
9677  }
9678 
9679  /* mark the current LP unflushed */
9680  lp->flushed = FALSE;
9681 
9682  checkLazyColArray(lp, set);
9683  checkLinks(lp);
9684  }
9685  assert(lp->nremovablecols <= lp->ncols);
9686 
9687  return SCIP_OKAY;
9688 }
9689 
9690 /** removes and releases all rows after the given number of rows from the LP */
9692  SCIP_LP* lp, /**< LP data */
9693  BMS_BLKMEM* blkmem, /**< block memory */
9694  SCIP_SET* set, /**< global SCIP settings */
9695  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9696  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9697  int newnrows /**< new number of rows in the LP */
9698  )
9699 {
9700  SCIP_ROW* row;
9701  int r;
9702 
9703  assert(lp != NULL);
9704  assert(0 <= newnrows && newnrows <= lp->nrows);
9705 
9706  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9707  if( newnrows < lp->nrows )
9708  {
9709  for( r = lp->nrows-1; r >= newnrows; --r )
9710  {
9711  row = lp->rows[r];
9712  assert(row != NULL);
9713  assert(row->len == 0 || row->cols != NULL);
9714  assert(row->lppos == r);
9715 
9716  /* mark row to be removed from the LP */
9717  row->lppos = -1;
9718  row->lpdepth = -1;
9719  lp->nrows--;
9720 
9721  /* count removable rows */
9722  if( row->removable )
9723  lp->nremovablerows--;
9724 
9725  /* update row arrays of all linked columns */
9726  rowUpdateDelLP(row);
9727 
9728  SCIProwUnlock(lp->rows[r]);
9729 
9730  /* check, if row deletion events are tracked
9731  * if so, issue ROWDELETEDLP event
9732  */
9733  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9734  {
9735  SCIP_EVENT* event;
9736 
9737  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9738  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9739  }
9740 
9741  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9742  }
9743  assert(lp->nrows == newnrows);
9744  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9745 
9746  /* mark the current LP unflushed */
9747  lp->flushed = FALSE;
9748 
9749  checkLinks(lp);
9750  }
9751  assert(lp->nremovablerows <= lp->nrows);
9752 
9753  return SCIP_OKAY;
9754 }
9755 
9756 /** removes all columns and rows from LP, releases all rows */
9758  SCIP_LP* lp, /**< LP data */
9759  BMS_BLKMEM* blkmem, /**< block memory */
9760  SCIP_SET* set, /**< global SCIP settings */
9761  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9762  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9763  )
9764 {
9765  assert(lp != NULL);
9766  assert(!lp->diving);
9767 
9768  SCIPsetDebugMsg(set, "clearing LP\n");
9769  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9770  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9771 
9772  return SCIP_OKAY;
9773 }
9774 
9775 /** remembers number of columns and rows to track the newly added ones */
9777  SCIP_LP* lp /**< current LP data */
9778  )
9779 {
9780  assert(lp != NULL);
9781  assert(!lp->diving);
9782 
9783  lp->firstnewrow = lp->nrows;
9784  lp->firstnewcol = lp->ncols;
9785 }
9786 
9787 /** sets the remembered number of columns and rows to the given values */
9789  SCIP_LP* lp, /**< current LP data */
9790  int nrows, /**< number of rows to set the size marker to */
9791  int ncols /**< number of columns to set the size marker to */
9792  )
9793 {
9794  assert(lp != NULL);
9795  assert(!lp->diving);
9796 
9797  lp->firstnewrow = nrows;
9798  lp->firstnewcol = ncols;
9799 }
9800 
9801 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9803  SCIP_LP* lp, /**< LP data */
9804  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9805  )
9806 {
9807  assert(lp != NULL);
9808  assert(lp->flushed);
9809  assert(lp->solved);
9810  assert(lp->solisbasic);
9811  assert(basisind != NULL);
9812 
9813  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9814 
9815  return SCIP_OKAY;
9816 }
9817 
9818 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9820  SCIP_LP* lp, /**< LP data */
9821  int* cstat, /**< array to store column basis status, or NULL */
9822  int* rstat /**< array to store row basis status, or NULL */
9823  )
9824 {
9825  assert(lp != NULL);
9826  assert(lp->flushed);
9827  assert(lp->solved);
9828  assert(lp->solisbasic);
9829 
9830  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9831 
9832  return SCIP_OKAY;
9833 }
9834 
9835 /** gets a row from the inverse basis matrix B^-1 */
9837  SCIP_LP* lp, /**< LP data */
9838  int r, /**< row number */
9839  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9840  int* inds, /**< array to store the non-zero indices, or NULL */
9841  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9842  * (-1: if we do not store sparsity informations) */
9843  )
9844 {
9845  assert(lp != NULL);
9846  assert(lp->flushed);
9847  assert(lp->solved);
9848  assert(lp->solisbasic);
9849  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9850  assert(coef != NULL);
9851 
9852  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9853 
9854  return SCIP_OKAY;
9855 }
9856 
9857 /** gets a column from the inverse basis matrix B^-1 */
9859  SCIP_LP* lp, /**< LP data */
9860  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9861  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9862  * to get the array which links the B^-1 column numbers to the row and
9863  * column numbers of the LP! c must be between 0 and nrows-1, since the
9864  * basis has the size nrows * nrows */
9865  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9866  int* inds, /**< array to store the non-zero indices, or NULL */
9867  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9868  * (-1: if we do not store sparsity informations) */
9869  )
9870 {
9871  assert(lp != NULL);
9872  assert(lp->flushed);
9873  assert(lp->solved);
9874  assert(lp->solisbasic);
9875  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9876  assert(coef != NULL);
9877 
9878  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9879 
9880  return SCIP_OKAY;
9881 }
9882 
9883 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9885  SCIP_LP* lp, /**< LP data */
9886  int r, /**< row number */
9887  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9888  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9889  int* inds, /**< array to store the non-zero indices, or NULL */
9890  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9891  * (-1: if we do not store sparsity informations) */
9892  )
9893 {
9894  assert(lp != NULL);
9895  assert(lp->flushed);
9896  assert(lp->solved);
9897  assert(lp->solisbasic);
9898  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9899  assert(coef != NULL);
9900 
9901  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9902 
9903  return SCIP_OKAY;
9904 }
9905 
9906 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9907  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9908  */
9910  SCIP_LP* lp, /**< LP data */
9911  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9912  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9913  int* inds, /**< array to store the non-zero indices, or NULL */
9914  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9915  * (-1: if we do not store sparsity informations) */
9916  )
9917 {
9918  assert(lp != NULL);
9919  assert(lp->flushed);
9920  assert(lp->solved);
9921  assert(lp->solisbasic);
9922  assert(0 <= c && c < lp->ncols);
9923  assert(coef != NULL);
9924 
9925  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9926 
9927  return SCIP_OKAY;
9928 }
9929 
9930 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9931  * LP row are swapped in the summation
9932  */
9934  SCIP_LP* lp, /**< LP data */
9935  SCIP_SET* set, /**< global SCIP settings */
9936  SCIP_PROB* prob, /**< problem data */
9937  SCIP_Real* weights, /**< row weights in row summation */
9938  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9939  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9940  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9941  )
9942 {
9943  SCIP_ROW* row;
9944  int r;
9945  int i;
9946  int idx;
9947  SCIP_Bool lhsinfinite;
9948  SCIP_Bool rhsinfinite;
9949 
9950  assert(lp != NULL);
9951  assert(prob != NULL);
9952  assert(weights != NULL);
9953  assert(sumcoef != NULL);
9954  assert(sumlhs != NULL);
9955  assert(sumrhs != NULL);
9956 
9957  /**@todo test, if a column based summation is faster */
9958 
9959  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9960  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9961  *sumlhs = 0.0;
9962  *sumrhs = 0.0;
9963  lhsinfinite = FALSE;
9964  rhsinfinite = FALSE;
9965  for( r = 0; r < lp->nrows; ++r )
9966  {
9967  if( !SCIPsetIsZero(set, weights[r]) )
9968  {
9969  row = lp->rows[r];
9970  assert(row != NULL);
9971  assert(row->len == 0 || row->cols != NULL);
9972  assert(row->len == 0 || row->cols_index != NULL);
9973  assert(row->len == 0 || row->vals != NULL);
9974 
9975  /* add the row coefficients to the sum */
9976  for( i = 0; i < row->len; ++i )
9977  {
9978  assert(row->cols[i] != NULL);
9979  assert(row->cols[i]->var != NULL);
9980  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9981  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9982  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9983  idx = row->cols[i]->var_probindex;
9984  assert(0 <= idx && idx < prob->nvars);
9985  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9986  }
9987 
9988  /* add the row sides to the sum, depending on the sign of the weight */
9989  if( weights[r] > 0.0 )
9990  {
9991  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9992  if( !lhsinfinite )
9993  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9994  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9995  if( !rhsinfinite )
9996  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9997  }
9998  else
9999  {
10000  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10001  if( !lhsinfinite )
10002  (*sumlhs) += weights[r] * (row->rhs - row->constant);
10003  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10004  if( !rhsinfinite )
10005  (*sumrhs) += weights[r] * (row->lhs - row->constant);
10006  }
10007  }
10008  }
10009 
10010  if( lhsinfinite )
10011  *sumlhs = -SCIPsetInfinity(set);
10012  if( rhsinfinite )
10013  *sumrhs = SCIPsetInfinity(set);
10014 
10015  return SCIP_OKAY;
10016 }
10017 
10018 /** stores LP state (like basis information) into LP state object */
10020  SCIP_LP* lp, /**< LP data */
10021  BMS_BLKMEM* blkmem, /**< block memory */
10022  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10023  )
10024 {
10025  assert(lp != NULL);
10026  assert(lp->flushed);
10027  assert(lp->solved);
10028  assert(blkmem != NULL);
10029  assert(lpistate != NULL);
10030 
10031  /* check whether there is no lp */
10032  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10033  *lpistate = NULL;
10034  else
10035  {
10036  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10037  }
10038 
10039  return SCIP_OKAY;
10040 }
10041 
10042 /** loads LP state (like basis information) into solver */
10044  SCIP_LP* lp, /**< LP data */
10045  BMS_BLKMEM* blkmem, /**< block memory */
10046  SCIP_SET* set, /**< global SCIP settings */
10047  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10048  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10049  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10050  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10051  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10052  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10053  )
10054 {
10055  assert(lp != NULL);
10056  assert(blkmem != NULL);
10057 
10058  /* flush changes to the LP solver */
10059  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
10060  assert(lp->flushed);
10061 
10062  if( lp->solved && lp->solisbasic )
10063  return SCIP_OKAY;
10064 
10065  /* set LPI state in the LP solver */
10066  if( lpistate == NULL )
10067  lp->solisbasic = FALSE;
10068  else
10069  {
10070  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10071  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10072  }
10073  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10074  * flushed and solved, also, e.g., when we hit the iteration limit
10075  */
10076  lp->primalfeasible = wasprimfeas;
10077  lp->primalchecked = wasprimchecked;
10078  lp->dualfeasible = wasdualfeas;
10079  lp->dualchecked = wasdualchecked;
10080 
10081  return SCIP_OKAY;
10082 }
10083 
10084 /** frees LP state information */
10086  SCIP_LP* lp, /**< LP data */
10087  BMS_BLKMEM* blkmem, /**< block memory */
10088  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10089  )
10090 {
10091  assert(lp != NULL);
10092 
10093  if( *lpistate != NULL )
10094  {
10095  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10096  }
10097 
10098  return SCIP_OKAY;
10099 }
10100 
10101 /** stores pricing norms into LP norms object */
10103  SCIP_LP* lp, /**< LP data */
10104  BMS_BLKMEM* blkmem, /**< block memory */
10105  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10106  )
10107 {
10108  assert(lp != NULL);
10109  assert(lp->flushed);
10110  assert(lp->solved);
10111  assert(blkmem != NULL);
10112  assert(lpinorms != NULL);
10113 
10114  /* check whether there is no lp */
10115  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10116  *lpinorms = NULL;
10117  else
10118  {
10119  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10120  }
10121 
10122  return SCIP_OKAY;
10123 }
10124 
10125 /** loads pricing norms from LP norms object into solver */
10127  SCIP_LP* lp, /**< LP data */
10128  BMS_BLKMEM* blkmem, /**< block memory */
10129  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10130  )
10131 {
10132  assert(lp != NULL);
10133  assert(blkmem != NULL);
10134  assert(lp->flushed);
10135 
10136  /* set LPI norms in the LP solver */
10137  if( lpinorms != NULL )
10138  {
10139  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10140  }
10141 
10142  return SCIP_OKAY;
10143 }
10144 
10145 /** frees pricing norms information */
10147  SCIP_LP* lp, /**< LP data */
10148  BMS_BLKMEM* blkmem, /**< block memory */
10149  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10150  )
10151 {
10152  assert(lp != NULL);
10153 
10154  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10155 
10156  return SCIP_OKAY;
10157 }
10158 
10159 /** return the current cutoff bound of the lp */
10161  SCIP_LP* lp /**< current LP data */
10162  )
10163 {
10164  assert(lp != NULL);
10165 
10166  return lp->cutoffbound;
10167 }
10168 
10169 /** sets the upper objective limit of the LP solver */
10171  SCIP_LP* lp, /**< current LP data */
10172  SCIP_SET* set, /**< global SCIP settings */
10173  SCIP_PROB* prob, /**< problem data */
10174  SCIP_Real cutoffbound /**< new upper objective limit */
10175  )
10176 {
10177  assert(lp != NULL);
10178 
10179  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10180 
10181  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10182  * in SCIPendDive())
10183  */
10184  if( SCIPlpDivingObjChanged(lp) )
10185  {
10186  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10187  return SCIP_OKAY;
10188  }
10189 
10190  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10191  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10192  {
10193  /* mark the current solution invalid */
10194  lp->solved = FALSE;
10195  lp->lpobjval = SCIP_INVALID;
10197  }
10198  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10199  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10200  */
10202  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10203  {
10204  assert(lp->flushed);
10205  assert(lp->solved);
10207  }
10208 
10209  lp->cutoffbound = cutoffbound;
10210 
10211  return SCIP_OKAY;
10212 }
10213 
10214 /** gets current primal feasibility tolerance of LP solver */
10216  SCIP_LP* lp /**< current LP data */
10217  )
10218 {
10219  assert(lp != NULL);
10220 
10221  return lp->feastol;
10222 }
10223 
10224 /** sets primal feasibility tolerance of LP solver */
10226  SCIP_LP* lp, /**< current LP data */
10227  SCIP_SET* set, /**< global SCIP settings */
10228  SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10229  )
10230 {
10231  assert(lp != NULL);
10232  assert(newfeastol > 0.0);
10233 
10234  SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10235 
10236  /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10237  if( newfeastol < lp->feastol )
10238  {
10239  lp->solved = FALSE;
10241  }
10242 
10243  lp->feastol = newfeastol;
10244 }
10245 
10246 /** resets primal feasibility tolerance of LP solver
10247  *
10248  * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10249  */
10251  SCIP_LP* lp, /**< current LP data */
10252  SCIP_SET* set /**< global SCIP settings */
10253  )
10254 {
10255  assert(lp != NULL);
10256 
10257  SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10258 
10259  if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10260  SCIPlpSetFeastol(lp, set, MIN(SCIPsetRelaxfeastol(set), SCIPsetLPFeastolFactor(set) * SCIPsetFeastol(set))); /*lint !e666*/
10261  else
10263 }
10264 
10265 /** returns the name of the given LP algorithm */
10266 static
10267 const char* lpalgoName(
10268  SCIP_LPALGO lpalgo /**< LP algorithm */
10269  )
10270 {
10271  switch( lpalgo )
10272  {
10274  return "primal simplex";
10276  return "dual simplex";
10277  case SCIP_LPALGO_BARRIER:
10278  return "barrier";
10280  return "barrier/crossover";
10281  default:
10282  SCIPerrorMessage("invalid LP algorithm\n");
10283  SCIPABORT();
10284  return "invalid"; /*lint !e527*/
10285  }
10286 }
10287 
10288 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10289 static
10291  SCIP_LP* lp, /**< current LP data */
10292  SCIP_SET* set, /**< global SCIP settings */
10293  SCIP_STAT* stat, /**< problem statistics */
10294  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10295  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10296  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10297  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10298  )
10299 {
10300  SCIP_Real timedelta;
10301  SCIP_RETCODE retcode;
10302  int iterations;
10303 
10304  assert(lp != NULL);
10305  assert(lp->flushed);
10306  assert(set != NULL);
10307  assert(stat != NULL);
10308  assert(lperror != NULL);
10309 
10310  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",
10311  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10312 
10313  *lperror = FALSE;
10314 
10315 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10316  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10317  {
10318  char fname[SCIP_MAXSTRLEN];
10319  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10320  SCIP_CALL( SCIPlpWrite(lp, fname) );
10321  SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10322  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10323  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10324  }
10325 #endif
10326 
10327  /* start timing */
10328  if( lp->diving || lp->probing )
10329  {
10330  if( lp->strongbranchprobing )
10331  SCIPclockStart(stat->strongbranchtime, set);
10332  else
10333  SCIPclockStart(stat->divinglptime, set);
10334 
10335  timedelta = 0.0; /* unused for diving or probing */
10336  }
10337  else
10338  {
10339  SCIPclockStart(stat->primallptime, set);
10340  timedelta = -SCIPclockGetTime(stat->primallptime);
10341  }
10342 
10343  /* if this is a call to resolve an instable LP, collect time */
10344  if( instable )
10345  {
10347  }
10348 
10349  /* call primal simplex */
10350  retcode = SCIPlpiSolvePrimal(lp->lpi);
10351  if( retcode == SCIP_LPERROR )
10352  {
10353  *lperror = TRUE;
10354  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10355  }
10356  else
10357  {
10358  SCIP_CALL( retcode );
10359  }
10361  lp->solisbasic = TRUE;
10362 
10363  /* stop timing */
10364  if( lp->diving || lp->probing )
10365  {
10366  if( lp->strongbranchprobing )
10367  SCIPclockStop(stat->strongbranchtime, set);
10368  else
10369  SCIPclockStop(stat->divinglptime, set);
10370  }
10371  else
10372  {
10373  timedelta += SCIPclockGetTime(stat->primallptime);
10374  SCIPclockStop(stat->primallptime, set);
10375  }
10376 
10377  if ( instable )
10378  {
10380  }
10381 
10382  /* count number of iterations */
10383  SCIPstatIncrement(stat, set, lpcount);
10384  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10385  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10386  {
10387  if( !lp->strongbranchprobing )
10388  {
10389  SCIPstatIncrement(stat, set, nlps);
10390  SCIPstatAdd( stat, set, nlpiterations, iterations );
10391  }
10392  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10393  {
10394  SCIPstatIncrement(stat, set, nprimalresolvelps );
10395  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10396  }
10397  if ( instable )
10398  {
10399  SCIPstatIncrement(stat, set, nresolveinstablelps);
10400  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10401  }
10402  if( lp->diving || lp->probing )
10403  {
10404  if( lp->strongbranchprobing )
10405  {
10406  SCIPstatIncrement(stat, set, nsbdivinglps);
10407  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10408  }
10409  else
10410  {
10411  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10412  SCIPstatIncrement(stat, set, ndivinglps);
10413  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10414  }
10415  }
10416  else
10417  {
10418  SCIPstatIncrement(stat, set, nprimallps);
10419  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10420  }
10421  }
10422  else
10423  {
10424  if ( ! lp->diving && ! lp->probing )
10425  {
10426  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10427  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10428  }
10429 
10430  if ( keepsol && !(*lperror) )
10431  {
10432  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10433  if( lp->validsollp == stat->lpcount-1 )
10434  lp->validsollp = stat->lpcount;
10435  if( lp->validfarkaslp == stat->lpcount-1 )
10436  lp->validfarkaslp = stat->lpcount;
10437  }
10438  }
10439 
10440  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10441  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10442 
10443  return SCIP_OKAY;
10444 }
10445 
10446 /** calls LPI to perform dual simplex, measures time and counts iterations */
10447 static
10449  SCIP_LP* lp, /**< current LP data */
10450  SCIP_SET* set, /**< global SCIP settings */
10451  SCIP_STAT* stat, /**< problem statistics */
10452  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10453  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10454  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10455  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10456  )
10457 {
10458  SCIP_Real timedelta;
10459  SCIP_RETCODE retcode;
10460  int iterations;
10461 
10462  assert(lp != NULL);
10463  assert(lp->flushed);
10464  assert(set != NULL);
10465  assert(stat != NULL);
10466  assert(lperror != NULL);
10467 
10468  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",
10469  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10470 
10471  *lperror = FALSE;
10472 
10473 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10474  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10475  {
10476  char fname[SCIP_MAXSTRLEN];
10477  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10478  SCIP_CALL( SCIPlpWrite(lp, fname) );
10479  SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10480  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10481  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10482  }
10483 #endif
10484 
10485  /* start timing */
10486  if( lp->diving || lp->probing )
10487  {
10488  if( lp->strongbranchprobing )
10489  SCIPclockStart(stat->strongbranchtime, set);
10490  else
10491  SCIPclockStart(stat->divinglptime, set);
10492 
10493  timedelta = 0.0; /* unused for diving or probing */
10494  }
10495  else
10496  {
10497  SCIPclockStart(stat->duallptime, set);
10498  timedelta = -SCIPclockGetTime(stat->duallptime);
10499  }
10500 
10501  /* if this is a call to resolve an instable LP, collect time */
10502  if ( instable )
10503  {
10505  }
10506 
10507  /* call dual simplex */
10508  retcode = SCIPlpiSolveDual(lp->lpi);
10509  if( retcode == SCIP_LPERROR )
10510  {
10511  *lperror = TRUE;
10512  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10513  }
10514  else
10515  {
10516  SCIP_CALL( retcode );
10517  }
10519  lp->solisbasic = TRUE;
10520 
10521  /* stop timing */
10522  if( lp->diving || lp->probing )
10523  {
10524  if( lp->strongbranchprobing )
10525  SCIPclockStop(stat->strongbranchtime, set);
10526  else
10527  SCIPclockStop(stat->divinglptime, set);
10528  }
10529  else
10530  {
10531  timedelta += SCIPclockGetTime(stat->duallptime);
10532  SCIPclockStop(stat->duallptime, set);
10533  }
10534 
10535  if ( instable )
10536  {
10538  }
10539 
10540  /* count number of iterations */
10541  SCIPstatIncrement(stat, set, lpcount);
10542  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10543  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10544  {
10545  if( !lp->strongbranchprobing )
10546  {
10547  SCIPstatIncrement(stat, set, nlps);
10548  SCIPstatAdd(stat, set, nlpiterations, iterations);
10549  }
10550  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10551  {
10552  SCIPstatIncrement(stat, set, ndualresolvelps);
10553  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10554  }
10555  if ( instable )
10556  {
10557  SCIPstatIncrement(stat, set, nresolveinstablelps);
10558  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10559  }
10560  if( lp->diving || lp->probing )
10561  {
10562  if( lp->strongbranchprobing )
10563  {
10564  SCIPstatIncrement(stat, set, nsbdivinglps);
10565  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10566  }
10567  else
10568  {
10569  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10570  SCIPstatIncrement(stat, set, ndivinglps);
10571  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10572  }
10573  }
10574  else
10575  {
10576  SCIPstatIncrement(stat, set, nduallps);
10577  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10578  }
10579  }
10580  else
10581  {
10582  if ( ! lp->diving && ! lp->probing )
10583  {
10584  SCIPstatIncrement(stat, set, ndualzeroitlps);
10585  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10586  }
10587 
10588  if( keepsol && !(*lperror) )
10589  {
10590  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10591  if( lp->validsollp == stat->lpcount-1 )
10592  lp->validsollp = stat->lpcount;
10593  if( lp->validfarkaslp == stat->lpcount-1 )
10594  lp->validfarkaslp = stat->lpcount;
10595  }
10596  }
10597 
10598  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10599  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10600 
10601  return SCIP_OKAY;
10602 }
10603 
10604 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10605  *
10606  * We follow the approach of the following paper to find a lexicographically minimal optimal
10607  * solution:
10608  *
10609  * Zanette, Fischetti, Balas@n
10610  * Can pure cutting plane algorithms work?@n
10611  * IPCO 2008, Bertinoro, Italy.
10612  *
10613  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10614  * heuristic, i.e., we limit the number of components which are minimized.
10615  *
10616  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10617  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10618  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10619  * pivots that will not change the objective are allowed afterwards.
10620  *
10621  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10622  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10623  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10624  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10625  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10626  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10627  * reduced cost. We then choose the next variable and iterate.
10628  *
10629  * We stop the process once we do not find candidates or have performed a maximum number of
10630  * iterations.
10631  *
10632  * @todo Does this really produce a lexicographically minimal solution?
10633  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10634  * guarantee that these variables will not be changed in later stages? We can fix these variables
10635  * to their lower bound, but this destroys the basis.
10636  * @todo Should we use lexicographical minimization in diving/probing or not?
10637  */
10638 static
10640  SCIP_LP* lp, /**< current LP data */
10641  SCIP_SET* set, /**< global SCIP settings */
10642  SCIP_STAT* stat, /**< problem statistics */
10643  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10644  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10645  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10646  )
10647 {
10648  SCIP_Real timedelta;
10649  SCIP_RETCODE retcode;
10650  int totalIterations;
10651  int lexIterations;
10652  int iterations;
10653  int rounds;
10654 
10655  assert(lp != NULL);
10656  assert(lp->flushed);
10657  assert(set != NULL);
10658  assert(stat != NULL);
10659  assert(lperror != NULL);
10660 
10661  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",
10662  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10663 
10664  *lperror = FALSE;
10665 
10666  /* start timing */
10667  if( lp->diving || lp->probing )
10668  {
10669  if( lp->strongbranchprobing )
10670  SCIPclockStart(stat->strongbranchtime, set);
10671  else
10672  SCIPclockStart(stat->divinglptime, set);
10673 
10674  timedelta = 0.0; /* unused for diving or probing */
10675  }
10676  else
10677  {
10678  SCIPclockStart(stat->duallptime, set);
10679  timedelta = -SCIPclockGetTime(stat->duallptime);
10680  }
10681 
10682  /* call dual simplex for first lp */
10683  retcode = SCIPlpiSolveDual(lp->lpi);
10684  if( retcode == SCIP_LPERROR )
10685  {
10686  *lperror = TRUE;
10687  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10688  }
10689  else
10690  {
10691  SCIP_CALL( retcode );
10692  }
10693  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10694  totalIterations = iterations;
10695 
10696  /* stop timing */
10697  if( lp->diving || lp->probing )
10698  {
10699  if( lp->strongbranchprobing )
10700  SCIPclockStop(stat->strongbranchtime, set);
10701  else
10702  SCIPclockStop(stat->divinglptime, set);
10703  }
10704  else
10705  {
10706  timedelta += SCIPclockGetTime(stat->duallptime);
10707  SCIPclockStop(stat->duallptime, set);
10708  }
10709 
10710  /* count number of iterations */
10711  SCIPstatIncrement(stat, set, lpcount);
10712  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10713  {
10714  if( lp->strongbranchprobing )
10715  {
10716  SCIPstatAdd(stat, set, nlpiterations, iterations);
10717  }
10718  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10719  {
10720  SCIPstatIncrement(stat, set, ndualresolvelps);
10721  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10722  }
10723  if( lp->diving || lp->probing )
10724  {
10725  if( lp->strongbranchprobing )
10726  {
10727  SCIPstatIncrement(stat, set, nsbdivinglps);
10728  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10729  }
10730  else
10731  {
10732  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10733  SCIPstatIncrement(stat, set, ndivinglps);
10734  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10735  }
10736  }
10737  else
10738  {
10739  SCIPstatIncrement(stat, set, nduallps);
10740  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10741  }
10742  }
10743  else
10744  {
10745  if ( ! lp->diving && ! lp->probing )
10746  {
10747  SCIPstatIncrement(stat, set, ndualzeroitlps);
10748  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10749  }
10750  }
10751  lexIterations = 0;
10752 
10753  /* search for lexicographically minimal optimal solution */
10754  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10755  {
10756  SCIP_Bool chooseBasic;
10757  SCIP_Real* primsol;
10758  SCIP_Real* dualsol;
10759  SCIP_Real* redcost;
10760  int* cstat;
10761  int* rstat;
10762  SCIP_Real* newobj;
10763  SCIP_Real* newlb;
10764  SCIP_Real* newub;
10765  SCIP_Real* newlhs;
10766  SCIP_Real* newrhs;
10767  SCIP_Real* oldlb;
10768  SCIP_Real* oldub;
10769  SCIP_Real* oldlhs;
10770  SCIP_Real* oldrhs;
10771  SCIP_Real* oldobj;
10772  SCIP_Bool* fixedc;
10773  SCIP_Bool* fixedr;
10774  int* indcol;
10775  int* indrow;
10776  int* indallcol;
10777  int* indallrow;
10778  int nDualDeg;
10779  int r, c;
10780  int cntcol;
10781  int cntrow;
10782  int nruns;
10783  int pos;
10784 
10785  chooseBasic = set->lp_lexdualbasic;
10786 
10787  /* start timing */
10788  SCIPclockStart(stat->lexduallptime, set);
10789 
10790  /* get all solution information */
10791  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10792  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10793  if( chooseBasic )
10794  {
10795  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10796  }
10797  else
10798  primsol = NULL;
10799 
10800  /* get basic and nonbasic information */
10801  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10802  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10803 
10804  /* save bounds, lhs/rhs, and objective */
10805  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10806  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10807  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10808  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10809  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10810  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10811  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10812  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10813 
10814  /* get storage for several arrays */
10815  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10816  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10817  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10818 
10819  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10820  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10821  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10822 
10823  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10824  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10825 
10826  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10827  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10828 
10829  /* initialize: set objective to 0, get fixed variables */
10830  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10831  for( c = 0; c < lp->nlpicols; ++c )
10832  {
10833  newobj[c] = 0.0;
10834  indallcol[c] = c;
10835  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10836  fixedc[c] = TRUE;
10837  else
10838  fixedc[c] = FALSE;
10839  }
10840 
10841  /* initialize: get fixed slack variables */
10842  for( r = 0; r < lp->nlpirows; ++r )
10843  {
10844  indallrow[r] = r;
10845  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10846  fixedr[r] = TRUE;
10847  else
10848  fixedr[r] = FALSE;
10849  }
10850 
10851 #ifdef DEBUG_LEXDUAL
10852  {
10853  int j;
10854 
10855  if( !chooseBasic )
10856  {
10857  assert(primsol == NULL);
10858  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10859  }
10860  assert(primsol != NULL);
10861  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10862  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10863 
10864  for( j = 0; j < lp->nlpicols; ++j )
10865  {
10866  if( fixedc[j] )
10867  {
10868  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10869  }
10870  else
10871  {
10872  char type;
10873  switch( (SCIP_BASESTAT) cstat[j] )
10874  {
10875  case SCIP_BASESTAT_LOWER:
10876  type = 'l';
10877  break;
10878  case SCIP_BASESTAT_UPPER:
10879  type = 'u';
10880  break;
10881  case SCIP_BASESTAT_ZERO:
10882  type = 'z';
10883  break;
10884  case SCIP_BASESTAT_BASIC:
10885  type = 'b';
10886  break;
10887  default:
10888  type = '?';
10889  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10890  SCIPABORT();
10891  }
10892  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10893  }
10894  }
10895  SCIPsetDebugMsg(set, "\n\n");
10896 
10897  if( !chooseBasic )
10898  {
10899  SCIPsetFreeBufferArray(set, &primsol);
10900  assert(primsol == NULL);
10901  }
10902  }
10903 #endif
10904 
10905  /* perform lexicographic rounds */
10906  pos = -1;
10907  nruns = 0;
10908  rounds = 0;
10909  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10910  do
10911  {
10912  int oldpos;
10913 
10914  /* get current solution */
10915  if( chooseBasic )
10916  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10917  else
10918  {
10919  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10920  assert(primsol == NULL);
10921  }
10922 
10923  /* get current basis */
10924  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10925 
10926  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10927  nDualDeg = 0;
10928  cntcol = 0;
10929  oldpos = pos;
10930  pos = -1;
10931  for( c = 0; c < lp->nlpicols; ++c )
10932  {
10933  if( !fixedc[c] )
10934  {
10935  /* check whether variable is in basis */
10936  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10937  {
10938  /* store first candidate */
10939  if( pos == -1 && c > oldpos )
10940  {
10941  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10942  pos = c;
10943  }
10944  }
10945  else
10946  {
10947  /* reduced cost == 0 -> possible candidate */
10948  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10949  {
10950  ++nDualDeg;
10951  /* only if we have not yet found a candidate */
10952  if( pos == -1 && c > oldpos )
10953  {
10954  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10955  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10956  {
10957  newlb[cntcol] = oldlb[c];
10958  newub[cntcol] = oldlb[c];
10959  indcol[cntcol++] = c;
10960  fixedc[c] = TRUE;
10961  }
10962  else /* found a non-fixed candidate */
10963  {
10964  if( !chooseBasic )
10965  pos = c;
10966  }
10967  }
10968  }
10969  else
10970  {
10971  /* nonzero reduced cost -> variable can be fixed */
10972  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10973  {
10974  newlb[cntcol] = oldlb[c];
10975  newub[cntcol] = oldlb[c];
10976  }
10977  else
10978  {
10979  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10980  {
10981  newlb[cntcol] = oldub[c];
10982  newub[cntcol] = oldub[c];
10983  }
10984  else
10985  {
10986  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10987  newlb[cntcol] = 0.0;
10988  newub[cntcol] = 0.0;
10989  }
10990  }
10991  indcol[cntcol++] = c;
10992  fixedc[c] = TRUE;
10993  }
10994  }
10995  }
10996  }
10997 
10998  /* check rows */
10999  cntrow = 0;
11000  for( r = 0; r < lp->nlpirows; ++r )
11001  {
11002  if( !fixedr[r] )
11003  {
11004  /* consider only nonbasic rows */
11005  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11006  {
11007  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
11008  if( SCIPsetIsFeasZero(set, dualsol[r]) )
11009  ++nDualDeg;
11010  else
11011  {
11012  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11013  {
11014  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11015  newlhs[cntrow] = oldlhs[r];
11016  newrhs[cntrow] = oldlhs[r];
11017  }
11018  else
11019  {
11020  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11021  newlhs[cntrow] = oldrhs[r];
11022  newrhs[cntrow] = oldrhs[r];
11023  }
11024  indrow[cntrow++] = r;
11025  fixedr[r] = TRUE;
11026  }
11027  }
11028  }
11029  }
11030 
11031  if( nDualDeg > 0 && pos >= 0 )
11032  {
11033  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11034 
11035  /* change objective */
11036  if( nruns == 0 )
11037  {
11038  /* set objective to appropriate unit vector for first run */
11039  newobj[pos] = 1.0;
11040  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11041  }
11042  else
11043  {
11044  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11045  SCIP_Real obj = 1.0;
11046  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11047  }
11048 
11049  /* fix variables */
11050  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11051  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11052 
11053  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11054  retcode = SCIPlpiSolvePrimal(lp->lpi);
11055  if( retcode == SCIP_LPERROR )
11056  {
11057  *lperror = TRUE;
11058  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11059  }
11060  else
11061  {
11062  SCIP_CALL( retcode );
11063  }
11064  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11065  lexIterations += iterations;
11066 
11067 #ifdef DEBUG_LEXDUAL
11068  if( iterations > 0 )
11069  {
11070  int j;
11071 
11072  if( !chooseBasic )
11073  {
11074  assert(primsol == NULL);
11075  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
11076  }
11077  assert(primsol != NULL);
11078  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
11079 
11080  for( j = 0; j < lp->nlpicols; ++j )
11081  {
11082  if( fixedc[j] )
11083  {
11084  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11085  }
11086  else
11087  {
11088  char cstart = '[';
11089  char cend = ']';
11090  char type;
11091 
11092  if(j == pos)
11093  {
11094  cstart = '*';
11095  cend = '*';
11096  }
11097 
11098  switch( (SCIP_BASESTAT) cstat[j] )
11099  {
11100  case SCIP_BASESTAT_LOWER:
11101  type = 'l';
11102  break;
11103  case SCIP_BASESTAT_UPPER:
11104  type = 'u';
11105  break;
11106  case SCIP_BASESTAT_ZERO:
11107  type = 'z';
11108  break;
11109  case SCIP_BASESTAT_BASIC:
11110  type = 'b';
11111  break;
11112  default:
11113  type = '?';
11114  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11115  SCIPABORT();
11116  }
11117  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11118  }
11119  }
11120  SCIPsetDebugMsg(set, "\n\n");
11121 
11122  if( !chooseBasic )
11123  {
11124  SCIPsetFreeBufferArray(set, &primsol);
11125  assert(primsol == NULL);
11126  }
11127  }
11128 #endif
11129 
11130  /* count only as round if iterations have been performed */
11131  if( iterations > 0 )
11132  ++rounds;
11133  ++nruns;
11134  }
11135  }
11136  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11137 
11138  /* reset bounds, lhs/rhs, and obj */
11139  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11140  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11141  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11142 
11143  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
11144  retcode = SCIPlpiSolveDual(lp->lpi);
11145  if( retcode == SCIP_LPERROR )
11146  {
11147  *lperror = TRUE;
11148  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11149  }
11150  else
11151  {
11152  SCIP_CALL( retcode );
11153  }
11154  assert(SCIPlpiIsOptimal(lp->lpi));
11155  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11156  lexIterations += iterations;
11157 
11158  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11159 
11160  /* count number of iterations */
11161  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11162  SCIPstatIncrement(stat, set, nlps);
11163 
11164  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11165  {
11166  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11167  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11168  {
11169  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11170  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11171  }
11172  SCIPstatIncrement(stat, set, nlexduallps);
11173  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11174 
11175  totalIterations += lexIterations;
11176  }
11177 
11178  /* free space */
11179  SCIPsetFreeBufferArray(set, &newobj);
11180 
11181  SCIPsetFreeBufferArray(set, &fixedr);
11182  SCIPsetFreeBufferArray(set, &fixedc);
11183 
11184  SCIPsetFreeBufferArray(set, &indallrow);
11185  SCIPsetFreeBufferArray(set, &indallcol);
11186 
11187  SCIPsetFreeBufferArray(set, &indrow);
11188  SCIPsetFreeBufferArray(set, &newrhs);
11189  SCIPsetFreeBufferArray(set, &newlhs);
11190 
11191  SCIPsetFreeBufferArray(set, &indcol);
11192  SCIPsetFreeBufferArray(set, &newub);
11193  SCIPsetFreeBufferArray(set, &newlb);
11194 
11195  SCIPsetFreeBufferArray(set, &oldobj);
11196  SCIPsetFreeBufferArray(set, &oldrhs);
11197  SCIPsetFreeBufferArray(set, &oldlhs);
11198  SCIPsetFreeBufferArray(set, &oldub);
11199  SCIPsetFreeBufferArray(set, &oldlb);
11200 
11201  SCIPsetFreeBufferArray(set, &rstat);
11202  SCIPsetFreeBufferArray(set, &cstat);
11203 
11204  SCIPsetFreeBufferArray(set, &redcost);
11205  SCIPsetFreeBufferArray(set, &dualsol);
11206  if( chooseBasic )
11207  SCIPsetFreeBufferArray(set, &primsol);
11208 
11209  /* stop timing */
11210  SCIPclockStop(stat->lexduallptime, set);
11211 
11212  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11213  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11214  }
11216  lp->solisbasic = TRUE;
11217 
11218  if( totalIterations > 0 && !lp->strongbranchprobing )
11219  SCIPstatIncrement(stat, set, nlps);
11220  else
11221  {
11222  if( keepsol && !(*lperror) )
11223  {
11224  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11225  if( lp->validsollp == stat->lpcount-1 )
11226  lp->validsollp = stat->lpcount;
11227  if( lp->validfarkaslp == stat->lpcount-1 )
11228  lp->validfarkaslp = stat->lpcount;
11229  }
11230  }
11231 
11232  return SCIP_OKAY;
11233 }
11234 
11235 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11236 static
11238  SCIP_LP* lp, /**< current LP data */
11239  SCIP_SET* set, /**< global SCIP settings */
11240  SCIP_STAT* stat, /**< problem statistics */
11241  SCIP_Bool crossover, /**< should crossover be performed? */
11242  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11243  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11244  )
11245 {
11246  SCIP_Real timedelta;
11247  SCIP_RETCODE retcode;
11248  int iterations;
11249 
11250  assert(lp != NULL);
11251  assert(lp->flushed);
11252  assert(set != NULL);
11253  assert(stat != NULL);
11254  assert(lperror != NULL);
11255 
11256  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",
11257  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11258  stat->nbarrierlps, stat->ndivinglps);
11259 
11260  *lperror = FALSE;
11261 
11262 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11263  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11264  {
11265  char fname[SCIP_MAXSTRLEN];
11266  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11267  SCIP_CALL( SCIPlpWrite(lp, fname) );
11268  SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11269  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11270  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11271  }
11272 #endif
11273 
11274  /* start timing */
11275  if( lp->diving || lp->probing )
11276  {
11277  if( lp->strongbranchprobing )
11278  SCIPclockStart(stat->strongbranchtime, set);
11279  else
11280  SCIPclockStart(stat->divinglptime, set);
11281 
11282  timedelta = 0.0; /* unused for diving or probing */
11283  }
11284  else
11285  {
11286  SCIPclockStart(stat->barrierlptime, set);
11287  timedelta = -SCIPclockGetTime(stat->barrierlptime);
11288  }
11289 
11290  /* call barrier algorithm */
11291  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11292  if( retcode == SCIP_LPERROR )
11293  {
11294  *lperror = TRUE;
11295  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11296  }
11297  else
11298  {
11299  SCIP_CALL( retcode );
11300  }
11302  lp->solisbasic = crossover;
11303 
11304  /* stop timing */
11305  if( lp->diving || lp->probing )
11306  {
11307  if( lp->strongbranchprobing )
11308  SCIPclockStop(stat->strongbranchtime, set);
11309  else
11310  SCIPclockStop(stat->divinglptime, set);
11311  }
11312  else
11313  {
11314  SCIPclockStop(stat->barrierlptime, set);
11315  timedelta += SCIPclockGetTime(stat->barrierlptime);
11316  }
11317 
11318  /* count number of iterations */
11319  SCIPstatIncrement(stat, set, lpcount);
11320  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11321  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11322  {
11323  if( !lp->strongbranchprobing )
11324  {
11325  SCIPstatIncrement(stat, set, nlps);
11326  SCIPstatAdd(stat, set, nlpiterations, iterations);
11327  }
11328  if( lp->diving || lp->probing )
11329  {
11330  if( lp->strongbranchprobing )
11331  {
11332  SCIPstatIncrement(stat, set, nsbdivinglps);
11333  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11334  }
11335  else
11336  {
11337  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11338  SCIPstatIncrement(stat, set, ndivinglps);
11339  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11340  }
11341  }
11342  else
11343  {
11344  SCIPstatIncrement(stat, set, nbarrierlps);
11345  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11346  }
11347  }
11348  else
11349  {
11350  if ( ! lp->diving && ! lp->probing )
11351  {
11352  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11353  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11354  }
11355 
11356  if( keepsol && !(*lperror) )
11357  {
11358  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11359  if( lp->validsollp == stat->lpcount-1 )
11360  lp->validsollp = stat->lpcount;
11361  if( lp->validfarkaslp == stat->lpcount-1 )
11362  lp->validfarkaslp = stat->lpcount;
11363  }
11364  }
11365 
11366  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11367  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11368 
11369  return SCIP_OKAY;
11370 }
11371 
11372 /** solves the LP with the given algorithm */
11373 static
11375  SCIP_LP* lp, /**< current LP data */
11376  SCIP_SET* set, /**< global SCIP settings */
11377  SCIP_STAT* stat, /**< problem statistics */
11378  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11379  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11380  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11381  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11382  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11383  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11384  )
11385 {
11386  SCIP_Real lptimelimit;
11387  SCIP_Bool success;
11388 
11389  assert(lp != NULL);
11390  assert(lp->flushed);
11391  assert(lperror != NULL);
11392 
11393  /* check if a time limit is set, and set time limit for LP solver accordingly */
11394  lptimelimit = SCIPlpiInfinity(lp->lpi);
11395  if( set->istimelimitfinite )
11396  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11397 
11398  success = FALSE;
11399  if( lptimelimit > 0.0 )
11400  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11401 
11402  if( lptimelimit <= 0.0 || !success )
11403  {
11404  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11405  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11406  *timelimit = TRUE;
11407  return SCIP_OKAY;
11408  }
11409  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11410 
11411  /* call appropriate LP algorithm */
11412  switch( lpalgo )
11413  {
11415  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11416  break;
11417 
11419  /* run dual lexicographic simplex if required */
11420  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11421  {
11422  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11423  }
11424  else
11425  {
11426  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11427  }
11428  break;
11429 
11430  case SCIP_LPALGO_BARRIER:
11431  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11432  break;
11433 
11435  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11436  break;
11437 
11438  default:
11439  SCIPerrorMessage("invalid LP algorithm\n");
11440  return SCIP_INVALIDDATA;
11441  }
11442 
11443  if( !(*lperror) )
11444  {
11445  /* check for primal and dual feasibility */
11447 
11448  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11449  }
11450 
11451  return SCIP_OKAY;
11452 }
11453 
11454 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11455  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11456  */
11457 #define MAXNUMTROUBLELPMSGS 10
11458 
11459 /** prints message about numerical trouble
11460  *
11461  * If message has verblevel at most high and display/verblevel is not full,
11462  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11463  * were printed before in the current run.
11464  */
11465 static
11467  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11468  SCIP_SET* set, /**< global SCIP settings */
11469  SCIP_STAT* stat, /**< problem statistics */
11470  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11471  const char* formatstr, /**< message format string */
11472  ... /**< arguments to format string */
11473  )
11474 {
11475  va_list ap;
11476 
11477  assert(verblevel > SCIP_VERBLEVEL_NONE);
11478  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11479  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11480 
11481  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11482  {
11483  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11484  {
11485  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11487  return;
11488 
11489  /* increase count on messages with verblevel high */
11490  ++stat->nnumtroublelpmsgs ;
11491  }
11492 
11493  /* if messages wouldn't be printed, then return already */
11494  if( verblevel > set->disp_verblevel )
11495  return;
11496  }
11497 
11498  /* print common begin of message */
11499  SCIPmessagePrintInfo(messagehdlr,
11500  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11501  stat->nnodes, stat->nlps);
11502 
11503  /* print individual part of message */
11504  va_start(ap, formatstr); /*lint !e838*/
11505  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11506  va_end(ap);
11507 
11508  /* warn that further messages will be suppressed */
11509  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11510  {
11511  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11512  }
11513 
11514  /* print closing new-line */
11515  SCIPmessagePrintInfo(messagehdlr, "\n");
11516 }
11517 
11518 static
11520  SCIP_LP* lp, /**< current LP data */
11521  SCIP_SET* set, /**< global SCIP settings */
11522  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11523  SCIP_STAT* stat, /**< problem statistics */
11524  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11525  SCIP_Bool* success /**< was instability successfully ignored */
11526  )
11527 {
11528  assert(lp != NULL);
11529  assert(set != NULL);
11530 
11531  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11532 
11533  if( *success )
11534  {
11535  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11536  if( !set->lp_checkdualfeas )
11537  lp->dualfeasible = TRUE;
11538  if( !set->lp_checkprimfeas )
11539  lp->primalchecked = TRUE;
11540  }
11541 
11542  return SCIP_OKAY;
11543 }
11544 
11545 #define FEASTOLTIGHTFAC 0.001
11546 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11547 static
11549  SCIP_LP* lp, /**< current LP data */
11550  SCIP_SET* set, /**< global SCIP settings */
11551  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11552  SCIP_STAT* stat, /**< problem statistics */
11553  SCIP_PROB* prob, /**< problem data */
11554  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11555  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11556  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11557  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11558  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11559  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11560  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11561  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11562  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11563  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11564  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11565  )
11566 {
11567  SCIP_Bool success;
11568  SCIP_Bool success2;
11569  SCIP_Bool success3;
11570  SCIP_Bool simplex;
11571  SCIP_Bool itlimishard;
11572  SCIP_Bool usepolishing;
11573 
11574  assert(lp != NULL);
11575  assert(lp->flushed);
11576  assert(set != NULL);
11577  assert(stat != NULL);
11578  assert(lperror != NULL);
11579  assert(timelimit != NULL);
11580 
11581  *lperror = FALSE;
11582 
11583  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11584  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11585  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11586  * SCIP_LP such that we can return a primal ray
11587  */
11588  if( lp->looseobjvalinf > 0 )
11589  {
11590  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11591  return SCIP_ERROR;
11592  }
11593 
11594  /* check, whether we solve with a simplex algorithm */
11595  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11596 
11597  /* check whether the iteration limit is a hard one */
11598  itlimishard = (itlim == harditlim);
11599 
11600  /* check whether solution polishing should be used */
11601  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11602  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11603  {
11604  usepolishing = TRUE;
11605  if( lp->updateintegrality )
11606  {
11607  SCIP_CALL( lpCopyIntegrality(lp, set) );
11608  }
11609  }
11610  else
11611  usepolishing = FALSE;
11612 
11613  /* solve with given settings (usually fast but imprecise) */
11614  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11615  {
11616  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound, &success) );
11617  }
11618  else
11619  {
11620  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11621  }
11622  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11623  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11624  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11625  &success) );
11626  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11627  : SCIPsetBarrierconvtol(set), &success) );
11628  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11629  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11630  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11631  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11632  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11633  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11634  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11635  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11636  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11637  SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11638  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11639  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11640  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11641  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11642 
11643  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11644 
11645  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11646  * optimal without preforming scaling/change tolerances/presolving */
11647  resolve = FALSE;
11648 
11649  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11650  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11651  return SCIP_OKAY;
11652 
11653  if( !set->lp_checkstability )
11654  {
11655  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11656 
11657  if( success )
11658  return SCIP_OKAY;
11659  }
11660 
11661  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11662  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11663  */
11664 
11665  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11666  * do this only if the iteration limit was not exceeded in the last LP solving call
11667  */
11668  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11669  {
11670  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11671  if( success )
11672  {
11673  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11674  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11675 
11676  /* check for stability */
11677  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11678  return SCIP_OKAY;
11679 
11680  if( !set->lp_checkstability )
11681  {
11682  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11683 
11684  if( success )
11685  return SCIP_OKAY;
11686  }
11687  }
11688  }
11689 
11690  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11691  * and go directly to solving the LP from scratch
11692  */
11693  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11694  {
11695  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11696  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11697  if( success )
11698  {
11699  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11700  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11701  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11702 
11703  /* check for stability */
11704  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11705  return SCIP_OKAY;
11706 
11707  if( !set->lp_checkstability )
11708  {
11709  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11710 
11711  if( success )
11712  return SCIP_OKAY;
11713  }
11714 
11715  /* reset scaling */
11716  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11717  assert(success);
11718  }
11719  }
11720 
11721  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11722  * and go directly to solving the LP from scratch */
11723  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11724  {
11725  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11726  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11727  if( success )
11728  {
11729  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11730  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11731  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11732 
11733  /* check for stability */
11734  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11735  return SCIP_OKAY;
11736 
11737  if( !set->lp_checkstability )
11738  {
11739  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11740 
11741  if( success )
11742  return SCIP_OKAY;
11743  }
11744 
11745  /* reset presolving */
11746  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11747  assert(success);
11748  }
11749  }
11750 
11751  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11752  * do this only if the iteration limit was not exceeded in the last LP solving call
11753  */
11754  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11755  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11756  {
11757  success = FALSE;
11758  if( !tightprimfeastol )
11759  {
11760  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11761  }
11762 
11763  success2 = FALSE;
11764  if( !tightdualfeastol )
11765  {
11766  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11767  }
11768 
11769  success3 = FALSE;
11770  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11771  {
11772  SCIP_CALL( lpSetBarrierconvtol(lp, FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set), &success3) );
11773  }
11774 
11775  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11776  if( success || success2 || success3 )
11777  {
11778  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11779  lpalgoName(lpalgo));
11780  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11781 
11782  /* check for stability */
11783  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11784  return SCIP_OKAY;
11785 
11786  if( !set->lp_checkstability )
11787  {
11788  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11789 
11790  if( success )
11791  return SCIP_OKAY;
11792  }
11793 
11794  /* reset feasibility tolerance */
11795  if( !tightprimfeastol )
11796  {
11797  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11798  }
11799  if( !tightdualfeastol )
11800  {
11801  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11802  }
11803  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11804  {
11805  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11806  }
11807  }
11808  }
11809 
11810  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11811  * the given iteration limit might be a soft one to restrict resolving calls only */
11812  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11813 
11814  /* if not already done, solve again from scratch */
11815  if( !fromscratch && simplex )
11816  {
11817  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11818  if( success )
11819  {
11820  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11821  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11822 
11823  /* check for stability */
11824  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11825  return SCIP_OKAY;
11826 
11827  if( !set->lp_checkstability )
11828  {
11829  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11830 
11831  if( success )
11832  return SCIP_OKAY;
11833  }
11834  }
11835  }
11836 
11837  /* solve again, use other simplex this time */
11838  if( simplex )
11839  {
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  /* solve again with opposite scaling and other simplex */
11857  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11858  if( success )
11859  {
11860  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11861  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11862  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11863 
11864  /* check for stability */
11865  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11866  return SCIP_OKAY;
11867 
11868  if( !set->lp_checkstability )
11869  {
11870  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11871 
11872  if( success )
11873  return SCIP_OKAY;
11874  }
11875 
11876  /* reset scaling */
11877  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11878  assert(success);
11879  }
11880 
11881  /* solve again with opposite presolving and other simplex */
11882  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11883  if( success )
11884  {
11885  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11886  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11887  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11888 
11889  /* check for stability */
11890  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11891  return SCIP_OKAY;
11892 
11893  if( !set->lp_checkstability )
11894  {
11895  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11896 
11897  if( success )
11898  return SCIP_OKAY;
11899  }
11900 
11901  /* reset presolving */
11902  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11903  assert(success);
11904  }
11905 
11906  /* solve again with tighter feasibility tolerance, use other simplex this time */
11907  if( !tightprimfeastol || !tightdualfeastol )
11908  {
11909  success = FALSE;
11910  if( !tightprimfeastol )
11911  {
11912  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11913  }
11914 
11915  success2 = FALSE;
11916  if( !tightdualfeastol )
11917  {
11918  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11919  }
11920 
11921  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11922  if( success || success2 )
11923  {
11924  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11925  lpalgoName(lpalgo));
11926  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11927 
11928  /* check for stability */
11929  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11930  return SCIP_OKAY;
11931 
11932  if( !set->lp_checkstability )
11933  {
11934  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11935 
11936  if( success )
11937  return SCIP_OKAY;
11938  }
11939 
11940  /* reset feasibility tolerance */
11941  if( !tightprimfeastol )
11942  {
11943  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11944  }
11945  if( !tightdualfeastol )
11946  {
11947  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11948  }
11949  SCIP_UNUSED(success);
11950  }
11951  }
11952  }
11953 
11954  /* nothing worked -- exit with an LPERROR */
11955  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11956  *lperror = TRUE;
11957 
11958  return SCIP_OKAY;
11959 }
11960 
11961 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11962 static
11964  SCIP_LP* lp, /**< current LP data */
11965  SCIP_SET* set, /**< global SCIP settings */
11966  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11967  )
11968 {
11969  assert(lp != NULL);
11970  assert(set != NULL);
11971 
11972  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11973  {
11974  if( !lp->adjustlpval && messagehdlr != NULL )
11975  {
11976  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11977  lp->adjustlpval = TRUE;
11978  }
11979  lp->lpobjval = SCIPsetInfinity(set);
11980  }
11981  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11982  {
11983  if( !lp->adjustlpval && messagehdlr != NULL )
11984  {
11985  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11986  lp->adjustlpval = TRUE;
11987  }
11988  lp->lpobjval = -SCIPsetInfinity(set);
11989  }
11990 }
11991 
11992 /** solves the LP with the given algorithm and evaluates return status */
11993 static
11995  SCIP_LP* lp, /**< current LP data */
11996  SCIP_SET* set, /**< global SCIP settings */
11997  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11998  SCIP_STAT* stat, /**< problem statistics */
11999  SCIP_PROB* prob, /**< problem data */
12000  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12001  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12002  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12003  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12004  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12005  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12006  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12007  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12008  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12009  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12010  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12011  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12012  )
12013 {
12014  SCIP_Bool solvedprimal;
12015  SCIP_Bool solveddual;
12016  SCIP_Bool timelimit;
12017  int itlim;
12018 
12019  assert(lp != NULL);
12020  assert(lp->flushed);
12021  assert(set != NULL);
12022  assert(stat != NULL);
12023  assert(lperror != NULL);
12024 
12025  checkLinks(lp);
12026 
12027  solvedprimal = FALSE;
12028  solveddual = FALSE;
12029  timelimit = FALSE;
12030 
12031  /* select the basic iteration limit depending on whether this is a resolving call or not */
12032  itlim = ( resolve ? resolveitlim : harditlim );
12033 
12034  SOLVEAGAIN:
12035  /* call simplex */
12036  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12037  keepsol, &timelimit, lperror) );
12038  resolve = FALSE; /* only the first solve should be counted as resolving call */
12039  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12040  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12041 
12042  /* check, if an error occurred */
12043  if( *lperror )
12044  {
12045  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12046  lp->solved = FALSE;
12048  return SCIP_OKAY;
12049  }
12050 
12051  /* check, if a time limit was exceeded */
12052  if( timelimit )
12053  {
12054  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12055  lp->solved = TRUE;
12057  lp->lpobjval = -SCIPsetInfinity(set);
12058  return SCIP_OKAY;
12059  }
12060 
12061  /* only one should return true */
12062  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
12064 
12065  /* evaluate solution status */
12066  if( SCIPlpiIsOptimal(lp->lpi) )
12067  {
12068  assert(lp->primalfeasible);
12069  assert(lp->dualfeasible);
12071  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12072  adjustLPobjval(lp, set, messagehdlr);
12073 
12074  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
12075  {
12076  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12077  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12079  lp->lpobjval = SCIPsetInfinity(set);
12080  }
12081  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12082  * reached if the LP objective value is greater than the cutoff bound
12083  */
12085  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12086  }
12087  else if( SCIPlpiIsObjlimExc(lp->lpi) )
12088  {
12089  assert(!lpCutoffDisabled(set));
12091  lp->lpobjval = SCIPsetInfinity(set);
12092  }
12093  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12094  {
12095  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12096  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12097  {
12098  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12099  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12100  goto SOLVEAGAIN;
12101  }
12103  lp->lpobjval = SCIPsetInfinity(set);
12104  }
12105  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12106  {
12107  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12108  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12109  {
12110  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12111  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12112  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12113  goto SOLVEAGAIN;
12114  }
12116  lp->lpobjval = -SCIPsetInfinity(set);
12117  }
12118  else if( SCIPlpiIsIterlimExc(lp->lpi) )
12119  {
12120  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12121 
12122  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12123  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12124  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12125  adjustLPobjval(lp, set, NULL);
12126  else
12127  adjustLPobjval(lp, set, messagehdlr);
12128 
12130  }
12131  else if( SCIPlpiIsTimelimExc(lp->lpi) )
12132  {
12133  lp->lpobjval = -SCIPsetInfinity(set);
12135  }
12136  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12137  {
12138  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12139  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12140  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12141  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12142  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12143  goto SOLVEAGAIN;
12144  }
12145  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12146  {
12147  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12148  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12149  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12150  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12151  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12152  goto SOLVEAGAIN;
12153  }
12154  else
12155  {
12156  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12157  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12159  return SCIP_LPERROR;
12160  }
12161 
12162  lp->solved = TRUE;
12163 
12164  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12167 
12168  return SCIP_OKAY;
12169 }
12170 
12171 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12172 static
12174  SCIP_LP* lp, /**< current LP data */
12175  BMS_BLKMEM* blkmem, /**< block memory */
12176  SCIP_SET* set, /**< global SCIP settings */
12177  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12178  SCIP_STAT* stat, /**< problem statistics */
12179  SCIP_PROB* prob, /**< problem data */
12180  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12181  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12182  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12183  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12184  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12185  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12186  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12187  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12188  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12189  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12190  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12191  )
12192 {
12193  SCIP_Bool resolve;
12194  char algo;
12195 
12196  assert(lp != NULL);
12197  assert(set != NULL);
12198  assert(lperror != NULL);
12199 
12200  /* flush changes to the LP solver */
12201  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12202  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12203 
12204  /* select LP algorithm to apply */
12205  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12206  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12207 
12208  switch( algo )
12209  {
12210  case 's':
12211  /* select simplex method */
12212  if( lp->dualfeasible || !lp->primalfeasible )
12213  {
12214  SCIPsetDebugMsg(set, "solving dual LP\n");
12215  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12216  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12217  }
12218  else
12219  {
12220  SCIPsetDebugMsg(set, "solving primal LP\n");
12221  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12222  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12223  }
12224  break;
12225 
12226  case 'p':
12227  SCIPsetDebugMsg(set, "solving primal LP\n");
12228  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12229  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12230  break;
12231 
12232  case 'd':
12233  SCIPsetDebugMsg(set, "solving dual LP\n");
12234  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12235  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12236  break;
12237 
12238  case 'b':
12239  SCIPsetDebugMsg(set, "solving barrier LP\n");
12240  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12241  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12242  break;
12243 
12244  case 'c':
12245  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12246  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12247  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12248  break;
12249 
12250  default:
12251  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12252  return SCIP_PARAMETERWRONGVAL;
12253  }
12254  assert(!(*lperror) || !lp->solved);
12255 
12256  return SCIP_OKAY;
12257 }
12258 
12259 #ifndef NDEBUG
12260 /** checks if the lazy bounds are valid */
12261 static
12263  SCIP_LP* lp, /**< LP data */
12264  SCIP_SET* set /**< global SCIP settings */
12265  )
12266 {
12267  SCIP_COL* col;
12268  int c;
12269 
12270  assert(lp->flushed);
12271 
12272  for( c = 0; c < lp->nlazycols; ++c )
12273  {
12274  col = lp->lazycols[c];
12275 
12276  /* in case lazy bounds are given, check that the primal solution satisfies them */
12277  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12278  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12279  }
12280 }
12281 #else
12282 #define checkLazyBounds(lp, set) /**/
12283 #endif
12284 
12285 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12286  * diving
12287  */
12288 static
12290  SCIP_LP* lp, /**< LP data */
12291  SCIP_SET* set /**< global SCIP settings */
12292  )
12293 {
12294  SCIP_COL* col;
12295  int c;
12296 
12297  assert(lp->nlazycols > 0);
12298 
12299  /* return, if we are in diving, and bounds were already applied
12300  * or if we are not in diving and bounds were not applied
12301  */
12302  if( lp->diving == lp->divinglazyapplied )
12303  return SCIP_OKAY;
12304 
12305  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12306  lp->diving, lp->divinglazyapplied);
12307 
12308  for( c = 0; c < lp->nlazycols; ++c )
12309  {
12310  col = lp->lazycols[c];
12311 
12312  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12313  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12314  {
12315  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12316  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12317  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12318 
12319  /* insert column in the chgcols list (if not already there) */
12320  SCIP_CALL( insertColChgcols(col, set, lp) );
12321 
12322  /* mark bound change in the column */
12323  col->lbchanged = TRUE;
12324  }
12325 
12326  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12327  if( !SCIPsetIsInfinity(set, col->lazyub) )
12328  {
12329  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12330  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12331  || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12332 
12333  /* insert column in the chgcols list (if not already there) */
12334  SCIP_CALL( insertColChgcols(col, set, lp) );
12335 
12336  /* mark bound change in the column */
12337  col->ubchanged = TRUE;
12338  }
12339  }
12340 
12341  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12342  * if not, we just removed them
12343  */
12344  lp->divinglazyapplied = lp->diving;
12345 
12346  return SCIP_OKAY;
12347 }
12348 
12349 /** returns the iteration limit for an LP resolving call */
12350 static
12352  SCIP_SET* set, /**< global SCIP settings */
12353  SCIP_STAT* stat, /**< dynamic problem statistics */
12354  int itlim /**< hard iteration limit */
12355  )
12356 {
12357  /* no limit set or average not yet reliable */
12358  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12359  return itlim;
12360  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12361  if( itlim == -1 )
12362  itlim = INT_MAX;
12363  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12364  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12365  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12366 }
12367 
12368 
12369 
12370 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12372  SCIP_LP* lp, /**< LP data */
12373  SCIP_SET* set, /**< global SCIP settings */
12374  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12375  BMS_BLKMEM* blkmem, /**< block memory buffers */
12376  SCIP_STAT* stat, /**< problem statistics */
12377  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12378  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12379  SCIP_PROB* prob, /**< problem data */
12380  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12381  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12382  * (limit is computed within the method w.r.t. the average LP iterations) */
12383  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12384  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12385  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12386  )
12387 {
12388  SCIP_RETCODE retcode;
12389  SCIP_Bool needprimalray;
12390  SCIP_Bool needdualray;
12391  int harditlim;
12392  int resolveitlim;
12393 
12394  assert(lp != NULL);
12395  assert(prob != NULL);
12396  assert(prob->nvars >= lp->ncols);
12397  assert(lperror != NULL);
12398 
12399  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12400  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12401 
12402  retcode = SCIP_OKAY;
12403  *lperror = FALSE;
12404 
12405  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12406  needprimalray = TRUE;
12407  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12408  || (set->conf_enable && set->conf_useinflp != 'o'));
12409 
12410  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12411  harditlim = (int) MIN(itlim, INT_MAX);
12412  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12413  assert(harditlim == -1 || (resolveitlim <= harditlim));
12414 
12415  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12416  * or removed from the LP (diving was ended)
12417  */
12418  if( lp->nlazycols > 0 )
12419  {
12420  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12421  * first resolve LP?
12422  */
12423  SCIP_CALL( updateLazyBounds(lp, set) );
12424  assert(lp->diving == lp->divinglazyapplied);
12425  }
12426 
12427  /* flush changes to the LP solver */
12428  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12429  assert(lp->flushed);
12430 
12431  /* 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
12432  * to run again anyway, since there seems to be some time left / the time limit was increased
12433  */
12434  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12435  {
12436  SCIP_Bool* primalfeaspointer;
12437  SCIP_Bool* dualfeaspointer;
12438  SCIP_Bool primalfeasible;
12439  SCIP_Bool dualfeasible;
12440  SCIP_Bool farkasvalid;
12441  SCIP_Bool rayfeasible;
12442  SCIP_Bool tightprimfeastol;
12443  SCIP_Bool tightdualfeastol;
12444  SCIP_Bool fromscratch;
12445  SCIP_Bool wasfromscratch;
12446  SCIP_Longint oldnlps;
12447  int fastmip;
12448 
12449  /* set initial LP solver settings */
12450  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12451  tightprimfeastol = FALSE;
12452  tightdualfeastol = FALSE;
12453  fromscratch = FALSE;
12454  primalfeasible = FALSE;
12455  dualfeasible = FALSE;
12456  wasfromscratch = (stat->nlps == 0);
12457 
12458  SOLVEAGAIN:
12459  /* solve the LP */
12460  oldnlps = stat->nlps;
12461  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12462  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12463  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12464  assert(!(*lperror) || !lp->solved);
12465 
12466  /* check for error */
12467  if( *lperror )
12468  {
12469  retcode = SCIP_OKAY;
12470  goto TERMINATE;
12471  }
12472 
12473  /* evaluate solution status */
12474  switch( SCIPlpGetSolstat(lp) )
12475  {
12477  /* get LP solution and possibly check the solution's feasibility again */
12478  if( set->lp_checkprimfeas )
12479  {
12480  primalfeaspointer = &primalfeasible;
12481  lp->primalchecked = TRUE;
12482  }
12483  else
12484  {
12485  /* believe in the primal feasibility of the LP solution */
12486  primalfeasible = TRUE;
12487  primalfeaspointer = NULL;
12488  lp->primalchecked = FALSE;
12489  }
12490  if( set->lp_checkdualfeas )
12491  {
12492  dualfeaspointer = &dualfeasible;
12493  lp->dualchecked = TRUE;
12494  }
12495  else
12496  {
12497  /* believe in the dual feasibility of the LP solution */
12498  dualfeasible = TRUE;
12499  dualfeaspointer = NULL;
12500  lp->dualchecked = FALSE;
12501  }
12502 
12503  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12504 
12505  /* in debug mode, check that lazy bounds (if present) are not violated */
12506  checkLazyBounds(lp, set);
12507 
12508  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12509  {
12510  /* update ages and remove obsolete columns and rows from LP */
12511  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12512  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12513  {
12514  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12515  }
12516 
12517  if( !lp->solved )
12518  {
12519  /* resolve LP after removing obsolete columns and rows */
12520  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12521  aging = FALSE; /* to prevent infinite loops */
12522  goto SOLVEAGAIN;
12523  }
12524  }
12525  if( !primalfeasible || !dualfeasible )
12526  {
12528 
12529  if( (fastmip > 0) && simplex )
12530  {
12531  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12532  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12533  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12534  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12535  fastmip = 0;
12536  goto SOLVEAGAIN;
12537  }
12538  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12539  {
12540  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12541  * tolerance
12542  */
12543  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12544  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12545  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12546  tightprimfeastol = tightprimfeastol || !primalfeasible;
12547  tightdualfeastol = tightdualfeastol || !dualfeasible;
12548  goto SOLVEAGAIN;
12549  }
12550  else if( !fromscratch && !wasfromscratch && simplex )
12551  {
12552  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12553  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12554  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12555  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12556  fromscratch = TRUE;
12557  goto SOLVEAGAIN;
12558  }
12559  else
12560  {
12561  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12562  lp->solved = FALSE;
12564  *lperror = TRUE;
12565  }
12566  }
12567  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12568  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12569  lp->lpsolstat, lp->cutoffbound);
12570  break;
12571 
12573  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12574  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12575  {
12576  if( SCIPlpiHasDualRay(lp->lpi) )
12577  {
12578  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12579  }
12580  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12581  * with the primal simplex due to numerical problems) - treat this case like an LP error
12582  */
12583  else
12584  {
12585  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12586  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12587  lp->solved = FALSE;
12589  farkasvalid = FALSE;
12590  *lperror = TRUE;
12591  }
12592  }
12593  else
12594  farkasvalid = TRUE;
12595 
12596  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12597  if( !farkasvalid && !(*lperror) )
12598  {
12600 
12601  if( (fastmip > 0) && simplex )
12602  {
12603  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12604  * without FASTMIP
12605  */
12606  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12607  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12608  stat->nnodes, stat->nlps);
12609  fastmip = 0;
12610  goto SOLVEAGAIN;
12611  }
12612  else if( !tightdualfeastol )
12613  {
12614  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12615  * solve again with tighter feasibility tolerance
12616  */
12617  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12618  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12619  stat->nnodes, stat->nlps);
12620  tightdualfeastol = TRUE;
12621  goto SOLVEAGAIN;
12622  }
12623  else if( !fromscratch && simplex )
12624  {
12625  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12626  * from scratch
12627  */
12628  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12629  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12630  stat->nnodes, stat->nlps);
12631  fromscratch = TRUE;
12632  goto SOLVEAGAIN;
12633  }
12634  else
12635  {
12636  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12637  * helped forget about the LP at this node and mark it to be unsolved
12638  */
12639  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12640  lp->solved = FALSE;
12642  *lperror = TRUE;
12643  }
12644  }
12645 
12646  break;
12647 
12649  if( set->lp_checkprimfeas )
12650  {
12651  /* get unbounded LP solution and check the solution's feasibility again */
12652  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12653 
12654  lp->primalchecked = TRUE;
12655  }
12656  else
12657  {
12658  /* get unbounded LP solution believing in the feasibility of the LP solution */
12659  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12660 
12661  primalfeasible = TRUE;
12662  rayfeasible = TRUE;
12663  lp->primalchecked = FALSE;
12664  }
12665 
12666  /* in debug mode, check that lazy bounds (if present) are not violated */
12667  checkLazyBounds(lp, set);
12668 
12669  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12670  primalfeasible, rayfeasible);
12671 
12672  if( !primalfeasible || !rayfeasible )
12673  {
12675 
12676  if( (fastmip > 0) && simplex )
12677  {
12678  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12679  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12680  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12681  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12682  fastmip = 0;
12683  goto SOLVEAGAIN;
12684  }
12685  else if( !tightprimfeastol )
12686  {
12687  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12688  * tolerance
12689  */
12690  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12691  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again with tighter primal feasibility tolerance\n",
12692  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12693  tightprimfeastol = TRUE;
12694  goto SOLVEAGAIN;
12695  }
12696  else if( !fromscratch && simplex )
12697  {
12698  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12699  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12700  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12701  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12702  fromscratch = TRUE;
12703  goto SOLVEAGAIN;
12704  }
12705  else
12706  {
12707  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12708  * forget about the LP at this node and mark it to be unsolved
12709  */
12710  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12711  lp->solved = FALSE;
12713  *lperror = TRUE;
12714  }
12715  }
12716 
12717  break;
12718 
12720  assert(!lpCutoffDisabled(set));
12721  /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
12722  * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
12723  * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
12724  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12725  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12726  * FASTMIP and solve again. */
12727  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12728  {
12729  SCIP_LPI* lpi;
12730  SCIP_Real objval;
12731 
12732  lpi = SCIPlpGetLPI(lp);
12733 
12734  assert(lpi != NULL);
12735  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12736  * the assert by using !SCIPsetIsFeasNegative()
12737  */
12738  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12739 
12740  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12741 
12742  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12743  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12744  {
12745  SCIP_Real tmpcutoff;
12746  char tmppricingchar;
12747  SCIP_LPSOLSTAT solstat;
12748 
12749  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12750 
12751  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12752  fromscratch = FALSE;
12753 
12754  /* temporarily disable cutoffbound, which also disables the objective limit */
12755  tmpcutoff = lp->cutoffbound;
12756  lp->cutoffbound = SCIPlpiInfinity(lpi);
12757 
12758  /* set lp pricing strategy to steepest edge */
12759  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12760  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12761 
12762  /* resolve LP with an iteration limit of 1 */
12763  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12764  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12765 
12766  /* reinstall old cutoff bound and lp pricing strategy */
12767  lp->cutoffbound = tmpcutoff;
12768  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12769 
12770  /* get objective value */
12771  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12772 
12773  /* get solution status for the lp */
12774  solstat = SCIPlpGetSolstat(lp);
12775  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12776 
12777  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12778  {
12779  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12780  }
12781 
12782  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12783  fastmip = 0;
12784 
12785  /* the solution is still not exceeding the objective limit and the solving process
12786  * was stopped due to time or iteration limit, solve again with fastmip turned off
12787  */
12788  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12789  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12790  {
12791  assert(!(*lperror));
12792 
12793  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12794  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12795 
12796  /* get objective value */
12797  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12798 
12799  /* get solution status for the lp */
12800  solstat = SCIPlpGetSolstat(lp);
12801 
12802  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12803  }
12804 
12805  /* check for lp errors */
12806  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12807  {
12808  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12809  lp->solved = FALSE;
12811 
12812  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12813  goto TERMINATE;
12814  }
12815 
12816  lp->solved = TRUE;
12817 
12818  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12819  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12820  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12821  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12822  {
12823  /* get LP solution and possibly check the solution's feasibility again */
12824  if( set->lp_checkprimfeas )
12825  {
12826  primalfeaspointer = &primalfeasible;
12827  lp->primalchecked = TRUE;
12828  }
12829  else
12830  {
12831  /* believe in the primal feasibility of the LP solution */
12832  primalfeasible = TRUE;
12833  primalfeaspointer = NULL;
12834  lp->primalchecked = FALSE;
12835  }
12836  if( set->lp_checkdualfeas )
12837  {
12838  dualfeaspointer = &dualfeasible;
12839  lp->dualchecked = TRUE;
12840  }
12841  else
12842  {
12843  /* believe in the dual feasibility of the LP solution */
12844  dualfeasible = TRUE;
12845  dualfeaspointer = NULL;
12846  lp->dualchecked = FALSE;
12847  }
12848 
12849  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12850 
12851  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12852  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12853  {
12854  checkLazyBounds(lp, set);
12855  }
12856 
12857  /* if objective value is larger than the cutoff bound, set solution status to objective
12858  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12859  * this was already done in the lpSolve() method
12860  */
12861  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12862  {
12864  lp->lpobjval = SCIPsetInfinity(set);
12865  }
12866 
12867  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12868  * the cutoffbound; mark the LP to be unsolved
12869  */
12870  if( !primalfeasible || !dualfeasible
12871  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12872  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12873  {
12874  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12875  lp->solved = FALSE;
12877  *lperror = TRUE;
12878  }
12879 
12880  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12881  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12882  lp->lpsolstat, lp->cutoffbound);
12883  }
12884  /* infeasible solution */
12885  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12886  {
12887  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12888 
12889  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12890  {
12891  if( SCIPlpiHasDualRay(lp->lpi) )
12892  {
12893  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12894  }
12895  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12896  * with the primal simplex due to numerical problems) - treat this case like an LP error
12897  */
12898  else
12899  {
12900  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12901  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12902  lp->solved = FALSE;
12904  farkasvalid = FALSE;
12905  *lperror = TRUE;
12906  }
12907  }
12908  else
12909  farkasvalid = TRUE;
12910 
12911  if( !farkasvalid )
12912  {
12914 
12915  if( !tightprimfeastol )
12916  {
12917  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12918  * solve again with tighter feasibility tolerance
12919  */
12920  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12921  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12922  stat->nnodes, stat->nlps);
12923  tightprimfeastol = TRUE;
12924  goto SOLVEAGAIN;
12925  }
12926  else if( simplex )
12927  {
12928  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12929  * from scratch
12930  */
12931  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12932  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12933  stat->nnodes, stat->nlps);
12934  fromscratch = TRUE;
12935  goto SOLVEAGAIN;
12936  }
12937  else
12938  {
12939  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12940  * helped forget about the LP at this node and mark it to be unsolved
12941  */
12942  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12943  lp->solved = FALSE;
12945  *lperror = TRUE;
12946  }
12947  }
12948  }
12949  /* unbounded solution */
12950  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12951  {
12952  if( set->lp_checkprimfeas )
12953  {
12954  /* get unbounded LP solution and check the solution's feasibility again */
12955  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12956 
12957  lp->primalchecked = TRUE;
12958  }
12959  else
12960  {
12961  /* get unbounded LP solution believing in its feasibility */
12962  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12963 
12964  primalfeasible = TRUE;
12965  rayfeasible = TRUE;
12966  lp->primalchecked = FALSE;
12967  }
12968 
12969  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12970 
12971  /* in debug mode, check that lazy bounds (if present) are not violated */
12972  checkLazyBounds(lp, set);
12973 
12974  if( !primalfeasible || !rayfeasible )
12975  {
12976  /* unbounded solution is infeasible (this can happen due to numerical problems):
12977  * forget about the LP at this node and mark it to be unsolved
12978  *
12979  * @todo: like in the default LP solving evaluation, solve without fastmip,
12980  * with tighter feasibility tolerance and from scratch
12981  */
12982  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12983  lp->solved = FALSE;
12985  *lperror = TRUE;
12986  }
12987  }
12988 
12989  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12990  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12992  }
12993  else
12994  {
12995  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12996  }
12997  }
12998  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12999  break;
13000 
13002  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13003  break;
13004 
13006  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13007 
13008  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13009  stat->nclockskipsleft = 0;
13010  if( !SCIPsolveIsStopped(set, stat, FALSE) )
13011  {
13012  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13013  "you might consider switching the clock type of SCIP\n");
13014  stat->status = SCIP_STATUS_TIMELIMIT;
13015  }
13016  break;
13017 
13018  case SCIP_LPSOLSTAT_ERROR:
13020  SCIPerrorMessage("error in LP solver\n");
13021  retcode = SCIP_LPERROR;
13022  goto TERMINATE;
13023 
13024  default:
13025  SCIPerrorMessage("unknown LP solution status\n");
13026  retcode = SCIP_ERROR;
13027  goto TERMINATE;
13028  }
13029  }
13030  assert(!(*lperror) || !lp->solved);
13031 
13032  TERMINATE:
13033  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13034  * may happen that we continue to solve from scratch during strong branching */
13035  if( lp->lpifromscratch )
13036  {
13037  SCIP_Bool success;
13038  (void) lpSetFromscratch(lp, FALSE, &success);
13039  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13040  SCIP_UNUSED(success);
13041  }
13042 
13043  return retcode;
13044 }
13045 
13046 /** gets solution status of current LP */
13048  SCIP_LP* lp /**< current LP data */
13049  )
13050 {
13051  assert(lp != NULL);
13052  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
13053 
13054  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13055 }
13056 
13057 /** gets objective value of current LP
13058  *
13059  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13060  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13061  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13062  */
13064  SCIP_LP* lp, /**< current LP data */
13065  SCIP_SET* set, /**< global SCIP settings */
13066  SCIP_PROB* prob /**< problem data */
13067  )
13068 {
13069  assert(lp != NULL);
13070  assert(lp->solved);
13071  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13072  assert(set != NULL);
13073 
13074  if( !lp->flushed )
13075  return SCIP_INVALID;
13076  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
13077  return lp->lpobjval;
13078  else if( lp->looseobjvalinf > 0 )
13079  return -SCIPsetInfinity(set);
13080  else
13081  {
13082  /* recalculate the loose objective value, if needed */
13083  if( !lp->looseobjvalid )
13084  recomputeLooseObjectiveValue(lp, set, prob);
13085 
13086  return lp->lpobjval + lp->looseobjval;
13087  }
13088 }
13089 
13090 /** gets part of objective value of current LP that results from COLUMN variables only */
13092  SCIP_LP* lp /**< current LP data */
13093  )
13094 {
13095  assert(lp != NULL);
13096  assert(lp->solved);
13097 
13098  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13099 }
13100 
13101 /** gets part of objective value of current LP that results from LOOSE variables only */
13103  SCIP_LP* lp, /**< current LP data */
13104  SCIP_SET* set, /**< global SCIP settings */
13105  SCIP_PROB* prob /**< problem data */
13106  )
13107 {
13108  assert(lp != NULL);
13109  assert(lp->solved);
13110  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13111  assert(set != NULL);
13112 
13113  if( !lp->flushed )
13114  return SCIP_INVALID;
13115  else if( lp->looseobjvalinf > 0 )
13116  return -SCIPsetInfinity(set);
13117  else
13118  return getFiniteLooseObjval(lp, set, prob);
13119 }
13120 
13121 /** remembers the current LP objective value as root solution value */
13123  SCIP_LP* lp, /**< current LP data */
13124  SCIP_SET* set, /**< global SCIP settings */
13125  SCIP_PROB* prob /**< problem data */
13126  )
13127 {
13128  assert(lp != NULL);
13129 
13131  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13132 }
13133 
13134 /** invalidates the root LP solution value */
13136  SCIP_LP* lp /**< current LP data */
13137  )
13138 {
13139  assert(lp != NULL);
13140 
13141  lp->rootlpobjval = SCIP_INVALID;
13143 }
13144 
13145 /** recomputes local and global pseudo objective values */
13147  SCIP_LP* lp, /**< current LP data */
13148  SCIP_SET* set, /**< global SCIP settings */
13149  SCIP_PROB* prob /**< problem data */
13150  )
13151 {
13152  SCIP_VAR** vars;
13153  int nvars;
13154  int v;
13155 
13156  assert(lp != NULL);
13157  assert(set != NULL);
13158  assert(prob != NULL);
13159 
13160  vars = prob->vars;
13161  nvars = prob->nvars;
13162 
13163  lp->glbpseudoobjvalinf = 0;
13164  lp->glbpseudoobjval = 0.0;
13165 
13166  lp->pseudoobjvalinf = 0;
13167  lp->pseudoobjval = 0.0;
13168 
13169  for( v = 0; v < nvars; ++v )
13170  {
13171  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13172 
13173  if( SCIPsetIsPositive(set, obj) )
13174  {
13175  /* update the global pseudo objective value */
13176  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13177  ++(lp->glbpseudoobjvalinf);
13178  else
13179  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13180 
13181  /* update the local pseudo objective value */
13182  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13183  ++(lp->pseudoobjvalinf);
13184  else
13185  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13186  }
13187 
13188  if( SCIPsetIsNegative(set, obj) )
13189  {
13190  /* update the global pseudo objective value */
13191  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13192  ++(lp->glbpseudoobjvalinf);
13193  else
13194  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13195 
13196  /* update the local pseudo objective value */
13197  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13198  ++(lp->pseudoobjvalinf);
13199  else
13200  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13201  }
13202  }
13203 
13204  /* the recomputed values are reliable */
13206  lp->glbpseudoobjvalid = TRUE;
13207  lp->relpseudoobjval = lp->pseudoobjval;
13208  lp->pseudoobjvalid = TRUE;
13209 }
13210 
13211 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13212  * global bound
13213  */
13215  SCIP_LP* lp, /**< current LP data */
13216  SCIP_SET* set, /**< global SCIP settings */
13217  SCIP_PROB* prob /**< problem data */
13218  )
13219 {
13220  assert(lp != NULL);
13221  assert(lp->glbpseudoobjvalinf >= 0);
13222  assert(set != NULL);
13223 
13224  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13225  return -SCIPsetInfinity(set);
13226  else
13227  {
13228  /* recalculate the global pseudo solution value, if needed */
13229  if( !lp->glbpseudoobjvalid )
13230  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13231 
13232  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13233  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13234  return -SCIPsetInfinity(set);
13235 
13236  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13237  return SCIPsetInfinity(set);
13238 
13239  return lp->glbpseudoobjval;
13240  }
13241 }
13242 
13243 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13244  * objective function) local bound
13245  */
13247  SCIP_LP* lp, /**< current LP data */
13248  SCIP_SET* set, /**< global SCIP settings */
13249  SCIP_PROB* prob /**< problem data */
13250  )
13251 {
13252  assert(lp != NULL);
13253  assert(lp->pseudoobjvalinf >= 0);
13254  assert(set != NULL);
13255 
13256  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13257  return -SCIPsetInfinity(set);
13258  else
13259  {
13260  /* recalculate the pseudo solution value, if needed */
13261  if( !lp->pseudoobjvalid )
13262  recomputePseudoObjectiveValue(lp, set, prob);
13263 
13264  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13265  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13266  return -SCIPsetInfinity(set);
13267 
13268  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13269  return SCIPsetInfinity(set);
13270 
13271  return lp->pseudoobjval;
13272  }
13273 }
13274 
13275 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13277  SCIP_LP* lp, /**< current LP data */
13278  SCIP_SET* set, /**< global SCIP settings */
13279  SCIP_PROB* prob, /**< problem data */
13280  SCIP_VAR* var, /**< problem variable */
13281  SCIP_Real oldbound, /**< old value for bound */
13282  SCIP_Real newbound, /**< new value for bound */
13283  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13284  )
13285 {
13286  SCIP_Real pseudoobjval;
13287  int pseudoobjvalinf;
13288  SCIP_Real obj;
13289 
13290  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13291  pseudoobjvalinf = lp->pseudoobjvalinf;
13292  obj = SCIPvarGetObj(var);
13293  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13294  {
13295  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13296  pseudoobjvalinf--;
13297  else
13298  pseudoobjval -= oldbound * obj;
13299  assert(pseudoobjvalinf >= 0);
13300  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13301  pseudoobjvalinf++;
13302  else
13303  pseudoobjval += newbound * obj;
13304  }
13305  assert(pseudoobjvalinf >= 0);
13306 
13307  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13308  return -SCIPsetInfinity(set);
13309  else
13310  return pseudoobjval;
13311 }
13312 
13313 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13314  * perform calculations with interval arithmetic to get an exact lower bound
13315  */
13317  SCIP_LP* lp, /**< current LP data */
13318  SCIP_SET* set, /**< global SCIP settings */
13319  SCIP_VAR* var, /**< problem variable */
13320  SCIP_Real oldbound, /**< old value for bound */
13321  SCIP_Real newbound, /**< new value for bound */
13322  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13323  )
13324 {
13325  SCIP_Real pseudoobjval;
13326  int pseudoobjvalinf;
13327  SCIP_Real obj;
13328 
13329  assert(lp->pseudoobjvalid);
13330 
13331  pseudoobjval = lp->pseudoobjval;
13332  pseudoobjvalinf = lp->pseudoobjvalinf;
13333  obj = SCIPvarGetObj(var);
13334  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13335  {
13336  SCIP_INTERVAL objint;
13337  SCIP_INTERVAL bd;
13338  SCIP_INTERVAL prod;
13339  SCIP_INTERVAL psval;
13340 
13341  SCIPintervalSet(&psval, pseudoobjval);
13342  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13343 
13344  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13345  pseudoobjvalinf--;
13346  else
13347  {
13348  SCIPintervalSet(&bd, oldbound);
13349  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13350  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13351  }
13352  assert(pseudoobjvalinf >= 0);
13353  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13354  pseudoobjvalinf++;
13355  else
13356  {
13357  SCIPintervalSet(&bd, newbound);
13358  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13359  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13360  }
13361 
13362  pseudoobjval = SCIPintervalGetInf(psval);
13363  }
13364  assert(pseudoobjvalinf >= 0);
13365 
13366  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13367  return -SCIPsetInfinity(set);
13368  else
13369  return pseudoobjval;
13370 }
13371 
13372 /** compute the objective delta due the new objective coefficient */
13373 static
13375  SCIP_SET* set, /**< global SCIP settings */
13376  SCIP_Real oldobj, /**< old objective value of variable */
13377  SCIP_Real newobj, /**< new objective value of variable */
13378  SCIP_Real lb, /**< lower bound of variable */
13379  SCIP_Real ub, /**< upper bound of variable */
13380  SCIP_Real* deltaval, /**< pointer to store the delta value */
13381  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13382  )
13383 {
13384  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13385  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13386  assert(!SCIPsetIsInfinity(set, lb));
13387  assert(!SCIPsetIsInfinity(set, -ub));
13388  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13389 
13390  (*deltaval) = 0.0;
13391  (*deltainf) = 0;
13392 
13393  if( SCIPsetIsPositive(set, oldobj) )
13394  {
13395  /* sign of objective did not change */
13396  if( SCIPsetIsPositive(set, newobj) )
13397  {
13398  /* if the bound is finite, calculate the deltaval */
13399  if( !SCIPsetIsInfinity(set, -lb) )
13400  (*deltaval) = lb * (newobj - oldobj);
13401  }
13402  /* sign of objective did change, so the best bound does change */
13403  else if( SCIPsetIsNegative(set, newobj) )
13404  {
13405  if( SCIPsetIsInfinity(set, -lb) )
13406  {
13407  /* old best bound was infinite while new one is not */
13408  if( !SCIPsetIsInfinity(set, ub) )
13409  {
13410  (*deltainf) = -1;
13411  (*deltaval) = ub * newobj;
13412  }
13413  }
13414  else
13415  {
13416  /* new best bound is infinite while old one was not */
13417  if( SCIPsetIsInfinity(set, ub) )
13418  {
13419  (*deltainf) = 1;
13420  (*deltaval) = -lb * oldobj;
13421  }
13422  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13423  else
13424  {
13425  (*deltaval) = (ub * newobj) - (lb * oldobj);
13426  }
13427  }
13428  }
13429  /* new objective is 0.0 */
13430  else
13431  {
13432  if( SCIPsetIsInfinity(set, -lb) )
13433  (*deltainf) = -1;
13434  else
13435  (*deltaval) = -lb * oldobj;
13436  }
13437  }
13438  else if( SCIPsetIsNegative(set, oldobj) )
13439  {
13440  /* sign of objective did not change */
13441  if( SCIPsetIsNegative(set, newobj) )
13442  {
13443  /* if the bound is finite, calculate the deltaval */
13444  if( !SCIPsetIsInfinity(set, ub) )
13445  (*deltaval) = ub * (newobj - oldobj);
13446  }
13447  /* sign of objective did change, so the best bound does change */
13448  else if( SCIPsetIsPositive(set, newobj) )
13449  {
13450  if( SCIPsetIsInfinity(set, ub) )
13451  {
13452  /* old best bound was infinite while new one is not */
13453  if( !SCIPsetIsInfinity(set, -lb) )
13454  {
13455  (*deltainf) = -1;
13456  (*deltaval) = lb * newobj;
13457  }
13458  }
13459  else
13460  {
13461  /* new best bound is infinite while old one was not */
13462  if( SCIPsetIsInfinity(set, -lb) )
13463  {
13464  (*deltainf) = 1;
13465  (*deltaval) = -ub * oldobj;
13466  }
13467  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13468  else
13469  {
13470  (*deltaval) = (lb * newobj) - (ub * oldobj);
13471  }
13472  }
13473  }
13474  /* new objective is 0.0 */
13475  else
13476  {
13477  if( SCIPsetIsInfinity(set, ub) )
13478  (*deltainf) = -1;
13479  else
13480  (*deltaval) = -ub * oldobj;
13481  }
13482  }
13483  /* old objective was 0.0 */
13484  else
13485  {
13486  if( SCIPsetIsNegative(set, newobj) )
13487  {
13488  if( SCIPsetIsInfinity(set, ub) )
13489  (*deltainf) = 1;
13490  else
13491  (*deltaval) = ub * newobj;
13492  }
13493  else if( SCIPsetIsPositive(set, newobj) )
13494  {
13495  if( SCIPsetIsInfinity(set, -lb) )
13496  (*deltainf) = 1;
13497  else
13498  (*deltaval) = lb * newobj;
13499  }
13500  }
13501 }
13502 
13503 /** compute the objective delta due the new lower bound */
13504 static
13506  SCIP_SET* set, /**< global SCIP settings */
13507  SCIP_Real obj, /**< objective value of variable */
13508  SCIP_Real oldlb, /**< old lower bound of variable */
13509  SCIP_Real newlb, /**< new lower bound of variable */
13510  SCIP_Real* deltaval, /**< pointer to store the delta value */
13511  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13512  )
13513 {
13514  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13515  assert(!SCIPsetIsInfinity(set, oldlb));
13516  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13517  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13518 
13519  if( SCIPsetIsInfinity(set, -oldlb) )
13520  {
13521  if( !SCIPsetIsInfinity(set, newlb) )
13522  {
13523  (*deltainf) = -1;
13524  (*deltaval) = newlb * obj;
13525  }
13526  else
13527  {
13528  (*deltainf) = 0;
13529  (*deltaval) = 0.0;
13530  }
13531  }
13532  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13533  {
13534  (*deltainf) = 1;
13535  (*deltaval) = -oldlb * obj;
13536  }
13537  else
13538  {
13539  (*deltainf) = 0;
13540  (*deltaval) = obj * (newlb - oldlb);
13541  }
13542 }
13543 
13544 /** compute the objective delta due the new upper bound */
13545 static
13547  SCIP_SET* set, /**< global SCIP settings */
13548  SCIP_Real obj, /**< objective value of variable */
13549  SCIP_Real oldub, /**< old upper bound of variable */
13550  SCIP_Real newub, /**< new upper bound of variable */
13551  SCIP_Real* deltaval, /**< pointer to store the delta value */
13552  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13553  )
13554 {
13555  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13556  assert(!SCIPsetIsInfinity(set, -oldub));
13557  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13558  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13559 
13560  if( SCIPsetIsInfinity(set, oldub) )
13561  {
13562  if( !SCIPsetIsInfinity(set, -newub) )
13563  {
13564  (*deltainf) = -1;
13565  (*deltaval) = newub * obj;
13566  }
13567  else
13568  {
13569  (*deltainf) = 0;
13570  (*deltaval) = 0.0;
13571  }
13572  }
13573  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13574  {
13575  (*deltainf) = 1;
13576  (*deltaval) = -oldub * obj;
13577  }
13578  else
13579  {
13580  (*deltainf) = 0;
13581  (*deltaval) = obj * (newub - oldub);
13582  }
13583 }
13584 
13585 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13586 static
13588  SCIP_LP* lp, /**< current LP data */
13589  SCIP_SET* set, /**< global SCIP settings */
13590  SCIP_VAR* var, /**< problem variable that changed */
13591  SCIP_Real deltaval, /**< delta value in the objective function */
13592  int deltainf, /**< delta value for the number of variables with infinite best bound */
13593  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13594  SCIP_Bool loose, /**< should the loose objective value be updated? */
13595  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13596  )
13597 {
13598  assert(lp != NULL);
13599  assert(lp->looseobjvalinf >= 0);
13600  assert(lp->pseudoobjvalinf >= 0);
13601  assert(lp->glbpseudoobjvalinf >= 0);
13602 
13603  /* update the pseudo objective value */
13604  if( local )
13605  {
13606  lp->pseudoobjvalinf += deltainf;
13607  if( lp->pseudoobjvalid )
13608  {
13609  lp->pseudoobjval += deltaval;
13610 
13611  /* if the absolute value was increased, this is regarded as reliable,
13612  * otherwise, we check whether we can still trust the updated value
13613  */
13614  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13615  lp->relpseudoobjval = lp->pseudoobjval;
13616  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13617  lp->pseudoobjvalid = FALSE;
13618  }
13619 
13620  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13622  loose = TRUE;
13623  }
13624  /* update the loose objective value */
13625  if( loose )
13626  {
13627  lp->looseobjvalinf += deltainf;
13628 
13629  if( deltaval != 0.0 && lp->looseobjvalid )
13630  {
13631  lp->looseobjval += deltaval;
13632 
13633  /* if the absolute value was increased, this is regarded as reliable,
13634  * otherwise, we check whether we can still trust the updated value
13635  */
13636  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13637  lp->rellooseobjval = lp->looseobjval;
13638  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13639  lp->looseobjvalid = FALSE;
13640  }
13641  }
13642  /* update the root pseudo objective values */
13643  if( global )
13644  {
13645  lp->glbpseudoobjvalinf += deltainf;
13646  if( lp->glbpseudoobjvalid )
13647  {
13648  lp->glbpseudoobjval += deltaval;
13649 
13650  /* if the absolute value was increased, this is regarded as reliable,
13651  * otherwise, we check whether we can still trust the updated value
13652  */
13656  lp->glbpseudoobjvalid = FALSE;
13657  }
13658  }
13659 
13660  assert(lp->looseobjvalinf >= 0);
13661  assert(lp->pseudoobjvalinf >= 0);
13662  assert(lp->glbpseudoobjvalinf >= 0);
13663 }
13664 
13665 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13666  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13667  */
13668 static
13670  SCIP_LP* lp, /**< current LP data */
13671  SCIP_SET* set, /**< global SCIP settings */
13672  SCIP_VAR* var, /**< problem variable that changed */
13673  SCIP_Real oldobj, /**< old objective value of variable */
13674  SCIP_Real oldlb, /**< old objective value of variable */
13675  SCIP_Real oldub, /**< old objective value of variable */
13676  SCIP_Real newobj, /**< new objective value of variable */
13677  SCIP_Real newlb, /**< new objective value of variable */
13678  SCIP_Real newub /**< new objective value of variable */
13679  )
13680 {
13681  SCIP_INTERVAL deltaval;
13682  SCIP_INTERVAL bd;
13683  SCIP_INTERVAL obj;
13684  SCIP_INTERVAL prod;
13685  SCIP_INTERVAL psval;
13686  int deltainf;
13687 
13688  assert(lp != NULL);
13689  assert(lp->pseudoobjvalinf >= 0);
13690  assert(lp->looseobjvalinf >= 0);
13691  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13692  assert(!SCIPsetIsInfinity(set, oldlb));
13693  assert(!SCIPsetIsInfinity(set, -oldub));
13694  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13695  assert(!SCIPsetIsInfinity(set, newlb));
13696  assert(!SCIPsetIsInfinity(set, -newub));
13697  assert(var != NULL);
13698 
13700  {
13701  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13702  return SCIP_INVALIDDATA;
13703  }
13704 
13705  assert(SCIPvarGetProbindex(var) >= 0);
13706 
13707  SCIPintervalSet(&deltaval, 0.0);
13708  deltainf = 0;
13709 
13710  /* subtract old pseudo objective value */
13711  if( oldobj > 0.0 )
13712  {
13713  if( SCIPsetIsInfinity(set, -oldlb) )
13714  deltainf--;
13715  else
13716  {
13717  SCIPintervalSet(&bd, oldlb);
13718  SCIPintervalSet(&obj, oldobj);
13719  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13720  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13721  }
13722  }
13723  else if( oldobj < 0.0 )
13724  {
13725  if( SCIPsetIsInfinity(set, oldub) )
13726  deltainf--;
13727  else
13728  {
13729  SCIPintervalSet(&bd, oldub);
13730  SCIPintervalSet(&obj, oldobj);
13731  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13732  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13733  }
13734  }
13735 
13736  /* add new pseudo objective value */
13737  if( newobj > 0.0 )
13738  {
13739  if( SCIPsetIsInfinity(set, -newlb) )
13740  deltainf++;
13741  else
13742  {
13743  SCIPintervalSet(&bd, newlb);
13744  SCIPintervalSet(&obj, newobj);
13745  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13746  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13747  }
13748  }
13749  else if( newobj < 0.0 )
13750  {
13751  if( SCIPsetIsInfinity(set, newub) )
13752  deltainf++;
13753  else
13754  {
13755  SCIPintervalSet(&bd, newub);
13756  SCIPintervalSet(&obj, newobj);
13757  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13758  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13759  }
13760  }
13761 
13762  /* update the pseudo and loose objective values */
13763  SCIPintervalSet(&psval, lp->pseudoobjval);
13764  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13765  lp->pseudoobjval = SCIPintervalGetInf(psval);
13766  lp->pseudoobjvalinf += deltainf;
13768  {
13769  SCIPintervalSet(&psval, lp->looseobjval);
13770  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13771  lp->looseobjval = SCIPintervalGetInf(psval);
13772  lp->looseobjvalinf += deltainf;
13773  }
13774 
13775  assert(lp->pseudoobjvalinf >= 0);
13776  assert(lp->looseobjvalinf >= 0);
13777 
13778  return SCIP_OKAY;
13779 }
13780 
13781 /** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
13783  SCIP_LP* lp, /**< current LP data */
13784  SCIP_SET* set, /**< global SCIP settings */
13785  SCIP_VAR* var, /**< problem variable that changed */
13786  SCIP_Real oldobj, /**< old objective coefficient of variable */
13787  SCIP_Real newobj /**< new objective coefficient of variable */
13788  )
13789 {
13790  assert(set != NULL);
13791  assert(var != NULL);
13792 
13793  if( set->misc_exactsolve )
13794  {
13795  if( oldobj != newobj ) /*lint !e777*/
13796  {
13797  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13798  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13799  }
13800  }
13801  else
13802  {
13803  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13804  {
13805  SCIP_Real deltaval;
13806  int deltainf;
13807 
13809  assert(SCIPvarGetProbindex(var) >= 0);
13810 
13811  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13812  * domain of the variable are the same
13813  */
13814  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13815  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13816 
13817  /* compute the pseudo objective delta due the new objective coefficient */
13818  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13819 
13820  /* update the local pseudo objective value */
13821  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13822 
13823  /* compute the pseudo objective delta due the new objective coefficient */
13824  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13825 
13826  /* update the global pseudo objective value */
13827  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13828  }
13829  }
13830 
13831  return SCIP_OKAY;
13832 }
13833 
13834 
13835 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13837  SCIP_LP* lp, /**< current LP data */
13838  SCIP_SET* set, /**< global SCIP settings */
13839  SCIP_VAR* var, /**< problem variable that changed */
13840  SCIP_Real oldlb, /**< old lower bound of variable */
13841  SCIP_Real newlb /**< new lower bound of variable */
13842  )
13843 {
13844  assert(set != NULL);
13845  assert(var != NULL);
13846 
13847  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13848  {
13849  SCIP_Real deltaval;
13850  int deltainf;
13851 
13852  /* compute the pseudo objective delta due the new lower bound */
13853  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13854 
13855  /* update the root pseudo objective values */
13856  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13857  }
13858 
13859  return SCIP_OKAY;
13860 }
13861 
13862 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13864  SCIP_LP* lp, /**< current LP data */
13865  SCIP_SET* set, /**< global SCIP settings */
13866  SCIP_VAR* var, /**< problem variable that changed */
13867  SCIP_Real oldlb, /**< old lower bound of variable */
13868  SCIP_Real newlb /**< new lower bound of variable */
13869  )
13870 {
13871  assert(set != NULL);
13872  assert(var != NULL);
13873 
13874  if( set->misc_exactsolve )
13875  {
13876  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13877  {
13878  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13879  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13880  }
13881  }
13882  else
13883  {
13884  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13885  {
13886  SCIP_Real deltaval;
13887  int deltainf;
13888 
13890  assert(SCIPvarGetProbindex(var) >= 0);
13891 
13892  /* compute the pseudo objective delta due the new lower bound */
13893  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13894 
13895  /* update the pseudo and loose objective values */
13896  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13897  }
13898  }
13899 
13900  return SCIP_OKAY;
13901 }
13902 
13903 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13905  SCIP_LP* lp, /**< current LP data */
13906  SCIP_SET* set, /**< global SCIP settings */
13907  SCIP_VAR* var, /**< problem variable that changed */
13908  SCIP_Real oldub, /**< old upper bound of variable */
13909  SCIP_Real newub /**< new upper bound of variable */
13910  )
13911 {
13912  assert(set != NULL);
13913  assert(var != NULL);
13914 
13915  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13916  {
13917  SCIP_Real deltaval;
13918  int deltainf;
13919 
13920  /* compute the pseudo objective delta due the new upper bound */
13921  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13922 
13923  /* update the root pseudo objective values */
13924  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13925  }
13926 
13927  return SCIP_OKAY;
13928 }
13929 
13930 /** updates current pseudo objective value for a change in a variable's upper bound */
13932  SCIP_LP* lp, /**< current LP data */
13933  SCIP_SET* set, /**< global SCIP settings */
13934  SCIP_VAR* var, /**< problem variable that changed */
13935  SCIP_Real oldub, /**< old upper bound of variable */
13936  SCIP_Real newub /**< new upper bound of variable */
13937  )
13938 {
13939  assert(set != NULL);
13940  assert(var != NULL);
13941 
13942  if( set->misc_exactsolve )
13943  {
13944  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13945  {
13946  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13947  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13948  }
13949  }
13950  else
13951  {
13952  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13953  {
13954  SCIP_Real deltaval;
13955  int deltainf;
13956 
13958  assert(SCIPvarGetProbindex(var) >= 0);
13959 
13960  /* compute the pseudo objective delta due the new upper bound */
13961  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13962 
13963  /* update the pseudo and loose objective values */
13964  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13965  }
13966  }
13967 
13968  return SCIP_OKAY;
13969 }
13970 
13971 /** informs LP, that given variable was added to the problem */
13973  SCIP_LP* lp, /**< current LP data */
13974  SCIP_SET* set, /**< global SCIP settings */
13975  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13976  )
13977 {
13978  assert(lp != NULL);
13980  assert(SCIPvarGetProbindex(var) >= 0);
13981 
13982  /* add the variable to the loose objective value sum */
13983  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13984 
13985  /* update the loose variables counter */
13987  lp->nloosevars++;
13988 
13989  return SCIP_OKAY;
13990 }
13991 
13992 /** informs LP, that given variable is to be deleted from the problem */
13994  SCIP_LP* lp, /**< current LP data */
13995  SCIP_SET* set, /**< global SCIP settings */
13996  SCIP_VAR* var /**< variable that will be deleted from the problem */
13997  )
13998 {
13999  assert(lp != NULL);
14001  assert(SCIPvarGetProbindex(var) >= 0);
14002 
14003  /* subtract the variable from the loose objective value sum */
14004  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
14005 
14006  /* update the loose variables counter */
14008  {
14009  SCIPlpDecNLoosevars(lp);
14010  }
14011 
14012  return SCIP_OKAY;
14013 }
14014 
14015 /** informs LP, that given formerly loose problem variable is now a column variable */
14016 static
14018  SCIP_LP* lp, /**< current LP data */
14019  SCIP_SET* set, /**< global SCIP settings */
14020  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14021  )
14022 {
14023  SCIP_Real obj;
14024  SCIP_Real lb;
14025  SCIP_Real ub;
14026 
14027  assert(lp != NULL);
14028  assert(lp->nloosevars > 0);
14029  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14030  assert(SCIPvarGetProbindex(var) >= 0);
14031  assert(lp->looseobjvalinf >= 0);
14032 
14033  obj = SCIPvarGetObj(var);
14034 
14035  /* update loose objective value */
14036  if( SCIPsetIsPositive(set, obj) )
14037  {
14038  lb = SCIPvarGetLbLocal(var);
14039  if( SCIPsetIsInfinity(set, -lb) )
14040  lp->looseobjvalinf--;
14041  else
14042  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14043  }
14044  else if( SCIPsetIsNegative(set, obj) )
14045  {
14046  ub = SCIPvarGetUbLocal(var);
14047  if( SCIPsetIsInfinity(set, ub) )
14048  lp->looseobjvalinf--;
14049  else
14050  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14051  }
14052 
14053  SCIPlpDecNLoosevars(lp);
14054 
14055  assert(lp->looseobjvalinf >= 0);
14056 
14057  return SCIP_OKAY;
14058 }
14059 
14060 /** informs LP, that given formerly loose problem variable is now a column variable
14061  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14062  */
14063 static
14065  SCIP_LP* lp, /**< current LP data */
14066  SCIP_SET* set, /**< global SCIP settings */
14067  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14068  )
14069 {
14070  SCIP_INTERVAL bd;
14071  SCIP_INTERVAL ob;
14072  SCIP_INTERVAL prod;
14073  SCIP_INTERVAL loose;
14074  SCIP_Real obj;
14075  SCIP_Real lb;
14076  SCIP_Real ub;
14077 
14078  assert(lp != NULL);
14079  assert(lp->nloosevars > 0);
14080  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14081  assert(SCIPvarGetProbindex(var) >= 0);
14082 
14083  obj = SCIPvarGetObj(var);
14084 
14085  SCIPintervalSet(&loose, lp->looseobjval);
14086 
14087  /* update loose objective value corresponding to the deletion of variable */
14088  if( obj > 0.0 )
14089  {
14090  lb = SCIPvarGetLbLocal(var);
14091  if( SCIPsetIsInfinity(set, -lb) )
14092  lp->looseobjvalinf--;
14093  else
14094  {
14095  SCIPintervalSet(&bd, lb);
14096  SCIPintervalSet(&ob, obj);
14097  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14098  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14099  }
14100  }
14101  else if( SCIPsetIsNegative(set, obj) )
14102  {
14103  ub = SCIPvarGetUbLocal(var);
14104  if( SCIPsetIsInfinity(set, ub) )
14105  lp->looseobjvalinf--;
14106  else
14107  {
14108  SCIPintervalSet(&bd, ub);
14109  SCIPintervalSet(&ob, obj);
14110  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14111  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14112  }
14113  }
14114  lp->nloosevars--;
14115 
14116  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14117  if( lp->nloosevars == 0 )
14118  {
14119  assert(lp->looseobjvalinf == 0);
14120  lp->looseobjval = 0.0;
14121  }
14122  else
14123  lp->looseobjval = SCIPintervalGetInf(loose);
14124 
14125  return SCIP_OKAY;
14126 }
14127 
14128 /** informs LP, that given formerly loose problem variable is now a column variable */
14130  SCIP_LP* lp, /**< current LP data */
14131  SCIP_SET* set, /**< global SCIP settings */
14132  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14133  )
14134 {
14135  assert(set != NULL);
14136 
14137  if( set->misc_exactsolve )
14138  {
14139  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
14140  }
14141  else
14142  {
14143  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
14144  }
14145 
14146  return SCIP_OKAY;
14147 }
14148 
14149 /** informs LP, that given formerly column problem variable is now again a loose variable */
14150 static
14152  SCIP_LP* lp, /**< current LP data */
14153  SCIP_SET* set, /**< global SCIP settings */
14154  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14155  )
14156 {
14157  SCIP_Real obj;
14158  SCIP_Real lb;
14159  SCIP_Real ub;
14160 
14161  assert(lp != NULL);
14162  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14163  assert(SCIPvarGetProbindex(var) >= 0);
14164  assert(lp->looseobjvalinf >= 0);
14165 
14166  obj = SCIPvarGetObj(var);
14167 
14168  /* update loose objective value corresponding to the addition of variable */
14169  if( SCIPsetIsPositive(set, obj) )
14170  {
14171  lb = SCIPvarGetLbLocal(var);
14172  if( SCIPsetIsInfinity(set, -lb) )
14173  lp->looseobjvalinf++;
14174  else
14175  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14176  }
14177  else if( SCIPsetIsNegative(set, obj) )
14178  {
14179  ub = SCIPvarGetUbLocal(var);
14180  if( SCIPsetIsInfinity(set, ub) )
14181  lp->looseobjvalinf++;
14182  else
14183  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14184  }
14185  lp->nloosevars++;
14186 
14187  assert(lp->looseobjvalinf >= 0);
14188 
14189  return SCIP_OKAY;
14190 }
14191 
14192 /** informs LP, that given formerly column problem variable is now again a loose variable
14193  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14194  */
14195 static
14197  SCIP_LP* lp, /**< current LP data */
14198  SCIP_SET* set, /**< global SCIP settings */
14199  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14200  )
14201 {
14202  SCIP_INTERVAL bd;
14203  SCIP_INTERVAL ob;
14204  SCIP_INTERVAL prod;
14205  SCIP_INTERVAL loose;
14206  SCIP_Real obj;
14207  SCIP_Real lb;
14208  SCIP_Real ub;
14209 
14210  assert(lp != NULL);
14211  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14212  assert(SCIPvarGetProbindex(var) >= 0);
14213 
14214  obj = SCIPvarGetObj(var);
14215 
14216  SCIPintervalSet(&loose, lp->looseobjval);
14217 
14218  /* update loose objective value corresponding to the deletion of variable */
14219  if( obj > 0.0 )
14220  {
14221  lb = SCIPvarGetLbLocal(var);
14222  if( SCIPsetIsInfinity(set, -lb) )
14223  lp->looseobjvalinf++;
14224  else
14225  {
14226  SCIPintervalSet(&bd, lb);
14227  SCIPintervalSet(&ob, obj);
14228  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14229  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14230  }
14231  }
14232  else if( SCIPsetIsNegative(set, obj) )
14233  {
14234  ub = SCIPvarGetUbLocal(var);
14235  if( SCIPsetIsInfinity(set, ub) )
14236  lp->looseobjvalinf++;
14237  else
14238  {
14239  SCIPintervalSet(&bd, ub);
14240  SCIPintervalSet(&ob, obj);
14241  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14242  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14243  }
14244  }
14245  lp->nloosevars++;
14246 
14247  lp->looseobjval = SCIPintervalGetInf(loose);
14248 
14249  return SCIP_OKAY;
14250 }
14251 
14252 /** informs LP, that given formerly column problem variable is now again a loose variable */
14254  SCIP_LP* lp, /**< current LP data */
14255  SCIP_SET* set, /**< global SCIP settings */
14256  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14257  )
14258 {
14259  assert(set != NULL);
14260 
14261  if( set->misc_exactsolve )
14262  {
14263  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14264  }
14265  else
14266  {
14267  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14268  }
14269 
14270  return SCIP_OKAY;
14271 }
14272 
14273 /** decrease the number of loose variables by one */
14275  SCIP_LP* lp /**< current LP data */
14276  )
14277 {
14278  assert(lp != NULL);
14279  assert(lp->nloosevars > 0);
14280 
14281  lp->nloosevars--;
14282 
14283  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14284  if( lp->nloosevars == 0 )
14285  {
14286  assert(lp->looseobjvalinf == 0);
14287  lp->looseobjval = 0.0;
14288  }
14289 }
14290 
14291 /** stores the LP solution in the columns and rows */
14293  SCIP_LP* lp, /**< current LP data */
14294  SCIP_SET* set, /**< global SCIP settings */
14295  SCIP_STAT* stat, /**< problem statistics */
14296  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14297  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14298  )
14299 {
14300  SCIP_COL** lpicols;
14301  SCIP_ROW** lpirows;
14302  SCIP_Real* primsol;
14303  SCIP_Real* dualsol;
14304  SCIP_Real* activity;
14305  SCIP_Real* redcost;
14306  SCIP_Real primalbound;
14307  SCIP_Real dualbound;
14308  SCIP_Bool stillprimalfeasible;
14309  SCIP_Bool stilldualfeasible;
14310  int* cstat;
14311  int* rstat;
14312  SCIP_Longint lpcount;
14313  int nlpicols;
14314  int nlpirows;
14315  int c;
14316  int r;
14317 
14318  assert(lp != NULL);
14319  assert(lp->flushed);
14320  assert(lp->solved);
14321  assert(set != NULL);
14322  assert(stat != NULL);
14323  assert(lp->validsollp <= stat->lpcount);
14324 
14325  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14326  * corresponding flag immediately to FALSE to skip all checks
14327  */
14328  if( primalfeasible == NULL )
14329  stillprimalfeasible = FALSE;
14330  else
14331  {
14332  *primalfeasible = TRUE;
14333  stillprimalfeasible = TRUE;
14334  }
14335  if( dualfeasible == NULL )
14336  stilldualfeasible = FALSE;
14337  else
14338  {
14339  *dualfeasible = TRUE;
14340  stilldualfeasible = TRUE;
14341  }
14342 
14343  /* check if the values are already calculated */
14344  if( lp->validsollp == stat->lpcount )
14345  return SCIP_OKAY;
14346  lp->validsollp = stat->lpcount;
14347 
14348  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14349  stat->lpcount, SCIPlpGetSolstat(lp));
14350 
14351  lpicols = lp->lpicols;
14352  lpirows = lp->lpirows;
14353  nlpicols = lp->nlpicols;
14354  nlpirows = lp->nlpirows;
14355  lpcount = stat->lpcount;
14356 
14357  /* get temporary memory */
14358  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14359  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14360  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14361  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14362  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14363  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14364 
14365  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14366  if( lp->solisbasic )
14367  {
14368  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14369  }
14370  else
14371  {
14372  BMSclearMemoryArray(cstat, nlpicols);
14373  BMSclearMemoryArray(rstat, nlpirows);
14374  }
14375 
14376  primalbound = 0.0;
14377  dualbound = 0.0;
14378 
14379  /* copy primal solution and reduced costs into columns */
14380  for( c = 0; c < nlpicols; ++c )
14381  {
14382  assert( 0 <= cstat[c] && cstat[c] < 4 );
14383  lpicols[c]->primsol = primsol[c];
14384  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14385  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14386  lpicols[c]->redcost = redcost[c];
14387  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14388  lpicols[c]->validredcostlp = lpcount;
14389  if( stillprimalfeasible )
14390  {
14391  stillprimalfeasible =
14392  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
14393  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
14394  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14395  }
14396  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14397  {
14398  double compslack;
14399 
14400  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14401  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14402  * variables, which would magnify even the tiniest violation in the dual multiplier
14403  */
14404  if( stilldualfeasible )
14405  {
14406  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14407  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14408  }
14409  if( stilldualfeasible )
14410  {
14411  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14412  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14413  }
14414 
14415  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14416  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14417  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14418  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14419  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14420  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14421  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14422  dualfeasible != NULL ? stilldualfeasible : TRUE);
14423  }
14424  else
14425  {
14426  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14427  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14428  {
14429  lpicols[c]->redcost = 0.0;
14430  }
14431 
14432  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14433  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14434  * bounds, its reduced cost must be zero
14435  */
14436  if( stilldualfeasible
14437  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
14438  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14439  if( stilldualfeasible
14440  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
14441  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14442 
14443  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14444  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14445  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14446  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14447  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14448  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14449  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14450  dualfeasible != NULL ? stilldualfeasible : TRUE);
14451  }
14452 
14453  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14454  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14455  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14456  */
14457  if( stilldualfeasible )
14458  {
14459  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14460  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14461  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14462  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14463  }
14464  }
14465 
14466  /* copy dual solution and activities into rows */
14467  for( r = 0; r < nlpirows; ++r )
14468  {
14469  assert( 0 <= rstat[r] && rstat[r] < 4 );
14470  lpirows[r]->dualsol = dualsol[r];
14471  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14472  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14473  lpirows[r]->validactivitylp = lpcount;
14474  if( stillprimalfeasible )
14475  {
14476  stillprimalfeasible =
14477  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14478  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14479  }
14480  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14481  {
14482  double compslack;
14483 
14484  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14485  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14486  * variables, which would magnify even the tiniest violation in the dual multiplier
14487  */
14488  if( stilldualfeasible )
14489  {
14490  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14491  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14492  }
14493  if( stilldualfeasible )
14494  {
14495  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14496  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14497  }
14498 
14499  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14500  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14501  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14502  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14503  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14504  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14505  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14506  dualfeasible != NULL ? stilldualfeasible : TRUE);
14507  }
14508  else
14509  {
14510  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14511  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14512  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14513  */
14514  if( stilldualfeasible &&
14515  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
14516  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14517  if( stilldualfeasible &&
14518  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
14519  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14520 
14521  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14522  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14523  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14524  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14525  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14526  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14527  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14528  dualfeasible != NULL ? stilldualfeasible : TRUE);
14529  }
14530 
14531  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14532  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14533  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14534  */
14535  if( stilldualfeasible )
14536  {
14537  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14538  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14539  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14540  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14541  }
14542  }
14543 
14544  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14545  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14546  * infinity
14547  */
14548  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14549  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14550  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14551  {
14552  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14553  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14554  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14555  }
14556 
14557  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14558  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14559  */
14560  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14561  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14562  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14563  {
14564  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14565  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14566  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14567  }
14568 
14569  if( primalfeasible != NULL )
14570  *primalfeasible = stillprimalfeasible;
14571  if( dualfeasible != NULL )
14572  *dualfeasible = stilldualfeasible;
14573 
14574  /* free temporary memory */
14575  SCIPsetFreeBufferArray(set, &rstat);
14576  SCIPsetFreeBufferArray(set, &cstat);
14577  SCIPsetFreeBufferArray(set, &redcost);
14578  SCIPsetFreeBufferArray(set, &activity);
14579  SCIPsetFreeBufferArray(set, &dualsol);
14580  SCIPsetFreeBufferArray(set, &primsol);
14581 
14582  return SCIP_OKAY;
14583 }
14584 
14585 /** stores LP solution with infinite objective value in the columns and rows */
14587  SCIP_LP* lp, /**< current LP data */
14588  SCIP_SET* set, /**< global SCIP settings */
14589  SCIP_STAT* stat, /**< problem statistics */
14590  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14591  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14592  )
14593 {
14594  SCIP_COL** lpicols;
14595  SCIP_ROW** lpirows;
14596  SCIP_Real* primsol;
14597  SCIP_Real* activity;
14598  SCIP_Real* ray;
14599  SCIP_Real rayobjval;
14600  SCIP_Real rayscale;
14601  SCIP_Longint lpcount;
14602  SCIP_COL* col;
14603  int nlpicols;
14604  int nlpirows;
14605  int c;
14606  int r;
14607 
14608  assert(lp != NULL);
14609  assert(lp->flushed);
14610  assert(lp->solved);
14611  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14612  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14613  assert(set != NULL);
14614  assert(stat != NULL);
14615  assert(lp->validsollp <= stat->lpcount);
14616 
14617  if( primalfeasible != NULL )
14618  *primalfeasible = TRUE;
14619  if( rayfeasible != NULL )
14620  *rayfeasible = TRUE;
14621 
14622  /* check if the values are already calculated */
14623  if( lp->validsollp == stat->lpcount )
14624  return SCIP_OKAY;
14625 
14626  /* check if the LP solver is able to provide a primal unbounded ray */
14627  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14628  {
14629  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14630  return SCIP_LPERROR;
14631  }
14632 
14633  lp->validsollp = stat->lpcount;
14634 
14635  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14636 
14637  /* get temporary memory */
14638  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14639  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14640  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14641 
14642  /* get primal unbounded ray */
14643  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14644 
14645  lpicols = lp->lpicols;
14646  lpirows = lp->lpirows;
14647  nlpicols = lp->nlpicols;
14648  nlpirows = lp->nlpirows;
14649  lpcount = stat->lpcount;
14650 
14651  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14652  rayobjval = 0.0;
14653  for( c = 0; c < nlpicols; ++c )
14654  {
14655  assert(lpicols[c] != NULL);
14656  assert(lpicols[c]->var != NULL);
14657 
14658  col = lpicols[c];
14659 
14660  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14661  if( rayfeasible != NULL )
14662  {
14663  *rayfeasible = *rayfeasible
14664  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14665  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14666  }
14667 
14668  if( ! SCIPsetIsZero(set, ray[c]) )
14669  rayobjval += ray[c] * col->obj;
14670 
14671  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14672  * heuristically try to construct a primal solution.
14673  */
14674  primsol[c] = 0.0;
14675  if( SCIPsetIsFeasZero(set, ray[c]) )
14676  {
14677  /* if the ray component is 0, we try to satisfy as many rows as possible */
14678  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14679  primsol[c] = col->lb;
14680  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14681  primsol[c] = col->ub;
14682  }
14683 
14684  /* make sure we respect the bounds */
14685  primsol[c] = MAX(primsol[c], col->lb);
14686  primsol[c] = MIN(primsol[c], col->ub);
14687 
14688  assert( SCIPsetIsFeasGE(set, primsol[c], col->lb) && SCIPsetIsFeasGE(set, primsol[c], col->lb) );
14689  }
14690 
14691  /* check feasibility of heuristic solution and compute activity */
14692  for( r = 0; r < nlpirows; ++r )
14693  {
14694  SCIP_Real act = 0.0;
14695  SCIP_ROW* row;
14696 
14697  row = lpirows[r];
14698  assert( row != NULL );
14699 
14700  for( c = 0; c < row->nlpcols; ++c )
14701  {
14702  col = row->cols[c];
14703 
14704  assert( col != NULL );
14705  assert( col->lppos >= 0 );
14706  assert( row->linkpos[c] >= 0 );
14707  assert( primsol[col->lppos] < SCIP_INVALID );
14708 
14709  act += row->vals[c] * primsol[col->lppos];
14710  }
14711 
14712  if( row->nunlinked > 0 )
14713  {
14714  for( c = row->nlpcols; c < row->len; ++c )
14715  {
14716  col = row->cols[c];
14717 
14718  assert( col != NULL );
14719 
14720  if( col->lppos >= 0 )
14721  act += row->vals[c] * primsol[col->lppos];
14722  }
14723  }
14724 
14725  /* check feasibility */
14726  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPsetIsFeasLT(set, act, row->lhs) ) ||
14727  (! SCIPsetIsInfinity(set, row->rhs) && SCIPsetIsFeasGT(set, act, row->rhs) ) )
14728  break;
14729 
14730  activity[r] = act;
14731  }
14732 
14733  /* if heuristic solution is not feasible, try to obtain solution from LPI */
14734  if( r < nlpirows )
14735  {
14736  /* get primal feasible point */
14737  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14738 
14739  /* determine feasibility status */
14740  if( primalfeasible != NULL )
14741  {
14742  for( c = 0; c < nlpicols; ++c )
14743  {
14744  assert( lpicols[c] != NULL );
14745  assert( lpicols[c]->var != NULL );
14746 
14747  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14748  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14749  */
14750  *primalfeasible = *primalfeasible
14751  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14752  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14753  }
14754  }
14755  }
14756  else
14757  {
14758  if( primalfeasible != NULL )
14759  *primalfeasible = TRUE;
14760  }
14761 
14762  if( primalfeasible != NULL && !(*primalfeasible) )
14763  {
14764  /* if the finite point is already infeasible, we do not have to add the ray */
14765  rayscale = 0.0;
14766  }
14767  else if( rayfeasible != NULL && !(*rayfeasible) )
14768  {
14769  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14770  rayscale = 0.0;
14771  }
14772  else if( !SCIPsetIsNegative(set, rayobjval) )
14773  {
14774  /* due to numerical problems, the objective of the ray might be nonnegative,
14775  *
14776  * @todo How to check for negative objective value here?
14777  */
14778  if( rayfeasible != NULL )
14779  {
14780  *rayfeasible = FALSE;
14781  }
14782 
14783  rayscale = 0.0;
14784  }
14785  else
14786  {
14787  assert(rayobjval != 0.0);
14788 
14789  /* scale the ray, such that the resulting point has infinite objective value */
14790  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14791  assert(SCIPsetIsFeasPositive(set, rayscale));
14792 
14793  /* ensure that unbounded point does not violate the bounds of the variables */
14794  for( c = 0; c < nlpicols; ++c )
14795  {
14796  if( SCIPsetIsPositive(set, ray[c]) )
14797  {
14798  if( !SCIPsetIsInfinity(set, primsol[c]) )
14799  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14800  /* if the primsol is infinity, as well as the bound, don't scale the ray to 0 */
14801  else
14802  {
14803  assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
14804  rayscale = MIN(rayscale, 1/ray[c]);
14805  }
14806  }
14807  else if( SCIPsetIsNegative(set, ray[c]) )
14808  {
14809  if( !SCIPsetIsInfinity(set, -primsol[c]) )
14810  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14811  /* if the primsol is infinity, as well as the bound, don't scal the ray to 0 */
14812  else
14813  {
14814  assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
14815  rayscale = MIN(rayscale, -1/ray[c]);
14816  }
14817  }
14818 
14819  assert(SCIPsetIsFeasPositive(set, rayscale));
14820  }
14821  }
14822 
14823  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14824 
14825  /* calculate the unbounded point: x' = x + rayscale * ray */
14826  for( c = 0; c < nlpicols; ++c )
14827  {
14828  if( SCIPsetIsZero(set, ray[c]) )
14829  lpicols[c]->primsol = primsol[c];
14830  else
14831  {
14832  SCIP_Real primsolval;
14833  primsolval = primsol[c] + rayscale * ray[c];
14834  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14835  }
14836  lpicols[c]->redcost = SCIP_INVALID;
14837  lpicols[c]->validredcostlp = -1;
14838  }
14839 
14840  /* transfer solution and check feasibility */
14841  for( r = 0; r < nlpirows; ++r )
14842  {
14843  lpirows[r]->dualsol = SCIP_INVALID;
14844  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14845  lpirows[r]->validactivitylp = lpcount;
14846 
14847  /* check for feasibility of the rows */
14848  if( primalfeasible != NULL )
14849  *primalfeasible = *primalfeasible
14850  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14851  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14852  }
14853 
14854  /* free temporary memory */
14855  SCIPsetFreeBufferArray(set, &ray);
14856  SCIPsetFreeBufferArray(set, &activity);
14857  SCIPsetFreeBufferArray(set, &primsol);
14858 
14859  return SCIP_OKAY;
14860 }
14861 
14862 /** returns primal ray proving the unboundedness of the current LP */
14864  SCIP_LP* lp, /**< current LP data */
14865  SCIP_SET* set, /**< global SCIP settings */
14866  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14867  * so the size of this array should be at least number of active variables
14868  * (all entries have to be initialized to 0 before) */
14869  )
14870 {
14871  SCIP_COL** lpicols;
14872  SCIP_Real* lpiray;
14873  SCIP_VAR* var;
14874  int nlpicols;
14875  int c;
14876 
14877  assert(lp != NULL);
14878  assert(set != NULL);
14879  assert(ray != NULL);
14880  assert(lp->flushed);
14881  assert(lp->solved);
14882  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14883  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14884 
14885  /* check if the LP solver is able to provide a primal unbounded ray */
14886  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14887  {
14888  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14889  return SCIP_LPERROR;
14890  }
14891 
14892  /* get temporary memory */
14893  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14894 
14895  SCIPsetDebugMsg(set, "getting primal ray values\n");
14896 
14897  /* get primal unbounded ray */
14898  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14899 
14900  lpicols = lp->lpicols;
14901  nlpicols = lp->nlpicols;
14902 
14903  /* store the ray values of active problem variables */
14904  for( c = 0; c < nlpicols; c++ )
14905  {
14906  assert(lpicols[c] != NULL);
14907 
14908  var = lpicols[c]->var;
14909  assert(var != NULL);
14910  assert(SCIPvarGetProbindex(var) != -1);
14911  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14912  }
14913 
14914  SCIPsetFreeBufferArray(set, &lpiray);
14915 
14916  return SCIP_OKAY;
14917 }
14918 
14919 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
14920  * lp/checkfarkas = TRUE.
14921  *
14922  * @note the check will not be performed if @p valid is NULL.
14923  */
14925  SCIP_LP* lp, /**< current LP data */
14926  SCIP_SET* set, /**< global SCIP settings */
14927  SCIP_STAT* stat, /**< problem statistics */
14928  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
14929  )
14930 {
14931  SCIP_COL** lpicols;
14932  SCIP_ROW** lpirows;
14933  SCIP_Real* dualfarkas;
14934  SCIP_Real* farkascoefs;
14935  SCIP_Real farkaslhs;
14936  SCIP_Real maxactivity;
14937  SCIP_Bool checkfarkas;
14938  int nlpicols;
14939  int nlpirows;
14940  int c;
14941  int r;
14942 
14943  assert(lp != NULL);
14944  assert(lp->flushed);
14945  assert(lp->solved);
14946  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14947  assert(set != NULL);
14948  assert(stat != NULL);
14949  assert(lp->validfarkaslp <= stat->lpcount);
14950 
14951  if( valid != NULL )
14952  *valid = TRUE;
14953 
14954  /* check if the values are already calculated */
14955  if( lp->validfarkaslp == stat->lpcount )
14956  return SCIP_OKAY;
14957  lp->validfarkaslp = stat->lpcount;
14958 
14959  farkascoefs = NULL;
14960  maxactivity = 0.0;
14961  farkaslhs = 0.0;
14962 
14963  checkfarkas = (set->lp_checkfarkas && valid != NULL);
14964 
14965  /* get temporary memory */
14966  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14967 
14968  if( checkfarkas )
14969  {
14970  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
14971  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
14972  }
14973 
14974  /* get dual Farkas infeasibility proof */
14975  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14976 
14977  lpicols = lp->lpicols;
14978  lpirows = lp->lpirows;
14979  nlpicols = lp->nlpicols;
14980  nlpirows = lp->nlpirows;
14981 
14982  /* store infeasibility proof in rows */
14983  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14984  for( r = 0; r < nlpirows; ++r )
14985  {
14986  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14987  lpirows[r]->dualfarkas = dualfarkas[r];
14988  lpirows[r]->dualsol = SCIP_INVALID;
14989  lpirows[r]->activity = 0.0;
14990  lpirows[r]->validactivitylp = -1L;
14991  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14992 
14993  if( checkfarkas )
14994  {
14995  assert(farkascoefs != NULL);
14996 
14997  /* the infeasibility proof would be invalid if
14998  * (i) dualfarkas[r] > 0 and lhs = -inf
14999  * (ii) dualfarkas[r] < 0 and rhs = inf
15000  * however, due to numerics we accept slightly negative / positive values
15001  */
15002  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15003  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15004  {
15005  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15006  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15007 
15008  *valid = FALSE; /*lint !e613*/
15009 
15010  goto TERMINATE;
15011  }
15012 
15013  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15014  * within tolerances (see above) but slighty positive / negative
15015  */
15016  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15017  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15018  continue;
15019 
15020  /* iterate over all columns and scale with dual solution */
15021  for( c = 0; c < lpirows[r]->len; c++ )
15022  {
15023  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15024 
15025  if( pos == -1 )
15026  continue;
15027 
15028  assert(pos >= 0 && pos < nlpicols);
15029 
15030  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15031  }
15032 
15033  /* the row contributes with its left-hand side to the proof */
15034  if( dualfarkas[r] > 0.0 )
15035  {
15036  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15037 
15038  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
15039  }
15040  /* the row contributes with its right-hand side to the proof */
15041  else if( dualfarkas[r] < 0.0 )
15042  {
15043  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15044 
15045  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
15046  }
15047  }
15048  }
15049 
15050  /* set columns as invalid */
15051  for( c = 0; c < nlpicols; ++c )
15052  {
15053  lpicols[c]->primsol = SCIP_INVALID;
15054  lpicols[c]->redcost = SCIP_INVALID;
15055  lpicols[c]->validredcostlp = -1L;
15056  lpicols[c]->validfarkaslp = -1L;
15057 
15058  if( checkfarkas )
15059  {
15060  assert(farkascoefs != NULL);
15061  assert(SCIPcolGetLPPos(lpicols[c]) == c);
15062 
15063  /* skip coefficients that are too close to zero */
15064  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
15065  continue;
15066 
15067  /* calculate the maximal activity */
15068  if( farkascoefs[c] > 0.0 )
15069  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
15070  else
15071  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
15072  }
15073  }
15074 
15075  /* check whether the farkasproof is valid
15076  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
15077  * in that case, we declare the Farkas proof to be invalid.
15078  */
15079  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
15080  {
15081  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15082 
15083  *valid = FALSE; /*lint !e613*/
15084  }
15085 
15086  TERMINATE:
15087  /* free temporary memory */
15088  if( checkfarkas )
15089  SCIPsetFreeBufferArray(set, &farkascoefs);
15090 
15091  SCIPsetFreeBufferArray(set, &dualfarkas);
15092 
15093  return SCIP_OKAY;
15094 }
15095 
15096 /** get number of iterations used in last LP solve */
15098  SCIP_LP* lp, /**< current LP data */
15099  int* iterations /**< pointer to store the iteration count */
15100  )
15101 {
15102  assert(lp != NULL);
15103 
15104  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15105 
15106  return SCIP_OKAY;
15107 }
15108 
15109 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15110  * resets age of non-zero columns and sharp rows
15111  */
15113  SCIP_LP* lp, /**< current LP data */
15114  SCIP_STAT* stat /**< problem statistics */
15115  )
15116 {
15117  SCIP_COL** lpicols;
15118  SCIP_ROW** lpirows;
15119  int nlpicols;
15120  int nlpirows;
15121  int c;
15122  int r;
15123 
15124  assert(lp != NULL);
15125  assert(lp->flushed);
15126  assert(lp->solved);
15127  assert(lp->nlpicols == lp->ncols);
15128  assert(lp->nlpirows == lp->nrows);
15129  assert(stat != NULL);
15130  assert(lp->validsollp == stat->lpcount);
15131 
15132  SCIPdebugMessage("updating LP ages\n");
15133 
15134  lpicols = lp->lpicols;
15135  lpirows = lp->lpirows;
15136  nlpicols = lp->nlpicols;
15137  nlpirows = lp->nlpirows;
15138 
15139  for( c = 0; c < nlpicols; ++c )
15140  {
15141  assert(lpicols[c] == lp->cols[c]);
15142  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15143  lpicols[c]->age++;
15144  else
15145  lpicols[c]->age = 0;
15146  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15147  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15148  }
15149 
15150  for( r = 0; r < nlpirows; ++r )
15151  {
15152  lpirows[r]->nlpsaftercreation++;
15153  assert(lpirows[r] == lp->rows[r]);
15154 
15155  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15156  {
15157  lpirows[r]->age++;
15158  }
15159  else
15160  {
15161  lpirows[r]->activeinlpcounter++;
15162  lpirows[r]->age = 0;
15163  }
15164  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15165  }
15166 
15167  return SCIP_OKAY;
15168 }
15169 
15170 /* deletes the marked columns from the LP and the LP interface */
15171 static
15173  SCIP_LP* lp, /**< current LP data */
15174  SCIP_SET* set, /**< global SCIP settings */
15175  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15176  )
15177 {
15178  SCIP_COL* col;
15179  int ncols;
15180  int c;
15181 
15182  assert(lp != NULL);
15183  assert(lp->flushed);
15184  assert(lp->ncols == lp->nlpicols);
15185  assert(!lp->diving);
15186  assert(coldstat != NULL);
15187  assert(lp->nlazycols <= lp->ncols);
15188 
15189  ncols = lp->ncols;
15190 
15191  /* delete columns in LP solver */
15192  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15193 
15194  /* update LP data respectively */
15195  for( c = 0; c < ncols; ++c )
15196  {
15197  col = lp->cols[c];
15198  assert(col != NULL);
15199  assert(col == lp->lpicols[c]);
15200  assert(coldstat[c] <= c);
15201  col->lppos = coldstat[c];
15202  if( coldstat[c] == -1 )
15203  {
15204  assert(col->removable);
15205 
15206  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15207  * function vector norms
15208  */
15209  markColDeleted(col);
15210  colUpdateDelLP(col, set);
15211  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15212  col->lpdepth = -1;
15213 
15214  lp->cols[c] = NULL;
15215  lp->lpicols[c] = NULL;
15216  lp->ncols--;
15217  lp->nremovablecols--;
15218  lp->nlpicols--;
15219  }
15220  else if( coldstat[c] < c )
15221  {
15222  assert(lp->cols[coldstat[c]] == NULL);
15223  assert(lp->lpicols[coldstat[c]] == NULL);
15224  lp->cols[coldstat[c]] = col;
15225  lp->lpicols[coldstat[c]] = col;
15226  lp->cols[coldstat[c]]->lppos = coldstat[c];
15227  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15228  lp->cols[c] = NULL;
15229  lp->lpicols[c] = NULL;
15230  }
15231  }
15232 
15233  /* remove columns which are deleted from the lazy column array */
15234  c = 0;
15235  while( c < lp->nlazycols )
15236  {
15237  if( lp->lazycols[c]->lpipos < 0 )
15238  {
15239  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15240  lp->nlazycols--;
15241  }
15242  else
15243  c++;
15244  }
15245 
15246  /* mark LP to be unsolved */
15247  if( lp->ncols < ncols )
15248  {
15249  assert(lp->ncols == lp->nlpicols);
15250  assert(lp->nchgcols == 0);
15251  assert(lp->flushed);
15252 
15253  lp->lpifirstchgcol = lp->nlpicols;
15254 
15255  /* mark the current solution invalid */
15256  lp->solved = FALSE;
15257  lp->primalfeasible = FALSE;
15258  lp->primalchecked = FALSE;
15259  lp->lpobjval = SCIP_INVALID;
15261  }
15262 
15263  checkLazyColArray(lp, set);
15264  checkLinks(lp);
15265 
15266  return SCIP_OKAY;
15267 }
15268 
15269 /* deletes the marked rows from the LP and the LP interface */
15270 static
15272  SCIP_LP* lp, /**< current LP data */
15273  BMS_BLKMEM* blkmem, /**< block memory buffers */
15274  SCIP_SET* set, /**< global SCIP settings */
15275  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15276  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15277  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15278  )
15279 {
15280  SCIP_ROW* row;
15281  int nrows;
15282  int r;
15283 
15284  assert(lp != NULL);
15285  assert(lp->flushed);
15286  assert(lp->nrows == lp->nlpirows);
15287  assert(!lp->diving);
15288  assert(rowdstat != NULL);
15289 
15290  nrows = lp->nrows;
15291 
15292  /* delete rows in LP solver */
15293  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15294 
15295  /* update LP data respectively */
15296  for( r = 0; r < nrows; ++r )
15297  {
15298  row = lp->rows[r];
15299  assert(row == lp->lpirows[r]);
15300  assert(rowdstat[r] <= r);
15301  assert(row != NULL);
15302  row->lppos = rowdstat[r];
15303  if( rowdstat[r] == -1 )
15304  {
15305  if( row->removable )
15306  lp->nremovablerows--;
15307 
15308  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15309  markRowDeleted(row);
15310  rowUpdateDelLP(row);
15311  row->lpdepth = -1;
15312 
15313  /* check, if row deletion events are tracked
15314  * if so, issue ROWDELETEDLP event
15315  */
15316  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15317  {
15318  SCIP_EVENT* event;
15319 
15320  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15321  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15322  }
15323 
15324  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15325  SCIProwUnlock(lp->rows[r]);
15326  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15327  assert(lp->lpirows[r] == NULL);
15328  assert(lp->rows[r] == NULL);
15329  lp->nrows--;
15330  lp->nlpirows--;
15331  }
15332  else if( rowdstat[r] < r )
15333  {
15334  assert(lp->rows[rowdstat[r]] == NULL);
15335  assert(lp->lpirows[rowdstat[r]] == NULL);
15336  lp->rows[rowdstat[r]] = row;
15337  lp->lpirows[rowdstat[r]] = row;
15338  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15339  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15340  lp->rows[r] = NULL;
15341  lp->lpirows[r] = NULL;
15342  }
15343  }
15344 
15345  /* mark LP to be unsolved */
15346  if( lp->nrows < nrows )
15347  {
15348  assert(lp->nrows == lp->nlpirows);
15349  assert(lp->nchgrows == 0);
15350  assert(lp->flushed);
15351 
15352  lp->lpifirstchgrow = lp->nlpirows;
15353 
15354  /* mark the current solution invalid */
15355  lp->solved = FALSE;
15356  lp->dualfeasible = FALSE;
15357  lp->dualchecked = FALSE;
15358  lp->lpobjval = SCIP_INVALID;
15360  }
15361 
15362  checkLinks(lp);
15363 
15364  return SCIP_OKAY;
15365 }
15366 
15367 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15368 static
15370  SCIP_LP* lp, /**< current LP data */
15371  SCIP_SET* set, /**< global SCIP settings */
15372  SCIP_STAT* stat, /**< problem statistics */
15373  int firstcol /**< first column to check for clean up */
15374  )
15375 {
15376  SCIP_COL** cols;
15377 #ifndef NDEBUG
15378  SCIP_COL** lpicols;
15379 #endif
15380  int* coldstat;
15381  int ncols;
15382  int ndelcols;
15383  int c;
15384 
15385  assert(lp != NULL);
15386  assert(lp->flushed);
15387  assert(lp->ncols == lp->nlpicols);
15388  assert(lp->nremovablecols <= lp->ncols);
15389  assert(!lp->diving);
15390  assert(set != NULL);
15391  assert(stat != NULL);
15392 
15393  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15394  return SCIP_OKAY;
15395 
15396  ncols = lp->ncols;
15397  cols = lp->cols;
15398 #ifndef NDEBUG
15399  lpicols = lp->lpicols;
15400 #endif
15401 
15402  /* get temporary memory */
15403  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15404 
15405  /* mark obsolete columns to be deleted */
15406  ndelcols = 0;
15407  BMSclearMemoryArray(coldstat, ncols);
15408  for( c = firstcol; c < ncols; ++c )
15409  {
15410  assert(cols[c] == lpicols[c]);
15411  assert(cols[c]->lppos == c);
15412  assert(cols[c]->lpipos == c);
15413  if( cols[c]->removable
15414  && 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 */
15415  && cols[c]->age > set->lp_colagelimit
15417  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15418  {
15419  assert(cols[c]->primsol == 0.0);
15420  coldstat[c] = 1;
15421  ndelcols++;
15422  cols[c]->obsoletenode = stat->nnodes;
15423  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15424  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15425  }
15426  }
15427 
15428  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15429 
15430  /* delete the marked columns in the LP solver interface, update the LP respectively */
15431  if( ndelcols > 0 )
15432  {
15433  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15434  }
15435  assert(lp->ncols == ncols - ndelcols);
15436 
15437  /* release temporary memory */
15438  SCIPsetFreeBufferArray(set, &coldstat);
15439 
15440  return SCIP_OKAY;
15441 }
15442 
15443 /** removes all basic rows, that are too old, beginning with the given firstrow */
15444 static
15446  SCIP_LP* lp, /**< current LP data */
15447  BMS_BLKMEM* blkmem, /**< block memory buffers */
15448  SCIP_SET* set, /**< global SCIP settings */
15449  SCIP_STAT* stat, /**< problem statistics */
15450  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15451  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15452  int firstrow /**< first row to check for clean up */
15453  )
15454 {
15455  SCIP_ROW** rows;
15456 #ifndef NDEBUG
15457  SCIP_ROW** lpirows;
15458 #endif
15459  int* rowdstat;
15460  int nrows;
15461  int ndelrows;
15462  int r;
15463 
15464  assert(lp != NULL);
15465  assert(lp->flushed);
15466  assert(lp->nrows == lp->nlpirows);
15467  assert(lp->nremovablerows <= lp->nrows);
15468  assert(!lp->diving);
15469  assert(set != NULL);
15470  assert(stat != NULL);
15471 
15472  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15473  return SCIP_OKAY;
15474 
15475  nrows = lp->nrows;
15476  rows = lp->rows;
15477 #ifndef NDEBUG
15478  lpirows = lp->lpirows;
15479 #endif
15480 
15481  /* get temporary memory */
15482  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15483 
15484  /* mark obsolete rows to be deleted */
15485  ndelrows = 0;
15486  BMSclearMemoryArray(rowdstat, nrows);
15487  for( r = firstrow; r < nrows; ++r )
15488  {
15489  assert(rows[r] == lpirows[r]);
15490  assert(rows[r]->lppos == r);
15491  assert(rows[r]->lpipos == r);
15492  if( rows[r]->removable
15493  && 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 */
15494  && rows[r]->age > set->lp_rowagelimit
15496  {
15497  rowdstat[r] = 1;
15498  ndelrows++;
15499  rows[r]->obsoletenode = stat->nnodes;
15500  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15501  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15502  }
15503  }
15504 
15505  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15506 
15507  /* delete the marked rows in the LP solver interface, update the LP respectively */
15508  if( ndelrows > 0 )
15509  {
15510  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15511  }
15512  assert(lp->nrows == nrows - ndelrows);
15513 
15514  /* release temporary memory */
15515  SCIPsetFreeBufferArray(set, &rowdstat);
15516 
15517  return SCIP_OKAY;
15518 }
15519 
15520 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15522  SCIP_LP* lp, /**< current LP data */
15523  BMS_BLKMEM* blkmem, /**< block memory buffers */
15524  SCIP_SET* set, /**< global SCIP settings */
15525  SCIP_STAT* stat, /**< problem statistics */
15526  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15527  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15528  )
15529 {
15530  assert(lp != NULL);
15531  assert(lp->solved);
15532  assert(!lp->diving);
15534  assert(set != NULL);
15535 
15536  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15537  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15538 
15539  if( lp->firstnewcol < lp->ncols )
15540  {
15541  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15542  }
15543  if( lp->firstnewrow < lp->nrows )
15544  {
15545  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15546  }
15547 
15548  return SCIP_OKAY;
15549 }
15550 
15551 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15553  SCIP_LP* lp, /**< current LP data */
15554  BMS_BLKMEM* blkmem, /**< block memory buffers */
15555  SCIP_SET* set, /**< global SCIP settings */
15556  SCIP_STAT* stat, /**< problem statistics */
15557  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15558  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15559  )
15560 {
15561  assert(lp != NULL);
15562  assert(lp->solved);
15563  assert(!lp->diving);
15565  assert(set != NULL);
15566 
15567  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15568 
15569  if( 0 < lp->ncols )
15570  {
15571  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15572  }
15573  if( 0 < lp->nrows )
15574  {
15575  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15576  }
15577 
15578  return SCIP_OKAY;
15579 }
15580 
15581 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15582 static
15584  SCIP_LP* lp, /**< current LP data */
15585  SCIP_SET* set, /**< global SCIP settings */
15586  SCIP_STAT* stat, /**< problem statistics */
15587  int firstcol /**< first column to check for clean up */
15588  )
15589 {
15590  SCIP_COL** cols;
15591  SCIP_COL** lpicols;
15592  int* coldstat;
15593  int ncols;
15594  int ndelcols;
15595  int c;
15596 
15597  assert(lp != NULL);
15598  assert(lp->flushed);
15599  assert(lp->ncols == lp->nlpicols);
15600  assert(!lp->diving);
15601  assert(stat != NULL);
15602  assert(lp->validsollp == stat->lpcount);
15603  assert(0 <= firstcol && firstcol < lp->ncols);
15604 
15605  if( lp->nremovablecols == 0 || !lp->solisbasic )
15606  return SCIP_OKAY;
15607 
15608  ncols = lp->ncols;
15609  cols = lp->cols;
15610  lpicols = lp->lpicols;
15611 
15612  /* get temporary memory */
15613  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15614 
15615  /* mark unused columns to be deleted */
15616  ndelcols = 0;
15617  BMSclearMemoryArray(coldstat, ncols);
15618  for( c = firstcol; c < ncols; ++c )
15619  {
15620  assert(cols[c] == lpicols[c]);
15621  assert(cols[c]->lppos == c);
15622  assert(cols[c]->lpipos == c);
15623  if( lpicols[c]->removable
15624  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15625  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15626  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15627  {
15628  coldstat[c] = 1;
15629  ndelcols++;
15630  }
15631  }
15632 
15633  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15634 
15635  /* delete the marked columns in the LP solver interface, update the LP respectively */
15636  if( ndelcols > 0 )
15637  {
15638  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15639  }
15640  assert(lp->ncols == ncols - ndelcols);
15641 
15642  /* release temporary memory */
15643  SCIPsetFreeBufferArray(set, &coldstat);
15644 
15645  return SCIP_OKAY;
15646 }
15647 
15648 /** removes all basic rows beginning with the given firstrow */
15649 static
15651  SCIP_LP* lp, /**< current LP data */
15652  BMS_BLKMEM* blkmem, /**< block memory buffers */
15653  SCIP_SET* set, /**< global SCIP settings */
15654  SCIP_STAT* stat, /**< problem statistics */
15655  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15656  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15657  int firstrow /**< first row to check for clean up */
15658  )
15659 {
15660 #ifndef NDEBUG
15661  SCIP_ROW** rows;
15662 #endif
15663  SCIP_ROW** lpirows;
15664  int* rowdstat;
15665  int nrows;
15666  int ndelrows;
15667  int r;
15668 
15669  assert(lp != NULL);
15670  assert(lp->flushed);
15671  assert(lp->ncols == lp->nlpicols);
15672  assert(lp->nrows == lp->nlpirows);
15673  assert(!lp->diving);
15674  assert(stat != NULL);
15675  assert(lp->validsollp == stat->lpcount);
15676  assert(0 <= firstrow && firstrow < lp->nrows);
15677 
15678  if( lp->nremovablerows == 0 || !lp->solisbasic )
15679  return SCIP_OKAY;
15680 
15681 #ifndef NDEBUG
15682  rows = lp->rows;
15683 #endif
15684  nrows = lp->nrows;
15685  lpirows = lp->lpirows;
15686 
15687  /* get temporary memory */
15688  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15689 
15690  /* mark unused rows to be deleted */
15691  ndelrows = 0;
15692  BMSclearMemoryArray(rowdstat, nrows);
15693  for( r = firstrow; r < nrows; ++r )
15694  {
15695  assert(rows[r] == lpirows[r]);
15696  assert(rows[r]->lppos == r);
15697  assert(rows[r]->lpipos == r);
15698  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15699  {
15700  rowdstat[r] = 1;
15701  ndelrows++;
15702  }
15703  }
15704 
15705  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15706 
15707  /* delete the marked rows in the LP solver interface, update the LP respectively */
15708  if( ndelrows > 0 )
15709  {
15710  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15711  }
15712  assert(lp->nrows == nrows - ndelrows);
15713 
15714  /* release temporary memory */
15715  SCIPsetFreeBufferArray(set, &rowdstat);
15716 
15717  return SCIP_OKAY;
15718 }
15719 
15720 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15722  SCIP_LP* lp, /**< current LP data */
15723  BMS_BLKMEM* blkmem, /**< block memory buffers */
15724  SCIP_SET* set, /**< global SCIP settings */
15725  SCIP_STAT* stat, /**< problem statistics */
15726  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15727  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15728  SCIP_Bool root /**< are we at the root node? */
15729  )
15730 {
15731  SCIP_Bool cleanupcols;
15732  SCIP_Bool cleanuprows;
15733 
15734  assert(lp != NULL);
15735  assert(lp->solved);
15736  assert(!lp->diving);
15738  assert(set != NULL);
15739 
15740  /* check, if we want to clean up the columns and rows */
15741  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15742  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15743 
15744  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15745  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15746 
15747  if( cleanupcols && lp->firstnewcol < lp->ncols )
15748  {
15749  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15750  }
15751  if( cleanuprows && lp->firstnewrow < lp->nrows )
15752  {
15753  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15754  }
15755 
15756  return SCIP_OKAY;
15757 }
15758 
15759 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15761  SCIP_LP* lp, /**< current LP data */
15762  BMS_BLKMEM* blkmem, /**< block memory buffers */
15763  SCIP_SET* set, /**< global SCIP settings */
15764  SCIP_STAT* stat, /**< problem statistics */
15765  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15766  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15767  SCIP_Bool root /**< are we at the root node? */
15768  )
15769 {
15770  SCIP_Bool cleanupcols;
15771  SCIP_Bool cleanuprows;
15772 
15773  assert(lp != NULL);
15774  assert(lp->solved);
15775  assert(!lp->diving);
15777  assert(set != NULL);
15778 
15779  /* check, if we want to clean up the columns and rows */
15780  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15781  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15782 
15783  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15784  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15785 
15786  if( cleanupcols && 0 < lp->ncols )
15787  {
15788  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15789  }
15790  if( cleanuprows && 0 < lp->nrows )
15791  {
15792  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15793  }
15794 
15795  return SCIP_OKAY;
15796 }
15797 
15798 /** removes all redundant rows that were added at the current node */
15800  SCIP_LP* lp, /**< current LP data */
15801  BMS_BLKMEM* blkmem, /**< block memory buffers */
15802  SCIP_SET* set, /**< global SCIP settings */
15803  SCIP_STAT* stat, /**< problem statistics */
15804  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15805  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15806  )
15807 {
15808 #ifndef NDEBUG
15809  SCIP_ROW** rows;
15810 #endif
15811  SCIP_ROW** lpirows;
15812  int* rowdstat;
15813  int nrows;
15814  int ndelrows;
15815  int r;
15816 
15817  assert(lp != NULL);
15818  assert(lp->flushed);
15819  assert(lp->ncols == lp->nlpicols);
15820  assert(lp->nrows == lp->nlpirows);
15821  assert(!lp->diving);
15822  assert(stat != NULL);
15823  assert(lp->validsollp == stat->lpcount);
15824  assert(lp->firstnewrow <= lp->nrows);
15825 
15826  if( lp->firstnewrow == lp->nrows )
15827  return SCIP_OKAY;
15828 
15829 #ifndef NDEBUG
15830  rows = lp->rows;
15831 #endif
15832  nrows = lp->nrows;
15833  lpirows = lp->lpirows;
15834 
15835  /* get temporary memory */
15836  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15837 
15838  /* mark redundant rows to be deleted (only delete basic rows!) */
15839  ndelrows = 0;
15840  BMSclearMemoryArray(rowdstat, nrows);
15841  for( r = lp->firstnewrow; r < nrows; ++r )
15842  {
15843  assert(rows[r] == lpirows[r]);
15844  assert(rows[r]->lppos == r);
15845  assert(rows[r]->lpipos == r);
15846  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15847  && SCIProwIsRedundant(lpirows[r], set, stat) )
15848  {
15849  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15850  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15851  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15852  rowdstat[r] = 1;
15853  ndelrows++;
15854  }
15855  }
15856 
15857  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15858 
15859  /* delete the marked rows in the LP solver interface, update the LP respectively */
15860  if( ndelrows > 0 )
15861  {
15862  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15863  }
15864  assert(lp->nrows == nrows - ndelrows);
15865 
15866  /* release temporary memory */
15867  SCIPsetFreeBufferArray(set, &rowdstat);
15868 
15869  return SCIP_OKAY;
15870 }
15871 
15872 /** initiates LP diving */
15874  SCIP_LP* lp, /**< current LP data */
15875  BMS_BLKMEM* blkmem, /**< block memory */
15876  SCIP_SET* set, /**< global SCIP settings */
15877  SCIP_STAT* stat /**< problem statistics */
15878  )
15879 {
15880  int c;
15881  int r;
15882 
15883  assert(lp != NULL);
15884  assert(lp->flushed || !lp->solved);
15885  assert(!lp->diving);
15886  assert(!lp->probing);
15887  assert(lp->divelpistate == NULL);
15888  assert(lp->divelpwasprimfeas);
15889  assert(lp->divelpwasdualfeas);
15890  assert(lp->validsollp <= stat->lpcount);
15891  assert(blkmem != NULL);
15892  assert(set != NULL);
15893  assert(lp->ndivechgsides == 0);
15894 
15895  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15896  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15897 
15898 #ifndef NDEBUG
15899  for( c = 0; c < lp->ncols; ++c )
15900  {
15901  assert(lp->cols[c] != NULL);
15902  assert(lp->cols[c]->var != NULL);
15903  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15904  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15905  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15906  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15907  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15908  }
15909 #endif
15910 
15911  /* save current LPI state (basis information) */
15912  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15914  lp->divelpwasdualfeas = lp->dualfeasible;
15917 
15918  /* save current LP values dependent on the solution */
15919  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15920  assert(lp->storedsolvals != NULL);
15921  if( !set->lp_resolverestore && lp->solved )
15922  {
15923  SCIP_Bool store = TRUE;
15924 
15925  switch ( lp->lpsolstat )
15926  {
15928  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15929  assert(lp->validsollp == stat->lpcount);
15930  break;
15932  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15933  assert(lp->validsollp == stat->lpcount);
15934  break;
15938  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15939  assert(lp->validsollp == stat->lpcount);
15940  break;
15942  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
15943  break;
15945  case SCIP_LPSOLSTAT_ERROR:
15946  default:
15947  store = FALSE;
15948  }
15949 
15950  if ( store )
15951  {
15952  for( c = 0; c < lp->ncols; ++c )
15953  {
15954  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15955  }
15956  for( r = 0; r < lp->nrows; ++r )
15957  {
15959  }
15960  }
15961  }
15962 
15963  /* store LPI iteration limit */
15965 
15966  /* remember the number of domain changes */
15967  lp->divenolddomchgs = stat->domchgcount;
15968 
15969  /* store current number of rows */
15970  lp->ndivingrows = lp->nrows;
15971 
15972  /* switch to diving mode */
15973  lp->diving = TRUE;
15974 
15975  return SCIP_OKAY;
15976 }
15977 
15978 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15980  SCIP_LP* lp, /**< current LP data */
15981  BMS_BLKMEM* blkmem, /**< block memory */
15982  SCIP_SET* set, /**< global SCIP settings */
15983  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15984  SCIP_STAT* stat, /**< problem statistics */
15985  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15986  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15987  SCIP_PROB* prob, /**< problem data */
15988  SCIP_VAR** vars, /**< array with all active variables */
15989  int nvars /**< number of active variables */
15990  )
15991 {
15992  SCIP_VAR* var;
15993  int v;
15994 
15995  assert(lp != NULL);
15996  assert(lp->diving);
15997  assert(blkmem != NULL);
15998  assert(nvars == 0 || vars != NULL);
15999 
16000  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16001 
16002  /* reset all columns' objective values and bounds to its original values */
16003  for( v = 0; v < nvars; ++v )
16004  {
16005  var = vars[v];
16006  assert(var != NULL);
16008  {
16009  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
16010  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
16011  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
16012  }
16013  }
16014 
16015  /* remove rows which were added in diving mode */
16016  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16017 
16018  /* undo changes to left hand sides and right hand sides */
16019  while( lp->ndivechgsides > 0 )
16020  {
16021  SCIP_Real oldside;
16022  SCIP_SIDETYPE sidetype;
16023  SCIP_ROW* row;
16024 
16025  lp->ndivechgsides--;
16026  oldside = lp->divechgsides[lp->ndivechgsides];
16027  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16028  row = lp->divechgrows[lp->ndivechgsides];
16029 
16030  if( sidetype == SCIP_SIDETYPE_LEFT )
16031  {
16032  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16033  }
16034  else
16035  {
16036  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16037  }
16038  }
16039 
16040  /* restore LPI iteration limit */
16042 
16043  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16044  * happens
16045  */
16046  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
16048  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16049  lp->divelpwasprimfeas = TRUE;
16050  lp->divelpwasdualfeas = TRUE;
16051  lp->divelpwasprimchecked = TRUE;
16052  lp->divelpwasdualchecked = TRUE;
16053  assert(lp->divelpistate == NULL);
16054 
16055  /* switch to standard (non-diving) mode */
16056  lp->diving = FALSE;
16057  lp->divingobjchg = FALSE;
16058 
16059  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16060  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16061  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16062  * the parameter resolverestore to TRUE
16063  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16064  */
16065  assert(lp->storedsolvals != NULL);
16066  if( lp->storedsolvals->lpissolved
16067  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16068  {
16069  SCIP_Bool lperror;
16070 
16071  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
16072  if( lperror )
16073  {
16074  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16075  lp->resolvelperror = TRUE;
16076  }
16081  {
16082  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16083  "LP was not resolved to a sufficient status after diving\n");
16084  lp->resolvelperror = TRUE;
16085  }
16086  }
16087  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16088  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16089  * re-solve as above can lead to a different LP status
16090  */
16091  else
16092  {
16093  int c;
16094  int r;
16095 
16096  /* if there are lazy bounds, remove them from the LP */
16097  if( lp->nlazycols > 0 )
16098  {
16099  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16100  * first resolve LP?
16101  */
16102  SCIP_CALL( updateLazyBounds(lp, set) );
16103  assert(lp->diving == lp->divinglazyapplied);
16104 
16105  /* flush changes to the LP solver */
16106  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
16107  }
16108 
16109  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
16110  SCIPstatIncrement(stat, set, lpcount);
16111 
16112  /* restore LP solution values in lp data, columns and rows */
16113  if( lp->storedsolvals->lpissolved &&
16120  )
16121  {
16122  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16123 
16124  for( c = 0; c < lp->ncols; ++c )
16125  {
16126  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16127  }
16128  for( r = 0; r < lp->nrows; ++r )
16129  {
16130  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16131  }
16132  }
16133  else
16134  {
16135  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16136  }
16137  }
16138 
16139 #ifndef NDEBUG
16140  {
16141  int c;
16142  for( c = 0; c < lp->ncols; ++c )
16143  {
16144  assert(lp->cols[c] != NULL);
16145  assert(lp->cols[c]->var != NULL);
16146  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16147  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16148  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16149  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16150  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16151  }
16152  }
16153 #endif
16154 
16155  return SCIP_OKAY;
16156 }
16157 
16158 #define DIVESTACKGROWFACT 1.5
16159 
16160 /** records a current row side such that any change will be undone after diving */
16162  SCIP_LP* lp, /**< LP data object */
16163  SCIP_ROW* row, /**< row affected by the change */
16164  SCIP_SIDETYPE sidetype /**< side type */
16165  )
16166 {
16167  assert(lp != NULL);
16168  assert(row != NULL);
16169 
16170  if( lp->ndivechgsides == lp->divechgsidessize )
16171  {
16173  }
16174  assert(lp->ndivechgsides < lp->divechgsidessize);
16175 
16176  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16177  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16178  lp->divechgrows[lp->ndivechgsides] = row;
16179  lp->ndivechgsides++;
16180 
16181  return SCIP_OKAY;
16182 }
16183 
16184 /** informs the LP that probing mode was initiated */
16186  SCIP_LP* lp /**< current LP data */
16187  )
16188 {
16189  assert(lp != NULL);
16190  assert(!lp->probing);
16191  assert(!lp->strongbranching);
16192  assert(!lp->strongbranchprobing);
16193 
16194  lp->probing = TRUE;
16195 
16196  return SCIP_OKAY;
16197 }
16198 
16199 /** informs the LP that probing mode was finished */
16201  SCIP_LP* lp /**< current LP data */
16202  )
16203 {
16204  assert(lp != NULL);
16205  assert(lp->probing);
16206  assert(!lp->strongbranching);
16207  assert(!lp->strongbranchprobing);
16208 
16209  lp->probing = FALSE;
16210 
16211  return SCIP_OKAY;
16212 }
16213 
16214 /** informs the LP that the probing mode is now used for strongbranching */
16216  SCIP_LP* lp /**< current LP data */
16217  )
16218 {
16219  assert(lp != NULL);
16220  assert(lp->probing);
16221  assert(!lp->strongbranching);
16222  assert(!lp->strongbranchprobing);
16223 
16224  lp->strongbranchprobing = TRUE;
16225 }
16226 
16227 /** informs the LP that the probing mode is not used for strongbranching anymore */
16229  SCIP_LP* lp /**< current LP data */
16230  )
16231 {
16232  assert(lp != NULL);
16233  assert(lp->probing);
16234  assert(!lp->strongbranching);
16235  assert(lp->strongbranchprobing);
16236 
16237  lp->strongbranchprobing = FALSE;
16238 }
16239 
16240 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16241  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16242  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16243  * we have only left hand sides):
16244  * min{cx | b <= Ax, lb <= x <= ub}
16245  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16246  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16247  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16248  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16249  */
16250 static
16252  SCIP_LP* lp, /**< current LP data */
16253  SCIP_SET* set, /**< global SCIP settings */
16254  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16255  SCIP_Real* bound /**< result of interval arithmetic minimization */
16256  )
16257 {
16258  SCIP_INTERVAL* yinter;
16259  SCIP_INTERVAL b;
16260  SCIP_INTERVAL ytb;
16261  SCIP_INTERVAL prod;
16262  SCIP_INTERVAL diff;
16263  SCIP_INTERVAL x;
16264  SCIP_INTERVAL minprod;
16265  SCIP_INTERVAL a;
16266  SCIP_ROW* row;
16267  SCIP_COL* col;
16268  SCIP_Real y;
16269  SCIP_Real c;
16270  int i;
16271  int j;
16272 
16273  assert(lp != NULL);
16274  assert(lp->solved);
16275  assert(set != NULL);
16276  assert(bound != NULL);
16277 
16278  /* allocate buffer for storing y in interval arithmetic */
16279  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16280 
16281  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16282  SCIPintervalSet(&ytb, 0.0);
16283  for( j = 0; j < lp->nrows; ++j )
16284  {
16285  row = lp->rows[j];
16286  assert(row != NULL);
16287 
16288  y = (usefarkas ? row->dualfarkas : row->dualsol);
16289 
16290  if( SCIPsetIsFeasPositive(set, y) )
16291  {
16292  SCIPintervalSet(&yinter[j], y);
16293  SCIPintervalSet(&b, row->lhs - row->constant);
16294  }
16295  else if( SCIPsetIsFeasNegative(set, y) )
16296  {
16297  SCIPintervalSet(&yinter[j], y);
16298  SCIPintervalSet(&b, row->rhs - row->constant);
16299  }
16300  else
16301  {
16302  SCIPintervalSet(&yinter[j], 0.0);
16303  SCIPintervalSet(&b, 0.0);
16304  }
16305 
16306  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16307  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16308  }
16309 
16310  /* calculate min{(c^T - y^TA)x} */
16311  SCIPintervalSet(&minprod, 0.0);
16312  for( j = 0; j < lp->ncols; ++j )
16313  {
16314  col = lp->cols[j];
16315  assert(col != NULL);
16316  assert(col->nunlinked == 0);
16317 
16319 
16320  c = usefarkas ? 0.0 : col->obj;
16321  SCIPintervalSet(&diff, c);
16322 
16323  for( i = 0; i < col->nlprows; ++i )
16324  {
16325  assert(col->rows[i] != NULL);
16326  assert(col->rows[i]->lppos >= 0);
16327  assert(col->linkpos[i] >= 0);
16328  SCIPintervalSet(&a, col->vals[i]);
16329  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16330  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16331  }
16332 
16333 #ifndef NDEBUG
16334  for( i = col->nlprows; i < col->len; ++i )
16335  {
16336  assert(col->rows[i] != NULL);
16337  assert(col->rows[i]->lppos == -1);
16338  assert(col->rows[i]->dualsol == 0.0);
16339  assert(col->rows[i]->dualfarkas == 0.0);
16340  assert(col->linkpos[i] >= 0);
16341  }
16342 #endif
16343 
16344  SCIPintervalSetBounds(&x, col->lb, col->ub);
16345  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16346  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16347  }
16348 
16349  /* add y^Tb */
16350  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16351 
16352  /* free buffer for storing y in interval arithmetic */
16353  SCIPsetFreeBufferArray(set, &yinter);
16354 
16355  *bound = SCIPintervalGetInf(minprod);
16356 
16357  return SCIP_OKAY;
16358 }
16359 
16360 /** gets proven lower (dual) bound of last LP solution */
16362  SCIP_LP* lp, /**< current LP data */
16363  SCIP_SET* set, /**< global SCIP settings */
16364  SCIP_Real* bound /**< pointer to store proven dual bound */
16365  )
16366 {
16367  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16368 
16369  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16370 
16371  return SCIP_OKAY;
16372 }
16373 
16374 /** gets proven dual bound of last LP solution */
16376  SCIP_LP* lp, /**< current LP data */
16377  SCIP_SET* set, /**< global SCIP settings */
16378  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16379  )
16380 {
16381  SCIP_Real bound;
16382 
16383  assert(proved != NULL);
16384 
16385  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16386 
16387  *proved = (bound > 0.0);
16388 
16389  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16390 
16391  return SCIP_OKAY;
16392 }
16393 
16394 
16395 
16396 /** writes LP to a file */
16398  SCIP_LP* lp, /**< current LP data */
16399  const char* fname /**< file name */
16400  )
16401 {
16402  assert(lp != NULL);
16403  assert(lp->flushed);
16404  assert(fname != NULL);
16405 
16406  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16407 
16408  return SCIP_OKAY;
16409 }
16410 
16411 /** writes MIP relaxation of the current B&B node to a file */
16413  SCIP_LP* lp, /**< current LP data */
16414  SCIP_SET* set, /**< global SCIP settings */
16415  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16416  const char* fname, /**< file name */
16417  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16418  * troubles with reserved symbols? */
16419  SCIP_Bool origobj, /**< should the original objective function be used? */
16420  SCIP_OBJSENSE objsense, /**< objective sense */
16421  SCIP_Real objscale, /**< objective scaling factor */
16422  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16423  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16424  )
16425 {
16426  FILE* file;
16427  int i;
16428  int j;
16429  char rowname[SCIP_MAXSTRLEN];
16430  SCIP_Real coeff;
16431 
16432  assert(lp != NULL);
16433  assert(lp->flushed);
16434  assert(fname != NULL);
16435 
16436  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16437  file = fopen(fname, "w");
16438  if( file == NULL )
16439  {
16440  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16441  SCIPprintSysError(fname);
16442  return SCIP_FILECREATEERROR;
16443  }
16444 
16445  /* print comments */
16446  if( genericnames )
16447  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16448  else
16449  {
16450  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16451  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16452  }
16453 
16454  if( origobj && objoffset != 0.0 )
16455  {
16456  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16457  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16458  }
16459 
16460  /* print objective function */
16461  /**@note the transformed problem in SCIP is always a minimization problem */
16462  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16463  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16464  else
16465  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16466 
16467  /* print objective */
16468  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16469  j = 0;
16470  for( i = 0; i < lp->ncols; ++i )
16471  {
16472  if( lp->cols[i]->obj != 0.0 )
16473  {
16474  coeff = lp->cols[i]->obj;
16475  if( origobj )
16476  {
16477  coeff *= (SCIP_Real) objsense;
16478  coeff *= objscale;
16479  }
16480 
16481  if( genericnames )
16482  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16483  else
16484  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16485 
16486  ++j;
16487  if( j % 10 == 0 )
16488  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16489  }
16490  }
16491  /* add artificial variable 'objoffset' to transfer objective offset */
16492  if( origobj && objoffset != 0.0 )
16493  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16494 
16495  /* print constraint section */
16496  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16497  for( i = 0; i < lp->nrows; i++ )
16498  {
16499  char type = 'i';
16500 
16501  /* skip removable rows if we want to write them as lazy constraints */
16502  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16503  continue;
16504 
16505  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16506  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16507  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16508  * type 'i' means: lhs and rhs are both infinite */
16509  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16510  type = 'r';
16511  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16512  type = 'l';
16513  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16514  type = 'e';
16515  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16516  type = 'b';
16517 
16518  /* print name of row */
16519  if( genericnames )
16520  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16521  else
16522  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16523 
16524  WRITEROW:
16525  switch( type )
16526  {
16527  case 'r':
16528  case 'l':
16529  case 'e':
16530  if( strlen(rowname) > 0 )
16531  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16532  break;
16533  case 'i':
16534  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16535  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16536  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16537  type = 'b';
16538  /*lint -fallthrough*/
16539  case 'b':
16540  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16541  break;
16542  default:
16543  assert(type == 'B');
16544  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16545  break;
16546  }
16547 
16548  /* print coefficients and variables */
16549  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16550  {
16551  if( genericnames )
16552  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16553  else
16554  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16555 
16556  if( (j+1) % 10 == 0 )
16557  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16558  }
16559 
16560  /* print right hand side */
16561  switch( type )
16562  {
16563  case 'b':
16564  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16565  type = 'B';
16566  goto WRITEROW;
16567  case 'l':
16568  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16569  break;
16570  case 'B':
16571  case 'r':
16572  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16573  break;
16574  case 'e':
16575  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16576  break;
16577  default:
16578  SCIPerrorMessage("Undefined row type!\n");
16579  fclose(file);
16580  return SCIP_ERROR;
16581  }
16582  }
16583 
16584  if ( lazyconss )
16585  {
16586  /* print lazy constraint section */
16587  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16588  for( i = 0; i < lp->nrows; i++ )
16589  {
16590  char type = 'i';
16591 
16592  /* skip non-removable rows if we want to write lazy constraints */
16593  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16594  continue;
16595 
16596  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16597  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16598  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16599  * type 'i' means: lhs and rhs are both infinite */
16600  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16601  type = 'r';
16602  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16603  type = 'l';
16604  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16605  type = 'e';
16606  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16607  type = 'b';
16608 
16609  /* print name of row */
16610  if( genericnames )
16611  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16612  else
16613  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16614 
16615  WRITELAZYROW:
16616  switch( type )
16617  {
16618  case 'r':
16619  case 'l':
16620  case 'e':
16621  if( strlen(rowname) > 0 )
16622  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16623  break;
16624  case 'i':
16625  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16626  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16627  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16628  type = 'b';
16629  /*lint -fallthrough*/
16630  case 'b':
16631  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16632  break;
16633  default:
16634  assert(type == 'B');
16635  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16636  break;
16637  }
16638 
16639  /* print coefficients and variables */
16640  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16641  {
16642  if( genericnames )
16643  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16644  else
16645  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16646 
16647  if( (j+1) % 10 == 0 )
16648  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16649  }
16650 
16651  /* print right hand side */
16652  switch( type )
16653  {
16654  case 'b':
16655  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16656  type = 'B';
16657  goto WRITELAZYROW;
16658  case 'l':
16659  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16660  break;
16661  case 'B':
16662  case 'r':
16663  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16664  break;
16665  case 'e':
16666  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16667  break;
16668  default:
16669  SCIPerrorMessage("Undefined row type!\n");
16670  fclose(file);
16671  return SCIP_ERROR;
16672  }
16673  }
16674  }
16675 
16676  /* print variable bounds */
16677  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16678  for( i = 0; i < lp->ncols; ++i )
16679  {
16680  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16681  {
16682  /* print lower bound as far this one is not infinity */
16683  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16684  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16685 
16686  /* print variable name */
16687  if( genericnames )
16688  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16689  else
16690  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16691 
16692  /* print upper bound as far this one is not infinity */
16693  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16694  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16695  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16696  }
16697  }
16698  if( origobj && objoffset != 0.0 )
16699  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16700 
16701  /* print integer variables */
16702  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16703  j = 0;
16704  for( i = 0; i < lp->ncols; ++i )
16705  {
16706  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16707  {
16708  /* print variable name */
16709  if( genericnames )
16710  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16711  else
16712  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16713 
16714  j++;
16715  if( j % 10 == 0 )
16716  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16717  }
16718  }
16719 
16720  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16721  fclose(file);
16722 
16723  return SCIP_OKAY;
16724 }
16725 
16726 /*
16727  * simple functions implemented as defines
16728  */
16729 
16730 /* In debug mode, the following methods are implemented as function calls to ensure
16731  * type validity.
16732  * In optimized mode, the methods are implemented as defines to improve performance.
16733  * However, we want to have them in the library anyways, so we have to undef the defines.
16734  */
16735 
16736 #undef SCIPcolGetObj
16737 #undef SCIPcolGetLb
16738 #undef SCIPcolGetUb
16739 #undef SCIPcolGetBestBound
16740 #undef SCIPcolGetPrimsol
16741 #undef SCIPcolGetMinPrimsol
16742 #undef SCIPcolGetMaxPrimsol
16743 #undef SCIPcolGetBasisStatus
16744 #undef SCIPcolGetVar
16745 #undef SCIPcolGetIndex
16746 #undef SCIPcolGetVarProbindex
16747 #undef SCIPcolIsIntegral
16748 #undef SCIPcolIsRemovable
16749 #undef SCIPcolGetLPPos
16750 #undef SCIPcolGetLPDepth
16751 #undef SCIPcolIsInLP
16752 #undef SCIPcolGetNNonz
16753 #undef SCIPcolGetNLPNonz
16754 #undef SCIPcolGetRows
16755 #undef SCIPcolGetVals
16756 #undef SCIPcolGetStrongbranchNode
16757 #undef SCIPcolGetNStrongbranchs
16758 #undef SCIPcolGetAge
16759 #undef SCIPboundtypeOpposite
16760 #undef SCIProwGetNNonz
16761 #undef SCIProwGetNLPNonz
16762 #undef SCIProwGetCols
16763 #undef SCIProwGetVals
16764 #undef SCIProwGetConstant
16765 #undef SCIProwGetNorm
16766 #undef SCIProwGetSumNorm
16767 #undef SCIProwGetLhs
16768 #undef SCIProwGetRhs
16769 #undef SCIProwGetDualsol
16770 #undef SCIProwGetDualfarkas
16771 #undef SCIProwGetBasisStatus
16772 #undef SCIProwGetName
16773 #undef SCIProwGetIndex
16774 #undef SCIProwGetAge
16775 #undef SCIProwGetRank
16776 #undef SCIProwIsIntegral
16777 #undef SCIProwIsLocal
16778 #undef SCIProwIsModifiable
16779 #undef SCIProwIsRemovable
16780 #undef SCIProwGetOrigintype
16781 #undef SCIProwGetOriginCons
16782 #undef SCIProwGetOriginConshdlr
16783 #undef SCIProwGetOriginSepa
16784 #undef SCIProwIsInGlobalCutpool
16785 #undef SCIProwGetLPPos
16786 #undef SCIProwGetLPDepth
16787 #undef SCIProwIsInLP
16788 #undef SCIProwGetActiveLPCount
16789 #undef SCIProwGetNLPsAfterCreation
16790 #undef SCIProwChgRank
16791 #undef SCIPlpGetCols
16792 #undef SCIPlpGetNCols
16793 #undef SCIPlpGetRows
16794 #undef SCIPlpGetNRows
16795 #undef SCIPlpGetNewcols
16796 #undef SCIPlpGetNNewcols
16797 #undef SCIPlpGetNewrows
16798 #undef SCIPlpGetNNewrows
16799 #undef SCIPlpGetObjNorm
16800 #undef SCIPlpGetRootObjval
16801 #undef SCIPlpGetRootColumnObjval
16802 #undef SCIPlpGetRootLooseObjval
16803 #undef SCIPlpGetLPI
16804 #undef SCIPlpSetIsRelax
16805 #undef SCIPlpIsRelax
16806 #undef SCIPlpIsSolved
16807 #undef SCIPlpIsSolBasic
16808 #undef SCIPlpDiving
16809 #undef SCIPlpDivingObjChanged
16810 #undef SCIPlpMarkDivingObjChanged
16811 #undef SCIPlpUnmarkDivingObjChanged
16812 #undef SCIPlpDivingRowsChanged
16813 
16814 /** gets objective value of column */
16816  SCIP_COL* col /**< LP column */
16817  )
16818 {
16819  assert(col != NULL);
16820 
16821  return col->obj;
16822 }
16823 
16824 /** gets lower bound of column */
16826  SCIP_COL* col /**< LP column */
16827  )
16828 {
16829  assert(col != NULL);
16830 
16831  return col->lb;
16832 }
16833 
16834 /** gets upper bound of column */
16836  SCIP_COL* col /**< LP column */
16837  )
16838 {
16839  assert(col != NULL);
16840 
16841  return col->ub;
16842 }
16843 
16844 /** gets best bound of column with respect to the objective function */
16846  SCIP_COL* col /**< LP column */
16847  )
16848 {
16849  assert(col != NULL);
16850 
16851  if( col->obj >= 0.0 )
16852  return col->lb;
16853  else
16854  return col->ub;
16855 }
16856 
16857 /** gets the primal LP solution of a column */
16859  SCIP_COL* col /**< LP column */
16860  )
16861 {
16862  assert(col != NULL);
16863 
16864  if( col->lppos >= 0 )
16865  return col->primsol;
16866  else
16867  return 0.0;
16868 }
16869 
16870 /** gets the minimal LP solution value, this column ever assumed */
16872  SCIP_COL* col /**< LP column */
16873  )
16874 {
16875  assert(col != NULL);
16876 
16877  return col->minprimsol;
16878 }
16879 
16880 /** gets the maximal LP solution value, this column ever assumed */
16882  SCIP_COL* col /**< LP column */
16883  )
16884 {
16885  assert(col != NULL);
16886 
16887  return col->maxprimsol;
16888 }
16889 
16890 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16891  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16892  */
16894  SCIP_COL* col /**< LP column */
16895  )
16896 {
16897  assert(col != NULL);
16898  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16899 
16900  return (SCIP_BASESTAT)col->basisstatus;
16901 }
16902 
16903 /** gets variable this column represents */
16905  SCIP_COL* col /**< LP column */
16906  )
16907 {
16908  assert(col != NULL);
16909 
16910  return col->var;
16911 }
16912 
16913 /** gets unique index of col */
16915  SCIP_COL* col /**< LP col */
16916  )
16917 {
16918  assert(col != NULL);
16919 
16920  return col->index;
16921 }
16922 
16923 /** gets probindex of corresponding variable */
16925  SCIP_COL* col /**< LP col */
16926  )
16927 {
16928  assert(col != NULL);
16929 
16930  return col->var_probindex;
16931 }
16932 
16933 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16935  SCIP_COL* col /**< LP column */
16936  )
16937 {
16938  assert(col != NULL);
16939  assert(SCIPvarIsIntegral(col->var) == col->integral);
16940 
16941  return col->integral;
16942 }
16943 
16944 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16946  SCIP_COL* col /**< LP column */
16947  )
16948 {
16949  assert(col != NULL);
16950 
16951  return col->removable;
16952 }
16953 
16954 /** gets position of column in current LP, or -1 if it is not in LP */
16956  SCIP_COL* col /**< LP column */
16957  )
16958 {
16959  assert(col != NULL);
16960  assert((col->lppos == -1) == (col->lpdepth == -1));
16961 
16962  return col->lppos;
16963 }
16964 
16965 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16967  SCIP_COL* col /**< LP column */
16968  )
16969 {
16970  assert(col != NULL);
16971  assert((col->lppos == -1) == (col->lpdepth == -1));
16972 
16973  return col->lpdepth;
16974 }
16975 
16976 /** returns TRUE iff column is member of current LP */
16978  SCIP_COL* col /**< LP column */
16979  )
16980 {
16981  assert(col != NULL);
16982  assert((col->lppos == -1) == (col->lpdepth == -1));
16983 
16984  return (col->lppos >= 0);
16985 }
16986 
16987 /** get number of nonzero entries in column vector */
16989  SCIP_COL* col /**< LP column */
16990  )
16991 {
16992  assert(col != NULL);
16993 
16994  return col->len;
16995 }
16996 
16997 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16998  *
16999  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17000  * 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
17001  */
17003  SCIP_COL* col /**< LP column */
17004  )
17005 {
17006  assert(col != NULL);
17007  assert(col->nunlinked == 0);
17008 
17009  return col->nlprows;
17010 }
17011 
17012 /** gets array with rows of nonzero entries */
17014  SCIP_COL* col /**< LP column */
17015  )
17016 {
17017  assert(col != NULL);
17018 
17019  return col->rows;
17020 }
17021 
17022 /** gets array with coefficients of nonzero entries */
17024  SCIP_COL* col /**< LP column */
17025  )
17026 {
17027  assert(col != NULL);
17028 
17029  return col->vals;
17030 }
17031 
17032 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
17033  * given column, or -1 if strong branching was never applied to the column in current run
17034  */
17036  SCIP_COL* col /**< LP column */
17037  )
17038 {
17039  assert(col != NULL);
17040 
17041  return col->sbnode;
17042 }
17043 
17044 /** gets number of times, strong branching was applied in current run on the given column */
17046  SCIP_COL* col /**< LP column */
17047  )
17048 {
17049  assert(col != NULL);
17050 
17051  return col->nsbcalls;
17052 }
17053 
17054 /** 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 */
17056  SCIP_COL* col /**< LP column */
17057  )
17058 {
17059  assert(col != NULL);
17060 
17061  return col->age;
17062 }
17063 
17064 /** gets opposite bound type of given bound type */
17066  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17067  )
17068 {
17069  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17070 
17072 }
17073 
17074 /** get number of nonzero entries in row vector */
17076  SCIP_ROW* row /**< LP row */
17077  )
17078 {
17079  assert(row != NULL);
17080 
17081  return row->len;
17082 }
17083 
17084 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17085  *
17086  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17087  * 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
17088  */
17090  SCIP_ROW* row /**< LP row */
17091  )
17092 {
17093  assert(row != NULL);
17094  assert(row->nunlinked == 0);
17095 
17096  return row->nlpcols;
17097 }
17098 
17099 /** gets array with columns of nonzero entries */
17101  SCIP_ROW* row /**< LP row */
17102  )
17103 {
17104  assert(row != NULL);
17105 
17106  return row->cols;
17107 }
17108 
17109 /** gets array with coefficients of nonzero entries */
17111  SCIP_ROW* row /**< LP row */
17112  )
17113 {
17114  assert(row != NULL);
17115 
17116  return row->vals;
17117 }
17118 
17119 /** gets constant shift of row */
17121  SCIP_ROW* row /**< LP row */
17122  )
17123 {
17124  assert(row != NULL);
17125 
17126  return row->constant;
17127 }
17128 
17129 /** gets Euclidean norm of row vector */
17131  SCIP_ROW* row /**< LP row */
17132  )
17133 {
17134  assert(row != NULL);
17135 
17136  checkRowSqrnorm(row);
17137 
17138  return sqrt(row->sqrnorm);
17139 }
17140 
17141 /** gets sum norm of row vector (sum of absolute values of coefficients) */
17143  SCIP_ROW* row /**< LP row */
17144  )
17145 {
17146  assert(row != NULL);
17147 
17148  checkRowSumnorm(row);
17149 
17150  return row->sumnorm;
17151 }
17152 
17153 /** returns the left hand side of the row */
17155  SCIP_ROW* row /**< LP row */
17156  )
17157 {
17158  assert(row != NULL);
17159 
17160  return row->lhs;
17161 }
17162 
17163 /** returns the right hand side of the row */
17165  SCIP_ROW* row /**< LP row */
17166  )
17167 {
17168  assert(row != NULL);
17169 
17170  return row->rhs;
17171 }
17172 
17173 /** gets the dual LP solution of a row */
17175  SCIP_ROW* row /**< LP row */
17176  )
17177 {
17178  assert(row != NULL);
17179 
17180  if( row->lppos >= 0 )
17181  return row->dualsol;
17182  else
17183  return 0.0;
17184 }
17185 
17186 /** gets the dual Farkas coefficient of a row in an infeasible LP */
17188  SCIP_ROW* row /**< LP row */
17189  )
17190 {
17191  assert(row != NULL);
17192 
17193  if( row->lppos >= 0 )
17194  return row->dualfarkas;
17195  else
17196  return 0.0;
17197 }
17198 
17199 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17200  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17201  */
17203  SCIP_ROW* row /**< LP row */
17204  )
17205 {
17206  assert(row != NULL);
17207  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17208 
17209  return (SCIP_BASESTAT)row->basisstatus;
17210 }
17211 
17212 /** returns the name of the row */
17213 const char* SCIProwGetName(
17214  SCIP_ROW* row /**< LP row */
17215  )
17216 {
17217  assert(row != NULL);
17218 
17219  return row->name;
17220 }
17221 
17222 /** gets unique index of row */
17224  SCIP_ROW* row /**< LP row */
17225  )
17226 {
17227  assert(row != NULL);
17228 
17229  return row->index;
17230 }
17231 
17232 /** gets age of row */
17234  SCIP_ROW* row /**< LP row */
17235  )
17236 {
17237  assert(row != NULL);
17238 
17239  return row->age;
17240 }
17241 
17242 /** gets rank of row */
17244  SCIP_ROW* row /**< LP row */
17245  )
17246 {
17247  assert(row != NULL);
17248 
17249  return row->rank;
17250 }
17251 
17252 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17254  SCIP_ROW* row /**< LP row */
17255  )
17256 {
17257  assert(row != NULL);
17258 
17259  return row->integral;
17260 }
17261 
17262 /** returns TRUE iff row is only valid locally */
17264  SCIP_ROW* row /**< LP row */
17265  )
17266 {
17267  assert(row != NULL);
17268 
17269  return row->local;
17270 }
17271 
17272 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17274  SCIP_ROW* row /**< LP row */
17275  )
17276 {
17277  assert(row != NULL);
17278 
17279  return row->modifiable;
17280 }
17281 
17282 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17284  SCIP_ROW* row /**< LP row */
17285  )
17286 {
17287  assert(row != NULL);
17288 
17289  return row->removable;
17290 }
17291 
17292 /** returns type of origin that created the row */
17294  SCIP_ROW* row /**< LP row */
17295  )
17296 {
17297  assert( row != NULL );
17298 
17299  return (SCIP_ROWORIGINTYPE) row->origintype;
17300 }
17301 
17302 /** returns origin constraint that created the row (NULL if not available) */
17304  SCIP_ROW* row /**< LP row */
17305  )
17306 {
17307  assert( row != NULL );
17308 
17310  {
17311  assert( row->origin != NULL );
17312  return (SCIP_CONS*) row->origin;
17313  }
17314  return NULL;
17315 }
17316 
17317 /** returns origin constraint handler that created the row (NULL if not available) */
17319  SCIP_ROW* row /**< LP row */
17320  )
17321 {
17322  assert( row != NULL );
17323 
17325  {
17326  assert( row->origin != NULL );
17327  return (SCIP_CONSHDLR*) row->origin;
17328  }
17330  {
17331  assert(row->origin != NULL);
17332  return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17333  }
17334  return NULL;
17335 }
17336 
17337 /** returns origin separator that created the row (NULL if not available) */
17339  SCIP_ROW* row /**< LP row */
17340  )
17341 {
17342  assert( row != NULL );
17343 
17345  {
17346  assert( row->origin != NULL );
17347  return (SCIP_SEPA*) row->origin;
17348  }
17349  return NULL;
17350 }
17351 
17352 /** returns TRUE iff row is member of the global cut pool */
17354  SCIP_ROW* row /**< LP row */
17355  )
17356 {
17357  assert(row != NULL);
17358 
17359  return row->inglobalcutpool;
17360 }
17361 
17362 /** gets position of row in current LP, or -1 if it is not in LP */
17364  SCIP_ROW* row /**< LP row */
17365  )
17366 {
17367  assert(row != NULL);
17368  assert((row->lppos == -1) == (row->lpdepth == -1));
17369 
17370  return row->lppos;
17371 }
17372 
17373 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17375  SCIP_ROW* row /**< LP row */
17376  )
17377 {
17378  assert(row != NULL);
17379  assert((row->lppos == -1) == (row->lpdepth == -1));
17380 
17381  return row->lpdepth;
17382 }
17383 
17384 /** returns TRUE iff row is member of current LP */
17386  SCIP_ROW* row /**< LP row */
17387  )
17388 {
17389  assert(row != NULL);
17390  assert((row->lppos == -1) == (row->lpdepth == -1));
17391 
17392  return (row->lppos >= 0);
17393 }
17394 
17395 /** changes the rank of LP row */
17397  SCIP_ROW* row, /**< LP row */
17398  int rank /**< new value for rank */
17399  )
17400 {
17401  assert(row != NULL);
17402 
17403  row->rank = rank;
17404 }
17405 
17406 /** returns the number of times that this row has been sharp in an optimal LP solution */
17408  SCIP_ROW* row /**< row */
17409  )
17410 {
17411  assert(row != NULL);
17412 
17413  return row->activeinlpcounter;
17414 }
17415 
17416 /** returns the number of LPs since this row has been created */
17418  SCIP_ROW* row /**< row */
17419  )
17420 {
17421  assert(row != NULL);
17422 
17423  return row->nlpsaftercreation;
17424 }
17425 
17426 /** gets array with columns of the LP */
17428  SCIP_LP* lp /**< current LP data */
17429  )
17430 {
17431  assert(lp != NULL);
17432 
17433  return lp->cols;
17434 }
17435 
17436 /** gets current number of columns in LP */
17438  SCIP_LP* lp /**< current LP data */
17439  )
17440 {
17441  assert(lp != NULL);
17442 
17443  return lp->ncols;
17444 }
17445 
17446 /** gets array with rows of the LP */
17448  SCIP_LP* lp /**< current LP data */
17449  )
17450 {
17451  assert(lp != NULL);
17452 
17453  return lp->rows;
17454 }
17455 
17456 /** gets current number of rows in LP */
17458  SCIP_LP* lp /**< current LP data */
17459  )
17460 {
17461  assert(lp != NULL);
17462 
17463  return lp->nrows;
17464 }
17465 
17466 /** gets array with newly added columns after the last mark */
17468  SCIP_LP* lp /**< current LP data */
17469  )
17470 {
17471  assert(lp != NULL);
17472  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17473 
17474  return &(lp->cols[lp->firstnewcol]);
17475 }
17476 
17477 /** gets number of newly added columns after the last mark */
17479  SCIP_LP* lp /**< current LP data */
17480  )
17481 {
17482  assert(lp != NULL);
17483  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17484 
17485  return lp->ncols - lp->firstnewcol;
17486 }
17487 
17488 /** gets array with newly added rows after the last mark */
17490  SCIP_LP* lp /**< current LP data */
17491  )
17492 {
17493  assert(lp != NULL);
17494  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17495 
17496  return &(lp->rows[lp->firstnewrow]);
17497 }
17498 
17499 /** gets number of newly added rows after the last mark */
17501  SCIP_LP* lp /**< current LP data */
17502  )
17503 {
17504  assert(lp != NULL);
17505  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17506 
17507  return lp->nrows - lp->firstnewrow;
17508 }
17509 
17510 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17512  SCIP_SET* set, /**< global SCIP settings */
17513  SCIP_LP* lp /**< LP data */
17514  )
17515 {
17516  if( lp->objsqrnormunreliable )
17517  {
17518  SCIP_COL** cols;
17519  int c;
17520 
17521  cols = lp->cols;
17522  assert(cols != NULL || lp->ncols == 0);
17523 
17524  lp->objsqrnorm = 0.0;
17525 
17526  for( c = lp->ncols - 1; c >= 0; --c )
17527  {
17528  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17529  }
17530  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17531 
17532  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17533  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17534 
17536  }
17537  return;
17538 }
17539 
17540 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17541  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17543  SCIP_LP* lp /**< LP data */
17544  )
17545 {
17546  assert(lp != NULL);
17547  assert(!lp->objsqrnormunreliable);
17548  assert(lp->objsqrnorm >= 0.0);
17549 
17550  return SQRT(lp->objsqrnorm);
17551 }
17552 
17553 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17555  SCIP_LP* lp, /**< LP data */
17556  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17557  )
17558 {
17559  assert(lp != NULL);
17560 
17561  lp->rootlpisrelax = isrelax;
17562 }
17563 
17564 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17566  SCIP_LP* lp /**< LP data */
17567  )
17568 {
17569  assert(lp != NULL);
17570 
17571  return lp->rootlpisrelax;
17572 }
17573 
17574 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17576  SCIP_LP* lp /**< LP data */
17577  )
17578 {
17579  assert(lp != NULL);
17580 
17581  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17582 }
17583 
17584 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17585  * returns SCIP_INVALID if the root node LP was not (yet) solved
17586  */
17588  SCIP_LP* lp /**< LP data */
17589  )
17590 {
17591  assert(lp != NULL);
17592 
17593  return lp->rootlpobjval;
17594 }
17595 
17596 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17597  * returns SCIP_INVALID if the root node LP was not (yet) solved
17598  */
17600  SCIP_LP* lp /**< LP data */
17601  )
17602 {
17603  assert(lp != NULL);
17604 
17605  return lp->rootlooseobjval;
17606 }
17607 
17608 /** gets the LP solver interface */
17610  SCIP_LP* lp /**< current LP data */
17611  )
17612 {
17613  assert(lp != NULL);
17614 
17615  return lp->lpi;
17616 }
17617 
17618 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17620  SCIP_LP* lp, /**< LP data */
17621  SCIP_Bool relax /**< is the current lp a relaxation? */
17622  )
17623 {
17624  assert(lp != NULL);
17625 
17626  lp->isrelax = relax;
17627 }
17628 
17629 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17630  * solution value a valid local lower bound?
17631  */
17633  SCIP_LP* lp /**< LP data */
17634  )
17635 {
17636  assert(lp != NULL);
17637 
17638  return lp->isrelax;
17639 }
17640 
17641 /** returns whether the current LP is flushed and solved */
17643  SCIP_LP* lp /**< current LP data */
17644  )
17645 {
17646  assert(lp != NULL);
17647 
17648  return lp->flushed && lp->solved;
17649 }
17650 
17651 /** return whether the current LP solution passed the primal feasibility check */
17653  SCIP_LP* lp /**< current LP data */
17654  )
17655 {
17656  assert(lp != NULL);
17657 
17658  return (lp->primalchecked && lp->primalfeasible);
17659 }
17660 
17661 /** return whether the current LP solution passed the dual feasibility check */
17663  SCIP_LP* lp /**< current LP data */
17664  )
17665 {
17666  assert(lp != NULL);
17667 
17668  return (lp->dualchecked && lp->dualfeasible);
17669 }
17670 
17671 /** returns whether the current LP solution is a basic solution */
17673  SCIP_LP* lp /**< current LP data */
17674  )
17675 {
17676  assert(lp != NULL);
17677 
17678  return lp->solisbasic;
17679 }
17680 
17681 /** returns whether the LP is in diving mode */
17683  SCIP_LP* lp /**< current LP data */
17684  )
17685 {
17686  assert(lp != NULL);
17687 
17688  return lp->diving;
17689 }
17690 
17691 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17693  SCIP_LP* lp /**< current LP data */
17694  )
17695 {
17696  assert(lp != NULL);
17697 
17698  return lp->divingobjchg;
17699 }
17700 
17701 /** marks the diving LP to have a changed objective function */
17703  SCIP_LP* lp /**< current LP data */
17704  )
17705 {
17706  assert(lp != NULL);
17707  assert(lp->diving || lp->probing);
17708 
17709  lp->divingobjchg = TRUE;
17710 }
17711 
17712 /** marks the diving LP to not have a changed objective function anymore */
17714  SCIP_LP* lp /**< current LP data */
17715  )
17716 {
17717  assert(lp != NULL);
17718  assert(lp->diving || lp->probing);
17719 
17720  lp->divingobjchg = FALSE;
17721 }
17722 
17723 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17725  SCIP_LP* lp /**< current LP data */
17726  )
17727 {
17728  assert(lp != NULL);
17729  assert(lp->diving || lp->ndivechgsides == 0);
17730 
17731  return (lp->ndivechgsides > 0);
17732 }
17733 
17734 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17735 static
17737  SCIP_LPI* lpi, /**< auxiliary LP interface */
17738  SCIP_SET* set, /**< global SCIP settings */
17739  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17740  SCIP_LP* lp, /**< LP data */
17741  SCIP_PROB* prob, /**< problem data */
17742  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17743  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17744  SCIP_Real timelimit, /**< time limit for LP solver */
17745  int iterlimit, /**< iteration limit for LP solver */
17746  SCIP_Real* point, /**< array to store relative interior point on exit */
17747  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17748  )
17749 {
17750  SCIP_RETCODE retcode;
17751  SCIP_Real* primal;
17752  SCIP_Real* obj;
17753  SCIP_Real* lb;
17754  SCIP_Real* ub;
17755  SCIP_Real* matvals;
17756  SCIP_Real* matlhs;
17757  SCIP_Real* matrhs;
17758  SCIP_Real objval;
17759  SCIP_Real alpha;
17760  int* matinds;
17761  int* matbeg;
17762 #ifndef NDEBUG
17763  int nslacks;
17764 #endif
17765  int nnewcols;
17766  int ntotnonz = 0;
17767  int ntotrows = 0;
17768  int matrowidx;
17769  int matidx;
17770  int cnt;
17771  int j;
17772  int i;
17773 
17774  assert(lpi != NULL);
17775 
17776  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
17777  if( retcode != SCIP_OKAY )
17778  {
17779  /* stop execution on error, since result is likely to be unsuable */
17780  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17781  return SCIP_LPERROR;
17782  }
17783 
17785  if( retcode != SCIP_OKAY )
17786  {
17787  /* stop execution on error, since result is likely to be unsuable */
17788  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17789  return SCIP_LPERROR;
17790  }
17791 
17792  /* get storage */
17793  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17794  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17795  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17796  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17797 
17798  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17799  for( j = 0; j < lp->ncols; ++j )
17800  {
17801  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17802  obj[j] = 0.0;
17803  lb[j] = -SCIPlpiInfinity(lpi);
17804  ub[j] = SCIPlpiInfinity(lpi);
17805  /* note: we could also use the original bounds - free variables seem to be faster. */
17806  }
17807 
17808  /* add artificial alpha variable */
17809  nnewcols = lp->ncols;
17810  obj[nnewcols] = 0.0;
17811  lb[nnewcols] = 1.0;
17812  ub[nnewcols] = SCIPlpiInfinity(lpi);
17813  ++nnewcols;
17814 
17815  /* create slacks for rows */
17816  for( i = 0; i < lp->nrows; ++i )
17817  {
17818  SCIP_ROW* row;
17819 
17820  row = lp->rows[i];
17821  assert( row != NULL );
17822 
17823  if( SCIProwIsModifiable(row) )
17824  continue;
17825 
17826  /* make sure row is sorted */
17827  rowSortLP(row);
17828  assert( row->lpcolssorted );
17829 
17830  /* check whether we have an equation */
17831  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17832  {
17833  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17834  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17835  ntotnonz += row->nlpcols + 1;
17836  ++ntotrows;
17837  }
17838  else
17839  {
17840  /* otherwise add slacks for each side if necessary */
17841  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17842  {
17843  if ( relaxrows )
17844  {
17845  lb[nnewcols] = 0.0;
17846  ub[nnewcols] = 1.0;
17847  obj[nnewcols++] = 1.0;
17848  ntotnonz += row->nlpcols + 2;
17849  }
17850  else
17851  ntotnonz += row->nlpcols + 1;
17852  ++ntotrows;
17853  }
17854  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17855  {
17856  if ( relaxrows )
17857  {
17858  lb[nnewcols] = 0.0;
17859  ub[nnewcols] = 1.0;
17860  obj[nnewcols++] = 1.0;
17861  ntotnonz += row->nlpcols + 2;
17862  }
17863  else
17864  ntotnonz += row->nlpcols + 1;
17865  ++ntotrows;
17866  }
17867  }
17868  }
17869 
17870  /* create slacks for objective cutoff row */
17871  if( inclobjcutoff && relaxrows )
17872  {
17873  /* add slacks for right hand side */
17874  lb[nnewcols] = 0.0;
17875  ub[nnewcols] = 1.0;
17876  obj[nnewcols++] = 1.0;
17877  ntotnonz += lp->ncols + 2;
17878  ++ntotrows;
17879  }
17880 
17881  /* create slacks for bounds */
17882  for( j = 0; j < lp->ncols; ++j )
17883  {
17884  SCIP_COL* col;
17885 
17886  col = lp->cols[j];
17887  assert( col != NULL );
17888 
17889  /* no slacks for fixed variables */
17890  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17891  {
17892  ++ntotrows;
17893  ntotnonz += 2;
17894  }
17895  else
17896  {
17897  /* add slacks for each bound if necessary */
17898  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17899  {
17900  lb[nnewcols] = 0.0;
17901  ub[nnewcols] = 1.0;
17902  obj[nnewcols++] = 1.0;
17903  ntotnonz += 3;
17904  ++ntotrows;
17905  }
17906  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
17907  {
17908  lb[nnewcols] = 0.0;
17909  ub[nnewcols] = 1.0;
17910  obj[nnewcols++] = 1.0;
17911  ntotnonz += 3;
17912  ++ntotrows;
17913  }
17914  }
17915  }
17916 #ifndef NDEBUG
17917  nslacks = nnewcols - lp->ncols - 1;
17918  assert( nslacks >= 0 );
17919  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17920 #endif
17921 
17922  /* add columns */
17923  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17924 
17925  /* free storage */
17926  SCIPsetFreeBufferArray(set, &obj);
17927  SCIPsetFreeBufferArray(set, &ub);
17928  SCIPsetFreeBufferArray(set, &lb);
17929 
17930  /* prepare storage for rows */
17931  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
17932  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
17933  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
17934  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
17935  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
17936 
17937  /* create rows arising from original rows */
17938  cnt = 0;
17939  matrowidx = 0;
17940  matidx = 0;
17941  for( i = 0; i < lp->nrows; ++i )
17942  {
17943  SCIP_ROW* row;
17944  SCIP_COL** rowcols;
17945  SCIP_Real* rowvals;
17946  SCIP_Real lhs;
17947  SCIP_Real rhs;
17948  int nnonz;
17949 
17950  row = lp->rows[i];
17951  assert( row != NULL );
17952 
17953  if( SCIProwIsModifiable(row) )
17954  continue;
17955  assert( row->lpcolssorted );
17956 
17957  /* get row data */
17958  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17959  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17960  nnonz = row->nlpcols;
17961  assert( nnonz <= lp->ncols );
17962  rowcols = row->cols;
17963  rowvals = row->vals;
17964 
17965  /* if we have an equation */
17966  if( SCIPsetIsEQ(set, lhs, rhs) )
17967  {
17968  /* set up indices */
17969  matbeg[matrowidx] = matidx;
17970  for( j = 0; j < nnonz; ++j )
17971  {
17972  assert( rowcols[j] != NULL );
17973  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17974  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17975  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17976  matinds[matidx] = rowcols[j]->lppos;
17977  matvals[matidx++] = rowvals[j];
17978  assert( matidx <= ntotnonz );
17979  }
17980 
17981  /* add artificial variable */
17982  if ( ! SCIPsetIsZero(set, rhs) )
17983  {
17984  matinds[matidx] = lp->ncols;
17985  matvals[matidx++] = -rhs;
17986  assert( matidx <= ntotnonz );
17987  }
17988 
17989  matlhs[matrowidx] = 0.0;
17990  matrhs[matrowidx++] = 0.0;
17991  assert( matrowidx <= ntotrows );
17992  }
17993  else
17994  {
17995  SCIP_Real abslhs = REALABS(lhs);
17996  SCIP_Real absrhs = REALABS(rhs);
17997 
17998  assert(!SCIPsetIsEQ(set, lhs, rhs));
17999 
18000  /* treat lhs */
18001  if( !SCIPsetIsInfinity(set, abslhs) )
18002  {
18003  /* set up indices */
18004  matbeg[matrowidx] = matidx;
18005  for( j = 0; j < nnonz; ++j )
18006  {
18007  assert( rowcols[j] != NULL );
18008  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18009  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18010  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18011  matinds[matidx] = rowcols[j]->lppos;
18012  matvals[matidx++] = rowvals[j];
18013  assert( matidx <= ntotnonz );
18014  }
18015 
18016  /* add artificial variable */
18017  if ( ! SCIPsetIsZero(set, lhs) )
18018  {
18019  matinds[matidx] = lp->ncols;
18020  matvals[matidx++] = -lhs;
18021  assert( matidx <= ntotnonz );
18022  }
18023 
18024  if( relaxrows )
18025  {
18026  /* add slack variable */
18027  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18028  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18029  assert( matidx <= ntotnonz );
18030  ++cnt;
18031  }
18032 
18033  matlhs[matrowidx] = 0.0;
18034  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18035  assert( matrowidx <= ntotrows );
18036  }
18037 
18038  /* treat rhs */
18039  if( !SCIPsetIsInfinity(set, absrhs) )
18040  {
18041  /* set up indices */
18042  matbeg[matrowidx] = matidx;
18043  for( j = 0; j < nnonz; ++j )
18044  {
18045  assert( rowcols[j] != NULL );
18046  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18047  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18048  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18049  matinds[matidx] = rowcols[j]->lppos;
18050  matvals[matidx++] = rowvals[j];
18051  assert( matidx <= ntotnonz );
18052  }
18053 
18054  /* add artificial variable */
18055  if ( ! SCIPsetIsZero(set, rhs) )
18056  {
18057  matinds[matidx] = lp->ncols;
18058  matvals[matidx++] = -rhs;
18059  assert( matidx <= ntotnonz );
18060  }
18061 
18062  if( relaxrows )
18063  {
18064  /* add slack variable */
18065  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18066  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18067  ++cnt;
18068  }
18069 
18070  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18071  matrhs[matrowidx++] = 0.0;
18072  assert( matrowidx <= ntotrows );
18073  }
18074  }
18075  }
18076 
18077  /* create row arising from objective cutoff */
18078  if( inclobjcutoff )
18079  {
18080  SCIP_Real rhs;
18081 
18082  /* get row data */
18083  assert(lp->looseobjvalinf == 0);
18084  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18085 
18086  /* set up indices and coefficients */
18087  matbeg[matrowidx] = matidx;
18088  for( j = 0; j < lp->ncols; ++j )
18089  {
18090  assert( lp->cols[j] != NULL );
18091  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18092  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18093 
18094  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18095  {
18096  matinds[matidx] = lp->cols[j]->lppos;
18097  matvals[matidx++] = lp->cols[j]->obj;
18098  assert( matidx <= ntotnonz );
18099  }
18100  }
18101 
18102  /* treat rhs */
18103 
18104  /* add artificial variable */
18105  if ( ! SCIPsetIsZero(set, rhs) )
18106  {
18107  matinds[matidx] = lp->ncols;
18108  matvals[matidx++] = -rhs;
18109  assert( matidx <= ntotnonz );
18110  }
18111 
18112  if( relaxrows )
18113  {
18114  SCIP_Real absrhs = REALABS(rhs);
18115 
18116  /* add slack variable */
18117  matvals[matidx] = MAX(1.0, absrhs);
18118  matinds[matidx++] = lp->ncols + 1 + cnt;
18119  assert( matidx <= ntotnonz );
18120  ++cnt;
18121  }
18122  matlhs[matrowidx] = -SCIPsetInfinity(set);
18123  matrhs[matrowidx++] = 0.0;
18124  assert( matrowidx <= ntotrows );
18125  }
18126 
18127  /* create rows arising from bounds */
18128  for( j = 0; j < lp->ncols; ++j )
18129  {
18130  SCIP_COL* col;
18131  SCIP_Real abscollb;
18132  SCIP_Real abscolub;
18133 
18134  col = lp->cols[j];
18135  assert( col != NULL );
18136  assert( col->lppos == j );
18137 
18138  /* fixed variable */
18139  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18140  {
18141  /* set up index of column */
18142  matbeg[matrowidx] = matidx;
18143 
18144  matinds[matidx] = j;
18145  matvals[matidx++] = 1.0;
18146  assert( matidx <= ntotnonz );
18147 
18148  /* add artificial variable */
18149  if ( ! SCIPsetIsZero(set, col->ub) )
18150  {
18151  matinds[matidx] = lp->ncols;
18152  matvals[matidx++] = -col->ub;
18153  assert( matidx <= ntotnonz );
18154  }
18155 
18156  matlhs[matrowidx] = 0.0;
18157  matrhs[matrowidx++] = 0.0;
18158  assert( matrowidx <= ntotrows );
18159 
18160  continue;
18161  }
18162 
18163  abscollb = REALABS(col->lb);
18164  abscolub = REALABS(col->ub);
18165 
18166  /* lower bound */
18167  if ( ! SCIPsetIsInfinity(set, abscollb) )
18168  {
18169  /* set up index of column */
18170  matbeg[matrowidx] = matidx;
18171 
18172  matinds[matidx] = j;
18173  matvals[matidx++] = 1.0;
18174  assert( matidx <= ntotnonz );
18175 
18176  /* add artificial variable */
18177  if ( ! SCIPsetIsZero(set, col->lb) )
18178  {
18179  matinds[matidx] = lp->ncols;
18180  matvals[matidx++] = -col->lb;
18181  assert( matidx <= ntotnonz );
18182  }
18183 
18184  /* add slack variable */
18185  matvals[matidx] = -MAX(1.0, abscollb);
18186  matinds[matidx++] = lp->ncols + 1 + cnt;
18187  assert( matidx <= ntotnonz );
18188  ++cnt;
18189 
18190  matlhs[matrowidx] = 0.0;
18191  matrhs[matrowidx++] = SCIPsetInfinity(set);
18192  assert( matrowidx <= ntotrows );
18193  }
18194 
18195  /* upper bound */
18196  if ( ! SCIPsetIsInfinity(set, abscolub) )
18197  {
18198  /* set up index of column */
18199  matbeg[matrowidx] = matidx;
18200 
18201  matinds[matidx] = j;
18202  matvals[matidx++] = 1.0;
18203  assert( matidx <= ntotnonz );
18204 
18205  /* add artificial variable */
18206  if ( ! SCIPsetIsZero(set, col->ub) )
18207  {
18208  matinds[matidx] = lp->ncols;
18209  matvals[matidx++] = -col->ub;
18210  assert( matidx <= ntotnonz );
18211  }
18212 
18213  /* add slack variable */
18214  matvals[matidx] = MAX(1.0, abscolub);
18215  matinds[matidx++] = lp->ncols + 1 + cnt;
18216  assert( matidx <= ntotnonz );
18217  ++cnt;
18218 
18219  matlhs[matrowidx] = -SCIPsetInfinity(set);
18220  matrhs[matrowidx++] = 0.0;
18221  assert( matrowidx <= ntotrows );
18222  }
18223  }
18224  assert( cnt == nslacks );
18225  assert( matrowidx == ntotrows );
18226 
18227  /* add rows */
18228  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18229 
18230  SCIPsetFreeBufferArray(set, &matrhs);
18231  SCIPsetFreeBufferArray(set, &matlhs);
18232  SCIPsetFreeBufferArray(set, &matbeg);
18233  SCIPsetFreeBufferArray(set, &matvals);
18234  SCIPsetFreeBufferArray(set, &matinds);
18235 
18236 #ifdef SCIP_OUTPUT
18237  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18238 #endif
18239 
18240 #ifndef NDEBUG
18241  {
18242  int ncols;
18243  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18244  assert( ncols == nnewcols );
18245  }
18246 #endif
18247 
18248  /* set time limit */
18249  if( SCIPsetIsInfinity(set, timelimit) )
18250  timelimit = SCIPlpiInfinity(lpi);
18251  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18252 
18253  /* check, if parameter is unknown */
18254  if( retcode == SCIP_PARAMETERUNKNOWN )
18255  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18256  else if ( retcode != SCIP_OKAY )
18257  return retcode;
18258 
18259  /* set iteration limit */
18260  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18261 
18262  /* check, if parameter is unknown */
18263  if( retcode == SCIP_PARAMETERUNKNOWN )
18264  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18265  else if ( retcode != SCIP_OKAY )
18266  return retcode;
18267 
18268  /* solve and store point */
18269  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18270  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18271 
18272 #ifndef NDEBUG
18273  if ( SCIPlpiIsIterlimExc(lpi) )
18274  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18275  if ( SCIPlpiIsTimelimExc(lpi) )
18276  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18277 #endif
18278 
18279  if( SCIPlpiIsOptimal(lpi) )
18280  {
18281  /* get primal solution */
18282  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18283  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18284  alpha = primal[lp->ncols];
18285  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18286 
18287  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18288 
18289  /* construct relative interior point */
18290  for( j = 0; j < lp->ncols; ++j )
18291  point[j] = primal[j]/alpha;
18292 
18293 #ifdef SCIP_DEBUG
18294  /* check whether the point is a relative interior point */
18295  cnt = 0;
18296  if( relaxrows )
18297  {
18298  for( i = 0; i < lp->nrows; ++i )
18299  {
18300  SCIP_ROW* row;
18301  SCIP_COL** rowcols;
18302  SCIP_Real* rowvals;
18303  SCIP_Real lhs;
18304  SCIP_Real rhs;
18305  SCIP_Real sum;
18306  int nnonz;
18307 
18308  row = lp->rows[i];
18309  assert( row != NULL );
18310 
18311  /* get row data */
18312  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18313  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18314  nnonz = row->nlpcols;
18315  assert( nnonz <= lp->ncols );
18316  rowcols = row->cols;
18317  rowvals = row->vals;
18318 
18319  sum = 0.0;
18320  for( j = 0; j < nnonz; ++j )
18321  sum += rowvals[j] * primal[rowcols[j]->lppos];
18322  sum /= alpha;
18323 
18324  /* if we have an equation */
18325  if( SCIPsetIsEQ(set, lhs, rhs) )
18326  {
18327  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18328  }
18329  else
18330  {
18331  /* treat lhs */
18332  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18333  {
18334  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18335  ++cnt;
18336  }
18337  /* treat rhs */
18338  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18339  {
18340  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18341  ++cnt;
18342  }
18343  }
18344  }
18345  if( inclobjcutoff )
18346  {
18347  SCIP_Real sum;
18348 #ifndef NDEBUG
18349  SCIP_Real rhs;
18350 
18351  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18352 #endif
18353  sum = 0.0;
18354  for( j = 0; j < lp->ncols; ++j )
18355  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18356  sum /= alpha;
18357 
18358  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18359  ++cnt;
18360  }
18361  }
18362  /* check bounds */
18363  for( j = 0; j < lp->ncols; ++j )
18364  {
18365  SCIP_COL* col;
18366 #ifndef NDEBUG
18367  SCIP_Real val;
18368 #endif
18369 
18370  col = lp->cols[j];
18371  assert( col != NULL );
18372 #ifndef NDEBUG
18373  val = primal[col->lppos] / alpha;
18374 #endif
18375  /* if the variable is not fixed */
18376  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18377  {
18378  /* treat lb */
18379  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18380  {
18381  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18382  ++cnt;
18383  }
18384  /* treat rhs */
18385  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18386  {
18387  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18388  ++cnt;
18389  }
18390  }
18391  }
18392 #endif
18393 
18394  /* free */
18395  SCIPsetFreeBufferArray(set, &primal);
18396 
18397  *success = TRUE;
18398  }
18399 
18400  return SCIP_OKAY;
18401 }
18402 
18403 /** compute relative interior point
18404  *
18405  * We use the approach of@par
18406  * R. Freund, R. Roundy, M. J. Todd@par
18407  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18408  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18409  *
18410  * to compute a relative interior point for the current LP.
18411  *
18412  * Assume the original LP looks as follows:
18413  * \f[
18414  * \begin{array}{rrl}
18415  * \min & c^T x &\\
18416  * & A x & \geq a\\
18417  * & B x & \leq b\\
18418  * & D x & = d.
18419  * \end{array}
18420  * \f]
18421  * Note that bounds should be included in the system.
18422  *
18423  * To find an interior point the following LP does the job:
18424  * \f[
18425  * \begin{array}{rrl}
18426  * \max & 1^T y &\\
18427  * & A x - y - \alpha a & \geq 0\\
18428  * & B x + y - \alpha b & \leq 0\\
18429  * & D x - \alpha d & = 0\\
18430  * & 0 \leq y & \leq 1\\
18431  * & \alpha & \geq 1.
18432  * \end{array}
18433  * \f]
18434  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18435  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18436  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18437  */
18439  SCIP_SET* set, /**< global SCIP settings */
18440  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18441  SCIP_LP* lp, /**< LP data */
18442  SCIP_PROB* prob, /**< problem data */
18443  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18444  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18445  SCIP_Real timelimit, /**< time limit for LP solver */
18446  int iterlimit, /**< iteration limit for LP solver */
18447  SCIP_Real* point, /**< array to store relative interior point on exit */
18448  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18449  )
18450 {
18451  SCIP_LPI* lpi;
18452  SCIP_RETCODE retcode;
18453 
18454  assert(set != NULL);
18455  assert(lp != NULL);
18456  assert(point != NULL);
18457  assert(success != NULL);
18458 
18459  *success = FALSE;
18460 
18461  /* check time and iteration limits */
18462  if ( timelimit <= 0.0 || iterlimit <= 0 )
18463  return SCIP_OKAY;
18464 
18465  /* exit if there are no columns */
18466  assert(lp->nrows >= 0);
18467  assert(lp->ncols >= 0);
18468  if( lp->ncols == 0 )
18469  return SCIP_OKAY;
18470 
18471  /* disable objective cutoff if we have none */
18472  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18473  inclobjcutoff = FALSE;
18474 
18475  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18476 
18477  /* if there are no rows, we return the zero point */
18478  if( lp->nrows == 0 && !inclobjcutoff )
18479  {
18480  /* create zero point */
18481  BMSclearMemoryArray(point, lp->ncols);
18482  *success = TRUE;
18483 
18484  return SCIP_OKAY;
18485  }
18486 
18487  /* create auxiliary LP */
18488  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18489 
18490  /* catch return code and ensure that lpi is freed, anyway */
18491  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18492 
18493  SCIP_CALL( SCIPlpiFree(&lpi) );
18494 
18495  /* return error, unless we obtained an LP error */
18496  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18497  {
18498  SCIP_CALL( retcode );
18499  }
18500 
18501  return SCIP_OKAY;
18502 }
18503 
18504 /** computes the changes to the problem when fixing to the optimal face
18505  *
18506  * returns the degeneracy rate, i.e., the number of nonbasic variables with reduced cost 0
18507  * and the variable constraint ratio, i.e., the number of unfixed variables in relation to the basis size
18508  */
18510  SCIP_LP* lp, /**< LP data */
18511  SCIP_SET* set, /**< global SCIP settings */
18512  SCIP_STAT* stat, /**< problem statistics */
18513  SCIP_Real* degeneracy, /**< pointer to store degeneracy share */
18514  SCIP_Real* varconsratio /**< pointer to store variable constraint ratio */
18515  )
18516 {
18517  assert(lp != NULL);
18518  assert(lp->solved);
18519  assert(lp->flushed);
18520 
18521  if( lp->validdegeneracylp != stat->nlps )
18522  {
18523  lp->validdegeneracylp = stat->nlps;
18524 
18525  /* if the LP was solved to optimality, we determine the degeneracy */
18527  {
18528  SCIP_COL** cols;
18529  SCIP_ROW** rows;
18530  SCIP_COL* col;
18531  int ncols;
18532  int nrows;
18533  int nfixedcols = 0;
18534  int nalreadyfixedcols = 0;
18535  int nfixedrows = 0;
18536  int nimplicitfixedrows = 0;
18537  int nineq = 0;
18538  int c;
18539  int r;
18540  int nbasicequalities = 0;
18541 
18542  cols = lp->cols;
18543  rows = lp->rows;
18544  ncols = lp->ncols;
18545  nrows = lp->nrows;
18546 
18547  /* count number of columns that will be fixed when reducing the LP to the optimal face */
18548  for( c = ncols - 1 ; c >= 0; --c )
18549  {
18550  col = cols[c];
18551  assert(SCIPcolIsInLP(col));
18552 
18553  /* column is not basic and not fixed already */
18555  {
18556  /* variable with nonzero reduced costs are fixed */
18557  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18558  if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
18559  ++nfixedcols;
18560  else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
18561  ++nalreadyfixedcols;
18562  }
18563  }
18564 
18565  /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
18566  for( r = nrows - 1; r >= 0; --r )
18567  {
18568  SCIP_ROW* row = rows[r];
18569 
18570  assert(SCIProwIsInLP(row));
18571 
18572  if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
18573  {
18574  SCIP_Real dualsol = SCIProwGetDualsol(row);
18575 
18576  ++nineq;
18577 
18579  {
18580  /* rows with nonzero dual solution are turned into equations */
18581  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18582  if( !SCIPsetIsZero(set, dualsol) )
18583  {
18584  if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18585  {
18586  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol));
18587  ++nfixedrows;
18588  }
18589  else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18590  {
18591  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol));
18592  ++nfixedrows;
18593  }
18594  }
18595  else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
18596  || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
18597  {
18598  ++nimplicitfixedrows;
18599  }
18600  }
18601  }
18602  else if( SCIProwGetBasisStatus(row) == SCIP_BASESTAT_BASIC )
18603  ++nbasicequalities;
18604  }
18605  assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
18606 
18607  if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
18608  lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
18609  else
18610  lp->degeneracy = 0.0;
18611 
18612  if( nrows > 0 )
18613  lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
18614  else
18615  lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
18616  assert(lp->degeneracy >= 0);
18617  assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
18618  assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
18619  }
18620  else
18621  {
18622  lp->degeneracy = 0.0;
18623  lp->varconsratio = 0.0;
18624  }
18625  }
18626 
18627  *degeneracy = lp->degeneracy;
18628  *varconsratio = lp->varconsratio;
18629 
18630  return SCIP_OKAY;
18631 }
SCIP_EXPORT SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:522
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17407
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:396
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:7104
SCIP_Longint nprimallps
Definition: struct_stat.h:182
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3678
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:17736
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4740
SCIP_EXPORT 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
int firstnewrow
Definition: struct_lp.h:326
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16361
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6496
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13135
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:4696
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:93
void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:10250
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:362
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17263
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5987
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6290
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2531
SCIP_EXPORT int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3325
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2849
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6691
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17035
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:4288
SCIP_EXPORT SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3893
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:459
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2737
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:13669
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8924
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:10146
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17724
SCIP_EXPORT const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:445
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2824
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7353
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6045
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17500
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6495
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:2955
void * origin
Definition: struct_lp.h:216
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:222
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17174
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:4929
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13972
SCIP_STATUS status
Definition: struct_stat.h:174
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17682
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:1850
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:17089
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9691
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17619
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:2383
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6308
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3633
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1387
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:101
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:198
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:5894
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6675
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:79
int * cols_index
Definition: struct_lp.h:219
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3634
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:16228
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:7169
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2843
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15583
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:18438
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:891
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3104
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:904
int nchgrows
Definition: struct_lp.h:315
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:223
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8659
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9858
char * name
Definition: struct_lp.h:217
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6262
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:3502
int nlpicols
Definition: struct_lp.h:307
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6385
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:530
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:15552
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6410
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17554
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17283
SCIP_Longint nlps
Definition: struct_stat.h:180
SCIP_EXPORT SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18054
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_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6628
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:344
#define SCIP_MAXSTRLEN
Definition: def.h:273
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7993
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2953
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1677
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6160
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17023
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17511
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:69
internal methods for clocks and timing issues
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:13546
int lpdepth
Definition: struct_lp.h:232
SCIP_EXPORT SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:17815
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6110
SCIP_EXPORT SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3508
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:112
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:16934
SCIP_Real objsumnorm
Definition: struct_lp.h:283
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17075
SCIP_Longint ndivinglps
Definition: struct_stat.h:195
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_ROW ** chgrows
Definition: struct_lp.h:290
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5327
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:5573
SCIP_EXPORT SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2454
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:15172
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:15097
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9022
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11963
int rank
Definition: struct_lp.h:239
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16988
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:1019
interface methods for specific LP solvers
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5852
SCIP_EXPORT SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1948
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1254
int rowssize
Definition: struct_lp.h:323
SCIP_EXPORT 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
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8889
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3687
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7885
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13214
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:14924
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13863
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14151
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:615
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11466
unsigned int nonlprowssorted
Definition: struct_lp.h:172
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16881
int nclockskipsleft
Definition: struct_stat.h:263
SCIP_COL ** cols
Definition: struct_lp.h:291
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10085
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1290
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7776
int nlpirows
Definition: struct_lp.h:310
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:105
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17120
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:139
int soldirectionsize
Definition: struct_lp.h:317
SCIP_EXPORT SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17197
#define debugColPrint(x, y)
Definition: lp.c:145
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:3268
static const int nscalars
Definition: lp.c:5732
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:13836
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:73
int lppos
Definition: struct_lp.h:163
SCIP_Real lazylb
Definition: struct_lp.h:132
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:16397
#define EPSEQ(x, y, eps)
Definition: def.h:188
#define EPSISINT(x, eps)
Definition: def.h:200
int pseudoobjvalinf
Definition: struct_lp.h:330
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17672
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17013
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:289
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13904
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6528
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:765
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3608
int divinglpiitlim
Definition: struct_lp.h:334
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17515
SCIP_EXPORT SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2488
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:1684
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_Longint nrootlps
Definition: struct_stat.h:181
SCIP_Bool dualchecked
Definition: struct_lp.h:361
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:17243
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6099
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16375
#define TRUE
Definition: def.h:72
#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:8216
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Bool lpifromscratch
Definition: struct_lp.h:375
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3335
SCIP_EXPORT SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1992
unsigned int basisstatus
Definition: struct_lp.h:240
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2780
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6796
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10019
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:17587
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16215
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1685
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:457
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2571
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:5464
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3578
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:16158
unsigned int delaysort
Definition: struct_lp.h:243
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5580
#define SCIP_UNUSED(x)
Definition: def.h:418
unsigned int basisstatus
Definition: struct_lp.h:170
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
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:15521
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16845
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6196
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3081
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:9045
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:336
public methods for problem variables
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:115
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6952
SCIP_EXPORT SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2676
SCIP_EXPORT SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:977
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1894
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:15979
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:5969
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:2930
SCIP_Real dualfarkas
Definition: struct_lp.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:12371
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:155
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12289
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition: set.c:5966
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17447
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:7907
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:13587
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13246
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6739
SCIP_Real rootlooseobjval
Definition: struct_lp.h:273
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16815
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
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:3553
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:15760
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3457
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10160
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17363
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:15112
unsigned int integral
Definition: struct_lp.h:248
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:456
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:10126
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1123
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:102
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6121
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:3016
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1052
#define SCIP_LONGINT_MAX
Definition: def.h:149
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:154
int lpifirstchgcol
Definition: struct_lp.h:308
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1692
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:137
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16200
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2543
#define checkRow(row)
Definition: lp.c:681
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6341
int maxdepth
Definition: struct_stat.h:224
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:9019
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:5516
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:287
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17273
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13047
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition: lp.c:269
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4728
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:54
int lazycolssize
Definition: struct_lp.h:319
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14064
Definition: heur_padm.c:125
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:849
SCIP_Real objprod
Definition: struct_lp.h:201
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16825
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:17565
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:16161
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_Bool primalchecked
Definition: struct_lp.h:359
real eps
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3262
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17303
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:17130
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_EXPORT SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2706
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16871
#define checkLinks(lp)
Definition: lp.c:1610
int lpithreads
Definition: struct_lp.h:337
int ndivechgsides
Definition: struct_lp.h:332
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17437
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12262
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11545
#define SCIP_DEFAULT_EPSILON
Definition: def.h:169
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:11548
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6081
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17385
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:6849
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2339
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int integral
Definition: struct_lp.h:177
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4304
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:1971
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17575
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3836
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4819
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6147
int divechgsidessize
Definition: struct_lp.h:333
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6027
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:15721
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17065
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:6254
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:39
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:10043
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:10912
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_EXPORT 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
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:7821
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:3436
int glbpseudoobjvalinf
Definition: struct_lp.h:329
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17478
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13931
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:453
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2465
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14196
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:483
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15873
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6707
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1408
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:16185
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5654
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
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:8167
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:16412
SCIP_Bool installing
Definition: struct_lp.h:366
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17208
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17100
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:392
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2391
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:17652
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:4889
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3424
#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:3218
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14274
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17662
SCIP_EXPORT SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2004
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:178
SCIP_Bool lpilpinfo
Definition: struct_lp.h:377
SCIP_EXPORT SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2722
SCIP_EXPORT SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:17805
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:9436
SCIP_Bool dualchecked
Definition: struct_lp.h:114
SCIP_COL ** cols
Definition: struct_lp.h:218
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:988
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9619
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17427
SCIP_EXPORT SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:3975
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:4071
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIPInterval sqrt(const SCIPInterval &x)
SCIP_EXPORT SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:859
SCIP_ROW ** lpirows
Definition: struct_lp.h:288
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:189
SCIP_Longint validsoldirlp
Definition: struct_lp.h:303
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:471
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:15650
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8611
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5718
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17110
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:17223
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:9933
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9776
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5922
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:17002
#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
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:2029
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
SCIP_EXPORT SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1638
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:6324
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14586
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6136
SCIP_Real cutoffbound
Definition: struct_lp.h:274
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6438
SCIP_EXPORT SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:828
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:9495
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:17542
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6662
int numintcols
Definition: struct_lp.h:235
SCIP_EXPORT void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
#define REALABS(x)
Definition: def.h:187
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:299
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17417
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1731
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2694
SCIP_Bool looseobjvalid
Definition: struct_lp.h:348
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:364
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition: lp.c:10225
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_EXPORT SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1158
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16858
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6473
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6514
SCIP_EXPORT 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
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17457
SCIP_EXPORT 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
int lpirandomseed
Definition: struct_lp.h:339
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16835
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:17702
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
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8364
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11457
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3609
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17338
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6009
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real objlim, SCIP_Bool *success)
Definition: lp.c:2643
#define lpCutoffDisabled(set)
Definition: lp.c:2636
int lpicolssize
Definition: struct_lp.h:306
SCIP_EXPORT SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17609
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13063
SCIP_LPI * lpi
Definition: struct_lp.h:286
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5287
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2422
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1805
SCIP_EXPORT 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_Real glbpseudoobjval
Definition: struct_lp.h:266
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:17202
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6429
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6896
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:189
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:2286
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4169
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6723
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:157
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:1510
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:8997
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8849
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5340
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:11994
SCIP_Longint nduallps
Definition: struct_stat.h:184
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6454
SCIP_Real sblpobjval
Definition: struct_lp.h:147
SCIP_EXPORT SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17381
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:456
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition: lp.c:10215
internal methods for problem variables
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7958
#define SCIP_UNKNOWN
Definition: def.h:184
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17187
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9802
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6132
int nchgcols
Definition: struct_lp.h:313
public data structures and miscellaneous methods
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17045
SCIP_EXPORT void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
int len
Definition: struct_lp.h:160
SCIP_Real * soldirection
Definition: struct_lp.h:294
SCIP_EXPORT 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_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17599
SCIP_RETCODE SCIPlpGetDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
Definition: lp.c:18509
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9757
#define SCIP_Bool
Definition: def.h:70
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13146
SCIP_EXPORT SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1796
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:17233
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:17142
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5884
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:190
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:445
int numminval
Definition: struct_lp.h:237
int lpipos
Definition: struct_lp.h:231
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:17253
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:807
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15271
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:9357
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6037
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:103
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3888
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 SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: cons.c:6195
int chgrowssize
Definition: struct_lp.h:314
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17489
SCIP_Longint validfarkaslp
Definition: struct_lp.h:155
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:312
unsigned int lbchanged
Definition: struct_lp.h:174
SCIP_EXPORT SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17779
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:9836
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:458
SCIP_Longint sbnode
Definition: struct_lp.h:148
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
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17374
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17692
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:3746
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3819
#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:1087
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:16945
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17154
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition: lp.c:3129
SCIP_EXPORT SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17525
SCIP_Real degeneracy
Definition: struct_lp.h:284
SCIP_Bool updateintegrality
Definition: struct_lp.h:355
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:9062
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1426
#define SCIPsetDebugMsg
Definition: set.h:1721
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_EXPORT int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3312
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:385
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1700
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:4199
int minidx
Definition: struct_lp.h:233
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2170
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2275
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:390
SCIP_EXPORT SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1231
SCIP_EXPORT SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2633
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
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:5418
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9065
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9819
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:3411
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9788
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3175
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:17396
SCIP_CLOCK * resolveinstablelptime
Definition: struct_stat.h:156
static void colSortLP(SCIP_COL *col)
Definition: lp.c:955
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13690
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6853
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6912
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:246
SCIP_Real ub
Definition: struct_lp.h:130
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6004
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15799
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6407
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6218
SCIP_ROW ** rows
Definition: struct_lp.h:293
SCIP_SOL * validsoldirsol
Definition: struct_lp.h:300
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
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:3791
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1201
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:295
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10102
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3151
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:7845
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3366
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3396
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12351
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1162
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10232
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16904
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_EXPORT int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2738
SCIP_Real flushedrhs
Definition: struct_lp.h:198
int SCIPcolGetAge(SCIP_COL *col)
Definition: lp.c:17055
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:13374
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:154
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:6996
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9402
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:4473
#define SCIP_REAL_MAX
Definition: def.h:164
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6717
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7712
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6607
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:13505
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:11237
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
#define checkRowObjprod(row)
Definition: lp.c:756
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13102
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16251
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8151
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:13276
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:567
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:2607
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:158
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
methods for sorting joint arrays of various types
SCIP_COL ** lazycols
Definition: struct_lp.h:292
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition: lp.c:16924
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:1452
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:268
SCIP_EXPORT SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2542
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:15369
SCIP_VAR ** b
Definition: circlepacking.c:56
SCIP_EXPORT SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2474
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13122
SCIP_Real lpimarkowitz
Definition: struct_lp.h:281
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6837
int age
Definition: struct_lp.h:168
SCIP_EXPORT 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
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3375
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:210
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:150
SCIP_EXPORT SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2507
void SCIPconsCapture(SCIP_CONS *cons)
Definition: cons.c:6183
SCIP_Real * vals
Definition: struct_lp.h:153
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6586
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:369
SCIP_Real rellooseobjval
Definition: struct_lp.h:264
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8963
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10170
static const SCIP_Real scalars[]
Definition: lp.c:5731
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
SCIP_EXPORT SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8721
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1619
SCIP_Real rootlpobjval
Definition: struct_lp.h:272
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1837
SCIP_EXPORT SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:634
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:143
unsigned int coefchanged
Definition: struct_lp.h:247
SCIP_EXPORT SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3415
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17353
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:148
SCIP_Longint nbarrierlps
Definition: struct_stat.h:187
SCIP_Bool flushed
Definition: struct_lp.h:356
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8512
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16977
SCIP_CLOCK * primallptime
Definition: struct_stat.h:152
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13782
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6352
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:138
int lpdepth
Definition: struct_lp.h:165
unsigned int inglobalcutpool
Definition: struct_lp.h:252
int nrows
Definition: struct_lp.h:324
#define checkRowSqrnorm(row)
Definition: lp.c:754
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:15445
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:170
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14017
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:16966
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:177
public methods for message output
data structures for LP management
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4760
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
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
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:6242
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6063
datastructures for problem variables
int ndivingrows
Definition: struct_lp.h:331
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:10290
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:163
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17642
int size
Definition: struct_lp.h:159
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5381
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7788
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6506
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_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8097
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition: lp.c:17318
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:5904
#define SCIPsetDebugMsgPrint
Definition: set.h:1722
int lpirowssize
Definition: struct_lp.h:309
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17213
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:5099
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4150
#define BMSallocMemory(ptr)
Definition: memory.h:111
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14253
#define SCIP_INVALID
Definition: def.h:183
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:119
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:5686
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17632
SCIP_EXPORT 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_CLOCK * duallptime
Definition: struct_stat.h:153
void SCIPprintSysError(const char *message)
Definition: misc.c:10513
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:148
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6706
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10267
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3039
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14863
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2980
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:5735
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:6451
SCIP_VAR * var
Definition: struct_lp.h:151
SCIP_EXPORT SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2436
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9884
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7866
int nlazycols
Definition: struct_lp.h:320
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16893
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:335
SCIP_Bool dualfeasible
Definition: struct_lp.h:360
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6659
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3227
SCIP_EXPORT SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1871
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4124
SCIP_EXPORT SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3489
SCIP_EXPORT int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17360
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2907
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6212
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:11519
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:936
unsigned int nlocks
Definition: struct_lp.h:254
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2880
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:443
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17164
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6728
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3782
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3965
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9909
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14129
SCIP_Longint obsoletenode
Definition: struct_lp.h:212
SCIP_Longint nnodes
Definition: struct_stat.h:73
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5366
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:13316
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:913
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4253
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13993
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:1482
#define SCIP_CALL_ABORT(x)
Definition: def.h:343
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3188
SCIP_EXPORT SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:1009
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17467
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:5397
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:3941
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:14292
#define SCIP_ALLOC(x)
Definition: def.h:375
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:13091
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6383
#define SCIPABORT()
Definition: def.h:336
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2905
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:200
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:2230
SCIP_EXPORT SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2818
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6618
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2504
unsigned int nonlpcolssorted
Definition: struct_lp.h:242
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:10639
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:10448
int ncols
Definition: struct_lp.h:318
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2596
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4184
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17713
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:449
SCIP_Real objsqrnorm
Definition: struct_lp.h:282
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition: set.c:5914
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1350
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3651
unsigned int local
Definition: struct_lp.h:249
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5247
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_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6517
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16914
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3241
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:12173
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16955
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9566
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:11374
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:5628
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:948
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:4019
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:3154
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17293
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:755