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-2018 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lp.c
17  * @brief LP management methods and data structures
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Marc Pfetsch
21  * @author Kati Wolter
22  * @author Gerald Gamrath
23  *
24  * In LP management, we have to differ between the current LP and the SCIP_LP
25  * stored in the LP solver. All LP methods affect the current LP only.
26  * Before solving the current LP with the LP solver or setting an LP state,
27  * the LP solvers data has to be updated to the current LP with a call to
28  * lpFlush().
29  */
30 
31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32 
33 
34 #include "lpi/lpi.h"
35 #include "scip/clock.h"
36 #include "scip/cons.h"
37 #include "scip/event.h"
38 #include "scip/intervalarith.h"
39 #include "scip/lp.h"
40 #include "scip/misc.h"
41 #include "scip/prob.h"
42 #include "scip/pub_lp.h"
43 #include "scip/pub_message.h"
44 #include "scip/pub_misc.h"
45 #include "scip/pub_misc_sort.h"
46 #include "scip/pub_var.h"
47 #include "scip/set.h"
48 #include "scip/sol.h"
49 #include "scip/solve.h"
50 #include "scip/stat.h"
51 #include "scip/struct_event.h"
52 #include "scip/struct_lp.h"
53 #include "scip/struct_prob.h"
54 #include "scip/struct_set.h"
55 #include "scip/struct_stat.h"
56 #include "scip/struct_var.h"
57 #include "scip/var.h"
58 #include <string.h>
59 
60 
61 
62 /*
63  * debug messages
64  */
65 
66 #ifdef SCIP_DEBUG
67 /** method is to print in row in case SCIP_DEBUG is defined */
68 static
69 void debugRowPrint(
70  SCIP_SET* set, /**< global SCIP settings */
71  SCIP_ROW* row /**< LP row */
72  )
73 {
74  int i;
75 
76  assert(row != NULL);
77 
78  /* print row name */
79  if( row->name != NULL && row->name[0] != '\0' )
80  {
81  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
82  }
83 
84  /* print left hand side */
85  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
86 
87  /* print coefficients */
88  if( row->len == 0 )
89  {
90  SCIPsetDebugMsgPrint(set, "0 ");
91  }
92  for( i = 0; i < row->len; ++i )
93  {
94  assert(row->cols[i] != NULL);
95  assert(row->cols[i]->var != NULL);
96  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
97  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
98  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
99  }
100 
101  /* print constant */
103  {
104  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
105  }
106 
107  /* print right hand side */
108  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
109 }
110 #else
111 #define debugRowPrint(x,y) /**/
112 #endif
113 
114 #ifdef SCIP_DEBUG
115 /** method to output column if SCIP_DEBUG is define */
116 static
117 void debugColPrint(
118  SCIP_SET* set, /**< global SCIP settings */
119  SCIP_COL* col /**< LP column */
120  )
121 {
122  int r;
123 
124  assert(col != NULL);
125  assert(col->var != NULL);
126 
127  /* print bounds */
128  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
129 
130  /* print coefficients */
131  if( col->len == 0 )
132  {
133  SCIPsetDebugMsgPrint(set, "<empty>");
134  }
135  for( r = 0; r < col->len; ++r )
136  {
137  assert(col->rows[r] != NULL);
138  assert(col->rows[r]->name != NULL);
139  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
140  }
141  SCIPsetDebugMsgPrint(set, "\n");
142 }
143 #else
144 #define debugColPrint(x,y) /**/
145 #endif
146 
147 /*
148  * memory growing methods for dynamically allocated arrays
149  */
150 
151 /** ensures, that chgcols array can store at least num entries */
152 static
154  SCIP_LP* lp, /**< current LP data */
155  SCIP_SET* set, /**< global SCIP settings */
156  int num /**< minimum number of entries to store */
157  )
158 {
159  assert(lp->nchgcols <= lp->chgcolssize);
160 
161  if( num > lp->chgcolssize )
162  {
163  int newsize;
164 
165  newsize = SCIPsetCalcMemGrowSize(set, num);
166  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
167  lp->chgcolssize = newsize;
168  }
169  assert(num <= lp->chgcolssize);
170 
171  return SCIP_OKAY;
172 }
173 
174 /** ensures, that chgrows array can store at least num entries */
175 static
177  SCIP_LP* lp, /**< current LP data */
178  SCIP_SET* set, /**< global SCIP settings */
179  int num /**< minimum number of entries to store */
180  )
181 {
182  assert(lp->nchgrows <= lp->chgrowssize);
183 
184  if( num > lp->chgrowssize )
185  {
186  int newsize;
187 
188  newsize = SCIPsetCalcMemGrowSize(set, num);
189  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
190  lp->chgrowssize = newsize;
191  }
192  assert(num <= lp->chgrowssize);
193 
194  return SCIP_OKAY;
195 }
196 
197 /** ensures, that lpicols array can store at least num entries */
198 static
200  SCIP_LP* lp, /**< current LP data */
201  SCIP_SET* set, /**< global SCIP settings */
202  int num /**< minimum number of entries to store */
203  )
204 {
205  assert(lp->nlpicols <= lp->lpicolssize);
206 
207  if( num > lp->lpicolssize )
208  {
209  int newsize;
210 
211  newsize = SCIPsetCalcMemGrowSize(set, num);
212  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
213  lp->lpicolssize = newsize;
214  }
215  assert(num <= lp->lpicolssize);
216 
217  return SCIP_OKAY;
218 }
219 
220 /** ensures, that lpirows array can store at least num entries */
221 static
223  SCIP_LP* lp, /**< current LP data */
224  SCIP_SET* set, /**< global SCIP settings */
225  int num /**< minimum number of entries to store */
226  )
227 {
228  assert(lp->nlpirows <= lp->lpirowssize);
229 
230  if( num > lp->lpirowssize )
231  {
232  int newsize;
233 
234  newsize = SCIPsetCalcMemGrowSize(set, num);
235  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
236  lp->lpirowssize = newsize;
237  }
238  assert(num <= lp->lpirowssize);
239 
240  return SCIP_OKAY;
241 }
242 
243 /** ensures, that cols array can store at least num entries */
244 static
246  SCIP_LP* lp, /**< current LP data */
247  SCIP_SET* set, /**< global SCIP settings */
248  int num /**< minimum number of entries to store */
249  )
250 {
251  assert(lp->ncols <= lp->colssize);
252 
253  if( num > lp->colssize )
254  {
255  int newsize;
256 
257  newsize = SCIPsetCalcMemGrowSize(set, num);
258  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
259  lp->colssize = newsize;
260  }
261  assert(num <= lp->colssize);
262 
263  return SCIP_OKAY;
264 }
265 
266 /** ensures, that soldirection array can store at least num entries */
267 static
269  SCIP_LP* lp, /**< current LP data */
270  int num /**< minimum number of entries to store */
271  )
272 {
273  if( num > lp->soldirectionsize )
274  {
277 
278  lp->soldirectionsize = num;
279  }
280 
281  assert(num <= lp->soldirectionsize);
282 
283  return SCIP_OKAY;
284 }
285 
286 /** ensures, that lazy cols array can store at least num entries */
287 static
289  SCIP_LP* lp, /**< current LP data */
290  SCIP_SET* set, /**< global SCIP settings */
291  int num /**< minimum number of entries to store */
292  )
293 {
294  assert(lp->nlazycols <= lp->lazycolssize);
295 
296  if( num > lp->lazycolssize )
297  {
298  int newsize;
299 
300  newsize = SCIPsetCalcMemGrowSize(set, num);
301  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
302  lp->lazycolssize = newsize;
303  }
304  assert(num <= lp->lazycolssize);
305 
306  return SCIP_OKAY;
307 }
308 
309 /** ensures, that rows array can store at least num entries */
310 static
312  SCIP_LP* lp, /**< current LP data */
313  SCIP_SET* set, /**< global SCIP settings */
314  int num /**< minimum number of entries to store */
315  )
316 {
317  assert(lp->nrows <= lp->rowssize);
318 
319  if( num > lp->rowssize )
320  {
321  int newsize;
322 
323  newsize = SCIPsetCalcMemGrowSize(set, num);
324  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
325  lp->rowssize = newsize;
326  }
327  assert(num <= lp->rowssize);
328 
329  return SCIP_OKAY;
330 }
331 
332 /** ensures, that row array of column can store at least num entries */
333 static
335  SCIP_COL* col, /**< LP column */
336  BMS_BLKMEM* blkmem, /**< block memory */
337  SCIP_SET* set, /**< global SCIP settings */
338  int num /**< minimum number of entries to store */
339  )
340 {
341  assert(col != NULL);
342  assert(col->len <= col->size);
343 
344  if( num > col->size )
345  {
346  int newsize;
347 
348  newsize = SCIPsetCalcMemGrowSize(set, num);
349  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
350  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
351  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
352  col->size = newsize;
353  }
354  assert(num <= col->size);
355 
356  return SCIP_OKAY;
357 }
358 
359 /** save current LP values dependent on the solution */
360 static
362  SCIP_LP* lp, /**< LP data */
363  SCIP_STAT* stat, /**< problem statistics */
364  BMS_BLKMEM* blkmem /**< block memory */
365  )
366 {
367  SCIP_LPSOLVALS* storedsolvals;
368 
369  assert(lp != NULL);
370  assert(stat != NULL);
371  assert(blkmem != NULL);
372 
373  /* allocate memory for storage */
374  if( lp->storedsolvals == NULL )
375  {
377  }
378  storedsolvals = lp->storedsolvals;
379 
380  /* store values */
381  storedsolvals->lpsolstat = lp->lpsolstat;
382  storedsolvals->lpobjval = lp->lpobjval;
383  storedsolvals->primalfeasible = lp->primalfeasible;
384  storedsolvals->primalchecked = lp->primalchecked;
385  storedsolvals->dualfeasible = lp->dualfeasible;
386  storedsolvals->dualchecked = lp->dualchecked;
387  storedsolvals->solisbasic = lp->solisbasic;
388  storedsolvals->lpissolved = lp->solved;
389 
390  return SCIP_OKAY;
391 }
392 
393 /** restore LP solution values in column */
394 static
396  SCIP_LP* lp, /**< LP data */
397  BMS_BLKMEM* blkmem, /**< block memory */
398  SCIP_Longint validlp /**< number of lp for which restored values are valid */
399  )
400 {
401  SCIP_LPSOLVALS* storedsolvals;
402 
403  assert(lp != NULL);
404  assert(blkmem != NULL);
405 
406  /* if stored values are available, restore them */
407  storedsolvals = lp->storedsolvals;
408  if( storedsolvals != NULL )
409  {
410  lp->solved = storedsolvals->lpissolved;
411  lp->validsollp = validlp;
412 
413  lp->lpsolstat = storedsolvals->lpsolstat;
414  lp->lpobjval = storedsolvals->lpobjval;
415  lp->primalfeasible = storedsolvals->primalfeasible;
416  lp->primalchecked = storedsolvals->primalchecked;
417  lp->dualfeasible = storedsolvals->dualfeasible;
418  lp->dualchecked = storedsolvals->dualchecked;
419  lp->solisbasic = storedsolvals->solisbasic;
420 
421  /* solution values are stored only for LPs solved to optimality or unboundedness */
422  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
428  lp->validsollp == -1);
429  }
430  /* no values available, mark LP as unsolved */
431  else
432  {
433  lp->solved = FALSE;
434  lp->validsollp = -1;
435 
437  lp->lpobjval = SCIP_INVALID;
438  lp->primalfeasible = FALSE;
439  lp->primalchecked = FALSE;
440  lp->dualfeasible = FALSE;
441  lp->dualchecked = FALSE;
442  lp->solisbasic = FALSE;
443  lp->validfarkaslp = -1;
444  }
445 
446  /* intentionally keep storage space allocated */
447 
448  return SCIP_OKAY;
449 }
450 
451 /** save current LP solution values stored in each column */
452 static
454  SCIP_COL* col, /**< LP column */
455  BMS_BLKMEM* blkmem /**< block memory */
456  )
457 {
458  SCIP_COLSOLVALS* storedsolvals;
459 
460  assert(col != NULL);
461  assert(blkmem != NULL);
462 
463  /* allocate memory for storage */
464  if( col->storedsolvals == NULL )
465  {
466  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
467  }
468  storedsolvals = col->storedsolvals;
469 
470  /* store values */
471  storedsolvals->primsol = col->primsol;
472  storedsolvals->redcost = col->redcost;
473  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
474 
475  return SCIP_OKAY;
476 }
477 
478 /** restore LP solution values in column */
479 static
481  SCIP_COL* col, /**< LP column */
482  BMS_BLKMEM* blkmem, /**< block memory */
483  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
484  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
485  )
486 {
487  SCIP_COLSOLVALS* storedsolvals;
488 
489  assert(col != NULL);
490  assert(blkmem != NULL);
491 
492  /* if stored values are available, restore them */
493  storedsolvals = col->storedsolvals;
494  if( storedsolvals != NULL )
495  {
496  col->primsol = storedsolvals->primsol;
497  col->redcost = storedsolvals->redcost;
498  col->validredcostlp = validlp;
499  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
500 
501  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
502  col->validfarkaslp = -1;
503  }
504  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
505  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
506  */
507  else
508  {
509  col->primsol = 0.0;
510  col->validredcostlp = -1;
511  col->validfarkaslp = -1;
512  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
513  }
514 
515  /* free memory */
516  if( freebuffer )
517  {
518  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
519  assert(col->storedsolvals == NULL);
520  }
521 
522  return SCIP_OKAY;
523 }
524 
525 /** save current LP solution values stored in each column */
526 static
528  SCIP_ROW* row, /**< LP row */
529  BMS_BLKMEM* blkmem, /**< block memory */
530  SCIP_Bool infeasible /**< is the solution infeasible? */
531  )
532 {
533  SCIP_ROWSOLVALS* storedsolvals;
534 
535  assert(row != NULL);
536  assert(blkmem != NULL);
537 
538  /* allocate memory for storage */
539  if( row->storedsolvals == NULL )
540  {
541  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
542  }
543  storedsolvals = row->storedsolvals;
544 
545  /* store values */
546  if ( infeasible )
547  {
548  storedsolvals->dualsol = row->dualfarkas;
549  storedsolvals->activity = SCIP_INVALID;
550  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
551  }
552  else
553  {
554  storedsolvals->dualsol = row->dualsol;
555  storedsolvals->activity = row->activity;
556  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
557  }
558 
559  return SCIP_OKAY;
560 }
561 
562 /** restore LP solution values in row */
563 static
565  SCIP_ROW* row, /**< LP column */
566  BMS_BLKMEM* blkmem, /**< block memory */
567  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
568  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
569  SCIP_Bool infeasible /**< is the solution infeasible? */
570  )
571 {
572  SCIP_ROWSOLVALS* storedsolvals;
573 
574  assert(row != NULL);
575  assert(blkmem != NULL);
576 
577  /* if stored values are available, restore them */
578  storedsolvals = row->storedsolvals;
579  if( storedsolvals != NULL )
580  {
581  if ( infeasible )
582  row->dualfarkas = storedsolvals->dualsol;
583  else
584  row->dualsol = storedsolvals->dualsol;
585  row->activity = storedsolvals->activity;
586  row->validactivitylp = validlp;
587  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
588  }
589  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
590  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
591  */
592  else
593  {
594  row->dualsol = 0.0;
595  row->dualfarkas = 0.0;
596  row->activity = SCIP_INVALID;
597  row->validactivitylp = -1;
598  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
599  }
600 
601  /* free memory */
602  if( freebuffer )
603  {
604  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
605  assert(row->storedsolvals == NULL);
606  }
607 
608  return SCIP_OKAY;
609 }
610 
611 /** ensures, that column array of row can store at least num entries */
613  SCIP_ROW* row, /**< LP row */
614  BMS_BLKMEM* blkmem, /**< block memory */
615  SCIP_SET* set, /**< global SCIP settings */
616  int num /**< minimum number of entries to store */
617  )
618 {
619  assert(row != NULL);
620  assert(row->len <= row->size);
621 
622  if( num > row->size )
623  {
624  int newsize;
625 
626  newsize = SCIPsetCalcMemGrowSize(set, num);
627  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
628  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
629  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
630  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
631  row->size = newsize;
632  }
633  assert(num <= row->size);
634 
635  return SCIP_OKAY;
636 }
637 
638 
639 #if 0 /* enable this to check the sortings within rows (for debugging, very slow!) */
640 static SCIP_Bool msgdisp_checkrow = FALSE;
641 
642 static
643 void checkRow(
644  SCIP_ROW* row
645  )
646 {
647  int i;
648 
649  if( !msgdisp_checkrow )
650  {
651  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
652  msgdisp_checkrow = TRUE;
653  }
654 
655  /* validate sorting of LP part of row */
656  if( row->lpcolssorted && row->nlpcols > 0)
657  {
658  assert(row->cols_index[0] == row->cols[0]->index);
659  for( i = 1; i < row->nlpcols; ++i )
660  {
661  assert(row->cols_index[i] == row->cols[i]->index);
662  assert(row->cols_index[i] >= row->cols_index[i-1]);
663  }
664  }
665 
666  /* validate sorting of non-LP part of row */
667  if( row->nonlpcolssorted && row->len > row->nlpcols )
668  {
669  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
670  for( i = row->nlpcols + 1; i < row->len; ++i )
671  {
672  assert(row->cols_index[i] == row->cols[i]->index);
673  assert(row->cols_index[i] >= row->cols_index[i-1]);
674  }
675  }
676 }
677 #else
678 #define checkRow(row) /**/
679 #endif
680 
681 #if 0 /* enable this to check norms of rows (for debugging, very slow!) */
682 static
683 void checkRowSqrnorm(
684  SCIP_ROW* row
685  )
686 {
687  SCIP_COL** cols;
688  SCIP_Real sqrnorm;
689  int c;
690 
691  cols = row->cols;
692  assert(cols != NULL || row->len == 0);
693 
694  sqrnorm = 0.0;
695 
696  for( c = row->len - 1; c >= 0; --c )
697  {
698  if( cols[c]->lppos >= 0 )
699  sqrnorm += SQR(row->vals[c]);
700  }
701 
702  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
703 }
704 
705 static
706 void checkRowSumnorm(
707  SCIP_ROW* row
708  )
709 {
710  SCIP_COL** cols;
711  SCIP_Real sumnorm;
712  int c;
713 
714  cols = row->cols;
715  assert(cols != NULL || row->len == 0);
716 
717  sumnorm = 0.0;
718 
719  for( c = row->len - 1; c >= 0; --c )
720  {
721  if( cols[c]->lppos >= 0 )
722  sumnorm += REALABS(row->vals[c]);
723  }
724 
725  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
726 }
727 
728 static
729 void checkRowObjprod(
730  SCIP_ROW* row
731  )
732 {
733  SCIP_COL** cols;
734  SCIP_Real objprod;
735  int c;
736 
737  cols = row->cols;
738  assert(cols != NULL || row->len == 0);
739 
740  objprod = 0.0;
741 
742  for( c = row->len - 1; c >= 0; --c )
743  {
744  if( cols[c]->lppos >= 0 )
745  objprod += row->vals[c] * cols[c]->unchangedobj;
746  }
747 
748  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
749 }
750 #else
751 #define checkRowSqrnorm(row) /**/
752 #define checkRowSumnorm(row) /**/
753 #define checkRowObjprod(row) /**/
754 #endif
755 
756 /*
757  * Local methods for pseudo and loose objective values
758  */
759 
760 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
761 static
763  SCIP_LP* lp, /**< current LP data */
764  SCIP_SET* set, /**< global SCIP settings */
765  SCIP_PROB* prob /**< problem data */
766  )
767 {
768  SCIP_VAR** vars;
769  SCIP_Real obj;
770  int nvars;
771  int v;
772 
773  assert(lp != NULL);
774  assert(set != NULL);
775  assert(prob != NULL);
776  assert(!lp->looseobjvalid);
777 
778  vars = prob->vars;
779  nvars = prob->nvars;
780  lp->looseobjval = 0.0;
781 
782  /* iterate over all variables in the problem */
783  for( v = 0; v < nvars; ++v )
784  {
785  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
786  {
787  obj = SCIPvarGetObj(vars[v]);
788 
789  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
790  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
791  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
792  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
793  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
794  }
795  }
796 
797  /* the recomputed value is reliable */
798  lp->rellooseobjval = lp->looseobjval;
799  lp->looseobjvalid = TRUE;
800 }
801 
802 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
803 static
805  SCIP_LP* lp, /**< current LP data */
806  SCIP_SET* set, /**< global SCIP settings */
807  SCIP_PROB* prob /**< problem data */
808  )
809 {
810  SCIP_VAR** vars;
811  int nvars;
812  int v;
813 
814  assert(lp != NULL);
815  assert(set != NULL);
816  assert(prob != NULL);
817  assert(!lp->pseudoobjvalid);
818 
819  vars = prob->vars;
820  nvars = prob->nvars;
821  lp->pseudoobjval = 0.0;
822 
823  /* iterate over all variables in the problem */
824  for( v = 0; v < nvars; ++v )
825  {
826  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
827  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
828  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
829  {
830  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
831  }
832  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
833  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
834  {
835  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
836  }
837  }
838 
839  /* the recomputed value is reliable */
840  lp->relpseudoobjval = lp->pseudoobjval;
841  lp->pseudoobjvalid = TRUE;
842 }
843 
844 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
845 static
847  SCIP_LP* lp, /**< current LP data */
848  SCIP_SET* set, /**< global SCIP settings */
849  SCIP_PROB* prob /**< problem data */
850  )
851 {
852  SCIP_VAR** vars;
853  int nvars;
854  int v;
855 
856  assert(lp != NULL);
857  assert(set != NULL);
858  assert(prob != NULL);
859  assert(!lp->glbpseudoobjvalid);
860 
861  vars = prob->vars;
862  nvars = prob->nvars;
863  lp->glbpseudoobjval = 0.0;
864 
865  /* iterate over all variables in the problem */
866  for( v = 0; v < nvars; ++v )
867  {
868  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
869  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
870  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
871  {
872  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
873  }
874  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
875  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
876  {
877  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
878  }
879  }
880 
881  /* the recomputed value is reliable */
883  lp->glbpseudoobjvalid = TRUE;
884 }
885 
886 /** gets finite part of objective value of current LP that results from LOOSE variables only */
887 static
889  SCIP_LP* lp, /**< current LP data */
890  SCIP_SET* set, /**< global SCIP settings */
891  SCIP_PROB* prob /**< problem data */
892  )
893 {
894  assert(lp != NULL);
895  assert(set != NULL);
896  assert(prob != NULL);
897  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
898  assert(lp->flushed);
899  assert(lp->looseobjvalinf == 0);
900 
901  /* recalculate the loose objective value, if needed */
902  if( !lp->looseobjvalid )
903  recomputeLooseObjectiveValue(lp, set, prob);
904 
905  return lp->looseobjval;
906 }
907 
908 /** gets finite part of pseudo objective value of current LP */
909 static
911  SCIP_LP* lp, /**< current LP data */
912  SCIP_SET* set, /**< global SCIP settings */
913  SCIP_PROB* prob /**< problem data */
914  )
915 {
916  assert(lp != NULL);
917  assert(set != NULL);
918  assert(prob != NULL);
919 
920  /* recalculate the pseudo objective value, if needed */
921  if( !lp->pseudoobjvalid )
922  recomputePseudoObjectiveValue(lp, set, prob);
923 
924  return lp->pseudoobjval;
925 }
926 
927 /*
928  * Sorting and searching rows and columns
929  */
930 
931 
932 /** comparison method for sorting rows by non-decreasing index */
934 {
935  assert(elem1 != NULL);
936  assert(elem2 != NULL);
937 
938  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
939  return -1;
940  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
941  return +1;
942  else
943  {
944  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
945  return 0;
946  }
947 }
948 
949 
950 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
951 static
953  SCIP_COL* col /**< column to be sorted */
954  )
955 {
956  int i;
957 
958  assert(col != NULL);
959 
960  /* check, if column is already sorted in the LP part */
961  if( col->lprowssorted )
962  return;
963 
964  /* sort coefficients */
965  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
966 
967  /* update links */
968  for( i = 0; i < col->nlprows; ++i )
969  {
970  if( col->linkpos[i] >= 0 )
971  {
972  assert(col->rows[i]->cols[col->linkpos[i]] == col);
973  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
974  col->rows[i]->linkpos[col->linkpos[i]] = i;
975  }
976  }
977 
978  col->lprowssorted = TRUE;
979 }
980 
981 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
982  * ones
983  */
984 static
986  SCIP_COL* col /**< column to be sorted */
987  )
988 {
989  int i;
990 
991  assert(col != NULL);
992 
993  /* check, if column is already sorted in the non-LP part */
994  if( col->nonlprowssorted )
995  return;
996 
997  /* sort coefficients */
998  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
999 
1000  /* update links */
1001  for( i = col->nlprows; i < col->len; ++i )
1002  {
1003  if( col->linkpos[i] >= 0 )
1004  {
1005  assert(col->rows[i]->cols[col->linkpos[i]] == col);
1006  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1007  col->rows[i]->linkpos[col->linkpos[i]] = i;
1008  }
1009  }
1010 
1011  col->nonlprowssorted = TRUE;
1012 }
1013 
1014 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1015 static
1017  SCIP_ROW* row /**< row to be sorted */
1018  )
1019 {
1020  int i;
1021 
1022  assert(row != NULL);
1023 
1024  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1025  if( row->lpcolssorted || row->delaysort )
1026  return;
1027 
1028  /* sort coefficients */
1029  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1030 
1031  /* update links */
1032  for( i = 0; i < row->nlpcols; ++i )
1033  {
1034  if( row->linkpos[i] >= 0 )
1035  {
1036  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1037  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1038  row->cols[i]->linkpos[row->linkpos[i]] = i;
1039  }
1040  }
1041 
1042  row->lpcolssorted = TRUE;
1043 }
1044 
1045 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1046  * higher ones
1047  */
1048 static
1050  SCIP_ROW* row /**< row to be sorted */
1051  )
1052 {
1053  int i;
1054 
1055  assert(row != NULL);
1056 
1057  checkRow(row);
1058 
1059  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1060  if( row->nonlpcolssorted || row->delaysort )
1061  return;
1062 
1063  /* sort coefficients */
1064  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1065 
1066  /* update links */
1067  for( i = row->nlpcols; i < row->len; ++i )
1068  {
1069  if( row->linkpos[i] >= 0 )
1070  {
1071  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1072  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1073  row->cols[i]->linkpos[row->linkpos[i]] = i;
1074  }
1075  }
1076 
1077  checkRow(row);
1078 
1079  row->nonlpcolssorted = TRUE;
1080 }
1081 
1082 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1083 static
1085  SCIP_COL* col, /**< column to be searched in */
1086  const SCIP_ROW* row, /**< coefficient to be searched for */
1087  int minpos, /**< first position of search range */
1088  int maxpos /**< last position of search range */
1089  )
1090 {
1091  int pos;
1092  int idx;
1093  int searchidx;
1094 
1095  assert(col != NULL);
1096  assert(row != NULL);
1097 
1098  /* binary search */
1099  searchidx = row->index;
1100  while(minpos <= maxpos)
1101  {
1102  pos = (minpos + maxpos)/2;
1103  assert(0 <= pos && pos < col->len);
1104  assert(col->rows[pos] != NULL);
1105  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1106  idx = col->rows[pos]->index;
1107  if( searchidx == idx )
1108  return pos;
1109  else if( searchidx < idx )
1110  maxpos = pos-1;
1111  else
1112  minpos = pos+1;
1113  }
1114 
1115  return -1;
1116 }
1117 
1118 /** searches coefficient in column, returns position in col vector or -1 if not found */
1119 static
1121  SCIP_COL* col, /**< column to be searched in */
1122  const SCIP_ROW* row /**< coefficient to be searched for */
1123  )
1124 {
1125  int pos;
1126 
1127  assert(col != NULL);
1128  assert(row != NULL);
1129 
1130  pos = -1;
1131 
1132  /* search in the linked LP rows */
1133  if( row->lppos >= 0 )
1134  {
1135  /* column has to be sorted, such that binary search works */
1136  colSortLP(col);
1137  assert(col->lprowssorted);
1138 
1139  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1140  if( pos >= 0 )
1141  return pos;
1142  }
1143 
1144  /* search in the non-LP/unlinked rows */
1145  if( row->lppos == -1 || col->nunlinked > 0 )
1146  {
1147  /* column has to be sorted, such that binary search works */
1148  colSortNonLP(col);
1149  assert(col->nonlprowssorted);
1150 
1151  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1152  }
1153 
1154  return pos;
1155 }
1156 
1157 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1158 static
1160  SCIP_ROW* row, /**< row to be searched in */
1161  const SCIP_COL* col, /**< coefficient to be searched for */
1162  int minpos, /**< first position of search range */
1163  int maxpos /**< last position of search range */
1164  )
1165 {
1166  int pos;
1167  int idx;
1168  int searchidx;
1169 
1170  assert(row != NULL);
1171  assert(col != NULL);
1172 
1173  /* binary search */
1174  searchidx = col->index;
1175  while(minpos <= maxpos)
1176  {
1177  pos = (minpos + maxpos)/2;
1178  assert(0 <= pos && pos < row->len);
1179  assert(row->cols[pos] != NULL);
1180  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1181  assert(row->cols_index[pos] == row->cols[pos]->index);
1182  idx = row->cols_index[pos];
1183  if( searchidx == idx )
1184  return pos;
1185  else if( searchidx < idx )
1186  maxpos = pos-1;
1187  else
1188  minpos = pos+1;
1189  }
1190 
1191  return -1;
1192 }
1193 
1194 /** searches coefficient in row, returns position in row vector or -1 if not found;
1195  * if the sorting of the row is delayed, returns -1
1196  */
1197 static
1199  SCIP_ROW* row, /**< row to be searched in */
1200  const SCIP_COL* col /**< coefficient to be searched for */
1201  )
1202 {
1203  int pos;
1204 
1205  assert(row != NULL);
1206  assert(col != NULL);
1207 
1208  if( row->delaysort )
1209  return -1;
1210 
1211  pos = -1;
1212 
1213  /* search in the linked LP columns */
1214  if( col->lppos >= 0 )
1215  {
1216  /* row has to be sorted, such that binary search works */
1217  rowSortLP(row);
1218  assert(row->lpcolssorted);
1219 
1220  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1221  }
1222 
1223  /* search in the non-LP/unlinked columns */
1224  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1225  {
1226  /* row has to be sorted, such that binary search works */
1227  rowSortNonLP(row);
1228  assert(row->nonlpcolssorted);
1229 
1230  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1231  }
1232 
1233 #ifndef NDEBUG
1234  /* validate result */
1235  assert(-1 <= pos && pos < row->len);
1236  if( pos >= 0 )
1237  assert(row->cols[pos] == col);
1238  else
1239  {
1240  int i;
1241  for( i = 0; i < row->len; ++i )
1242  assert(row->cols[i] != col);
1243  }
1244 #endif
1245 
1246  return pos;
1247 }
1248 
1249 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1250 static
1252  SCIP_COL* col, /**< LP column */
1253  int oldpos, /**< old position of coefficient */
1254  int newpos /**< new position of coefficient */
1255  )
1256 {
1257  assert(col != NULL);
1258  assert(0 <= oldpos && oldpos < col->len);
1259  assert(0 <= newpos && newpos < col->len);
1260  assert(col->rows[oldpos] != NULL);
1261 
1262  if( oldpos == newpos )
1263  return;
1264 
1265  col->rows[newpos] = col->rows[oldpos];
1266  col->vals[newpos] = col->vals[oldpos];
1267  col->linkpos[newpos] = col->linkpos[oldpos];
1268 
1269  /* update link position in row */
1270  if( col->linkpos[newpos] >= 0 )
1271  {
1272  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1273  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1274 
1275  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1276  }
1277 
1278  /* update sorted flags */
1279  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1280  col->lprowssorted = FALSE;
1281  else
1282  col->nonlprowssorted = FALSE;
1283 }
1284 
1285 /** swaps two coefficients in a column, and updates all corresponding data structures */
1286 static
1288  SCIP_COL* col, /**< LP column */
1289  int pos1, /**< position of first coefficient */
1290  int pos2 /**< position of second coefficient */
1291  )
1292 {
1293  SCIP_ROW* tmprow;
1294  SCIP_Real tmpval;
1295  int tmplinkpos;
1296 
1297  assert(col != NULL);
1298  assert(0 <= pos1 && pos1 < col->len);
1299  assert(0 <= pos2 && pos2 < col->len);
1300  assert(col->rows[pos1] != NULL);
1301 
1302  if( pos1 == pos2 )
1303  return;
1304 
1305  /* swap coefficients */
1306  tmprow = col->rows[pos2];
1307  tmpval = col->vals[pos2];
1308  tmplinkpos = col->linkpos[pos2];
1309 
1310  col->rows[pos2] = col->rows[pos1];
1311  col->vals[pos2] = col->vals[pos1];
1312  col->linkpos[pos2] = col->linkpos[pos1];
1313 
1314  col->rows[pos1] = tmprow;
1315  col->vals[pos1] = tmpval;
1316  col->linkpos[pos1] = tmplinkpos;
1317 
1318  /* update link position in rows */
1319  if( col->linkpos[pos1] >= 0 )
1320  {
1321  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1322  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1323 
1324  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1325  }
1326  if( col->linkpos[pos2] >= 0 )
1327  {
1328  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1329  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1330 
1331  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1332  }
1333 
1334  /* update sorted flags */
1335  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1336  col->lprowssorted = FALSE;
1337  else
1338  col->nonlprowssorted = FALSE;
1339  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1340  col->lprowssorted = FALSE;
1341  else
1342  col->nonlprowssorted = FALSE;
1343 }
1344 
1345 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1346 static
1348  SCIP_ROW* row, /**< LP row */
1349  int oldpos, /**< old position of coefficient */
1350  int newpos /**< new position of coefficient */
1351  )
1352 {
1353  assert(row != NULL);
1354  assert(0 <= oldpos && oldpos < row->len);
1355  assert(0 <= newpos && newpos < row->len);
1356  assert(row->cols[oldpos] != NULL);
1357 
1358  if( oldpos == newpos )
1359  return;
1360 
1361  row->cols[newpos] = row->cols[oldpos];
1362  row->cols_index[newpos] = row->cols_index[oldpos];
1363  row->vals[newpos] = row->vals[oldpos];
1364  row->linkpos[newpos] = row->linkpos[oldpos];
1365 
1366  /* update link position in column */
1367  if( row->linkpos[newpos] >= 0 )
1368  {
1369  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1370  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1371 
1372  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1373  }
1374 
1375  /* update sorted flags */
1376  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1377  row->lpcolssorted = FALSE;
1378  else
1379  row->nonlpcolssorted = FALSE;
1380 }
1381 
1382 /** swaps two coefficients in a row, and updates all corresponding data structures */
1383 static
1385  SCIP_ROW* row, /**< LP row */
1386  int pos1, /**< position of first coefficient */
1387  int pos2 /**< position of second coefficient */
1388  )
1389 {
1390  SCIP_COL* tmpcol;
1391  SCIP_Real tmpval;
1392  int tmpindex;
1393  int tmplinkpos;
1394 
1395  assert(row != NULL);
1396  assert(0 <= pos1 && pos1 < row->len);
1397  assert(0 <= pos2 && pos2 < row->len);
1398  assert(row->cols[pos1] != NULL);
1399  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1400 
1401  if( pos1 == pos2 )
1402  return;
1403 
1404  /* swap coefficients */
1405  tmpcol = row->cols[pos2];
1406  tmpindex = row->cols_index[pos2];
1407  tmpval = row->vals[pos2];
1408  tmplinkpos = row->linkpos[pos2];
1409 
1410  row->cols[pos2] = row->cols[pos1];
1411  row->cols_index[pos2] = row->cols_index[pos1];
1412  row->vals[pos2] = row->vals[pos1];
1413  row->linkpos[pos2] = row->linkpos[pos1];
1414 
1415  row->cols[pos1] = tmpcol;
1416  row->cols_index[pos1] = tmpindex;
1417  row->vals[pos1] = tmpval;
1418  row->linkpos[pos1] = tmplinkpos;
1419 
1420  /* update link position in columns */
1421  if( row->linkpos[pos1] >= 0 )
1422  {
1423  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1424  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1425 
1426  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1427  }
1428  if( row->linkpos[pos2] >= 0 )
1429  {
1430  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1431  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1432 
1433  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1434  }
1435 
1436  /* update sorted flags */
1437  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1438  row->lpcolssorted = FALSE;
1439  else
1440  row->nonlpcolssorted = FALSE;
1441  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1442  row->lpcolssorted = FALSE;
1443  else
1444  row->nonlpcolssorted = FALSE;
1445 }
1446 
1447 /** issues a ROWCOEFCHANGED event on the given row */
1448 static
1450  SCIP_ROW* row, /**< row which coefficient has changed */
1451  BMS_BLKMEM* blkmem, /**< block memory */
1452  SCIP_SET* set, /**< global SCIP settings */
1453  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1454  SCIP_COL* col, /**< the column which coefficient has changed */
1455  SCIP_Real oldval, /**< old value of the coefficient */
1456  SCIP_Real newval /**< new value of the coefficient */
1457  )
1458 {
1459  assert(row != NULL);
1460  assert(row->eventfilter != NULL);
1461  assert(col != NULL);
1462 
1463  /* check, if the row is being tracked for coefficient changes
1464  * if so, issue ROWCOEFCHANGED event
1465  */
1466  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1467  {
1468  SCIP_EVENT* event;
1469 
1470  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1471  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1472  }
1473 
1474  return SCIP_OKAY;
1475 }
1476 
1477 /** issues a ROWCONSTCHANGED event on the given row */
1478 static
1480  SCIP_ROW* row, /**< row which coefficient has changed */
1481  BMS_BLKMEM* blkmem, /**< block memory */
1482  SCIP_SET* set, /**< global SCIP settings */
1483  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1484  SCIP_Real oldval, /**< old value of the constant */
1485  SCIP_Real newval /**< new value of the constant */
1486  )
1487 {
1488  assert(row != NULL);
1489  assert(row->eventfilter != NULL);
1490 
1491  /* check, if the row is being tracked for coefficient changes
1492  * if so, issue ROWCONSTCHANGED event
1493  */
1494  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED) != 0) )
1495  {
1496  SCIP_EVENT* event;
1497 
1498  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1499  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1500  }
1501 
1502  return SCIP_OKAY;
1503 }
1504 
1505 /** issues a ROWSIDECHANGED event on the given row */
1506 static
1508  SCIP_ROW* row, /**< row which coefficient has changed */
1509  BMS_BLKMEM* blkmem, /**< block memory */
1510  SCIP_SET* set, /**< global SCIP settings */
1511  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1512  SCIP_SIDETYPE side, /**< the side that has changed */
1513  SCIP_Real oldval, /**< old value of side */
1514  SCIP_Real newval /**< new value of side */
1515  )
1516 {
1517  assert(row != NULL);
1518  assert(row->eventfilter != NULL);
1519 
1520  /* check, if the row is being tracked for coefficient changes
1521  * if so, issue ROWSIDECHANGED event
1522  */
1523  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED) != 0) )
1524  {
1525  SCIP_EVENT* event;
1526 
1527  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1528  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1529  }
1530 
1531  return SCIP_OKAY;
1532 }
1533 
1534 #if 0 /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1535 
1536 #ifdef NDEBUG
1537 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1538 #else
1539 #define ASSERT(x) assert(x)
1540 #endif
1541 
1542 static SCIP_Bool msgdisp_checklinks = FALSE;
1543 
1544 
1545 static
1546 void checkLinks(
1547  SCIP_LP* lp /**< current LP data */
1548  )
1549 {
1550  SCIP_COL* col;
1551  SCIP_ROW* row;
1552  int i;
1553  int j;
1554 
1555  ASSERT(lp != NULL);
1556 
1557  if( !msgdisp_checklinks )
1558  {
1559  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1560  msgdisp_checklinks = TRUE;
1561  }
1562 
1563  for( i = 0; i < lp->ncols; ++i )
1564  {
1565  col = lp->cols[i];
1566  ASSERT(col != NULL);
1567  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1568  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1569  ASSERT(col->nlprows <= col->len);
1570  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1571 
1572  for( j = 0; j < col->len; ++j )
1573  {
1574  row = col->rows[j];
1575  ASSERT(row != NULL);
1576  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1577  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1578  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1579  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1580  }
1581  }
1582 
1583  for( i = 0; i < lp->nrows; ++i )
1584  {
1585  row = lp->rows[i];
1586  ASSERT(row != NULL);
1587  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1588  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1589  ASSERT(row->nlpcols <= row->len);
1590  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1591 
1592  for( j = 0; j < row->len; ++j )
1593  {
1594  col = row->cols[j];
1595  ASSERT(col != NULL);
1596  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1597  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1598  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1599  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1600  }
1601  }
1602 }
1603 
1604 #undef ASSERT
1605 
1606 #else
1607 #define checkLinks(lp) /**/
1608 #endif
1609 
1610 /*
1611  * Changing announcements
1612  */
1613 
1614 /** announces, that the given coefficient in the constraint matrix changed */
1615 static
1617  SCIP_ROW* row, /**< LP row */
1618  SCIP_COL* col, /**< LP col */
1619  SCIP_LP* lp /**< current LP data */
1620  )
1621 {
1622  assert(row != NULL);
1623  assert(col != NULL);
1624  assert(lp != NULL);
1625 
1626  if( row->lpipos >= 0 && col->lpipos >= 0 )
1627  {
1628  assert(row->lpipos < lp->nlpirows);
1629  assert(col->lpipos < lp->nlpicols);
1630 
1631  /* we have to remember the change only in the row or in the column,
1632  * because the readdition of one vector would change the other automatically.
1633  */
1634  if( row->lpipos >= lp->lpifirstchgrow )
1635  row->coefchanged = TRUE;
1636  else if( col->lpipos >= lp->lpifirstchgcol )
1637  col->coefchanged = TRUE;
1638  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1639  {
1640  row->coefchanged = TRUE;
1641  lp->lpifirstchgrow = row->lpipos;
1642  }
1643  else
1644  {
1645  col->coefchanged = TRUE;
1646  lp->lpifirstchgcol = col->lpipos;
1647  }
1648 
1649  /* mark the current LP unflushed */
1650  lp->flushed = FALSE;
1651  }
1652 
1654  row->minactivity = SCIP_INVALID;
1655  row->maxactivity = SCIP_INVALID;
1656  row->validpsactivitydomchg = -1;
1657  row->validactivitybdsdomchg = -1;
1658 }
1659 
1660 
1661 
1662 /*
1663  * local column changing methods
1664  */
1665 
1666 /* forward declaration for colAddCoef() */
1667 static
1669  SCIP_ROW* row, /**< LP row */
1670  BMS_BLKMEM* blkmem, /**< block memory */
1671  SCIP_SET* set, /**< global SCIP settings */
1672  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1673  SCIP_LP* lp, /**< current LP data */
1674  SCIP_COL* col, /**< LP column */
1675  SCIP_Real val, /**< value of coefficient */
1676  int linkpos /**< position of row in the column's row array, or -1 */
1677  );
1678 
1679 /** adds a previously non existing coefficient to an LP column */
1680 static
1682  SCIP_COL* col, /**< LP column */
1683  BMS_BLKMEM* blkmem, /**< block memory */
1684  SCIP_SET* set, /**< global SCIP settings */
1685  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1686  SCIP_LP* lp, /**< current LP data */
1687  SCIP_ROW* row, /**< LP row */
1688  SCIP_Real val, /**< value of coefficient */
1689  int linkpos /**< position of column in the row's col array, or -1 */
1690  )
1691 {
1692  int pos;
1693 
1694  assert(blkmem != NULL);
1695  assert(col != NULL);
1696  assert(col->nlprows <= col->len);
1697  assert(col->var != NULL);
1698  assert(row != NULL);
1699  assert(!SCIPsetIsZero(set, val));
1700  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1701 
1702  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1703  assert(col->rows != NULL);
1704  assert(col->vals != NULL);
1705  assert(col->linkpos != NULL);
1706 
1707  pos = col->len;
1708  col->len++;
1709 
1710  /* 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
1711  * part of the column's arrays
1712  */
1713  if( row->lppos >= 0 && linkpos >= 0 )
1714  {
1715  /* move the first non-LP/not linked row to the end */
1716  if( col->nlprows < pos )
1717  {
1718  colMoveCoef(col, col->nlprows, pos);
1719  pos = col->nlprows;
1720  }
1721  col->nlprows++;
1722  }
1723 
1724  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1725  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1726 
1727  /* insert the row at the correct position and update the links */
1728  col->rows[pos] = row;
1729  col->vals[pos] = val;
1730  col->linkpos[pos] = linkpos;
1731  if( linkpos == -1 )
1732  {
1733  col->nunlinked++;
1734 
1735  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1736  * of the row is not complete
1737  */
1738  if( col->lppos >= 0 )
1739  {
1740  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1741  * has to be updated
1742  */
1743  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1744  if( row->lppos >= 0 )
1745  pos = col->nlprows-1;
1746  linkpos = col->linkpos[pos];
1747 
1748  assert(0 <= linkpos && linkpos < row->len);
1749  assert(row->cols[linkpos] == col);
1750  assert(col->rows[pos] == row);
1751  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1752  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1753  }
1754  }
1755  else
1756  {
1757  assert(row->linkpos[linkpos] == -1);
1758  assert(row->nunlinked > 0);
1759  row->linkpos[linkpos] = pos;
1760  row->nunlinked--;
1761 
1762  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1763  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1764  */
1765  if( col->lppos >= 0 )
1766  {
1767  row->nlpcols++;
1768  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1769 
1770  /* if no swap was necessary, mark nonlpcols to be unsorted */
1771  if( linkpos == row->nlpcols-1 )
1772  row->lpcolssorted = FALSE;
1773  }
1774  }
1775 
1776  /* update the sorted flags */
1777  if( row->lppos >= 0 && linkpos >= 0 )
1778  {
1779  assert(col->nlprows >= 1);
1780  assert(col->rows[col->nlprows-1] == row);
1781  if( col->nlprows > 1 )
1782  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1783  }
1784  else
1785  {
1786  assert(col->len - col->nlprows >= 1);
1787  assert(col->rows[col->len-1] == row);
1788  if( col->len - col->nlprows > 1 )
1789  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1790  }
1791 
1792  coefChanged(row, col, lp);
1793 
1794  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1795  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1796 
1797  return SCIP_OKAY;
1798 }
1799 
1800 /** deletes coefficient at given position from column */
1801 static
1803  SCIP_COL* col, /**< column to be changed */
1804  SCIP_SET* set, /**< global SCIP settings */
1805  SCIP_LP* lp, /**< current LP data */
1806  int pos /**< position in column vector to delete */
1807  )
1808 {
1809  SCIP_ROW* row;
1810 
1811  assert(col != NULL);
1812  assert(col->var != NULL);
1813  assert(set != NULL);
1814  assert(0 <= pos && pos < col->len);
1815  assert(col->rows[pos] != NULL);
1816  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1817  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1818 
1819  row = col->rows[pos];
1820  assert((row->lppos >= 0) == (pos < col->nlprows));
1821 
1822  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1823  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1824 
1825  if( col->linkpos[pos] == -1 )
1826  col->nunlinked--;
1827 
1828  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1829  if( pos < col->nlprows )
1830  {
1831  colMoveCoef(col, col->nlprows-1, pos);
1832  col->nlprows--;
1833  pos = col->nlprows;
1834  }
1835 
1836  /* move last coefficient to position of empty slot */
1837  colMoveCoef(col, col->len-1, pos);
1838  col->len--;
1839 
1840  coefChanged(row, col, lp);
1841 
1842  return SCIP_OKAY;
1843 }
1844 
1845 /** changes a coefficient at given position of an LP column */
1846 static
1848  SCIP_COL* col, /**< LP column */
1849  SCIP_SET* set, /**< global SCIP settings */
1850  SCIP_LP* lp, /**< current LP data */
1851  int pos, /**< position in column vector to change */
1852  SCIP_Real val /**< value of coefficient */
1853  )
1854 {
1855  assert(col != NULL);
1856  assert(col->var != NULL);
1857  assert(0 <= pos && pos < col->len);
1858  assert(col->rows[pos] != NULL);
1859  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1860 
1861  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1862  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1863 
1864  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1865  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1866 
1867  if( SCIPsetIsZero(set, val) )
1868  {
1869  /* delete existing coefficient */
1870  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1871  }
1872  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1873  {
1874  /* change existing coefficient */
1875  col->vals[pos] = val;
1876  coefChanged(col->rows[pos], col, lp);
1877  }
1878 
1879  return SCIP_OKAY;
1880 }
1881 
1882 
1883 
1884 
1885 /*
1886  * local row changing methods
1887  */
1888 
1889 /** update row norms after addition of coefficient */
1890 static
1892  SCIP_ROW* row, /**< LP row */
1893  SCIP_SET* set, /**< global SCIP settings */
1894  SCIP_COL* col, /**< column of added coefficient */
1895  SCIP_Real val, /**< value of added coefficient */
1896  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1897  )
1898 {
1899  SCIP_Real absval;
1900 
1901  assert(row != NULL);
1902  assert(row->nummaxval >= 0);
1903  assert(row->numminval >= 0);
1904  assert(set != NULL);
1905  assert(col != NULL);
1906 
1907  absval = REALABS(val);
1908  assert(!SCIPsetIsZero(set, absval));
1909 
1910  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1911  if( col->lppos >= 0 )
1912  {
1913  /* update squared Euclidean norm and sum norm */
1914  row->sqrnorm += SQR(absval);
1915  row->sumnorm += absval;
1916 
1917  /* update objective function scalar product */
1918  row->objprod += val * col->unchangedobj;
1919  }
1920 
1921  if( updateidxvals )
1922  {
1923  /* update min/maxidx */
1924  row->minidx = MIN(row->minidx, col->index);
1925  row->maxidx = MAX(row->maxidx, col->index);
1926 
1927  /* update maximal and minimal non-zero value */
1928  if( row->nummaxval > 0 )
1929  {
1930  if( SCIPsetIsGT(set, absval, row->maxval) )
1931  {
1932  row->maxval = absval;
1933  row->nummaxval = 1;
1934  }
1935  else if( SCIPsetIsGE(set, absval, row->maxval) )
1936  {
1937  /* make sure the maxval is always exactly the same */
1938  row->maxval = MAX(absval, row->maxval);
1939  row->nummaxval++;
1940  }
1941  }
1942  if( row->numminval > 0 )
1943  {
1944  if( SCIPsetIsLT(set, absval, row->minval) )
1945  {
1946  row->minval = absval;
1947  row->numminval = 1;
1948  }
1949  else if( SCIPsetIsLE(set, absval, row->minval) )
1950  {
1951  /* make sure the minval is always exactly the same */
1952  row->minval = MIN(absval, row->minval);
1953  row->numminval++;
1954  }
1955  }
1956  }
1957  else
1958  {
1959  assert(row->minidx <= col->index);
1960  assert(row->maxidx >= col->index);
1961  assert(row->numminval <= 0 || absval >= row->minval);
1962  assert(row->nummaxval <= 0 || absval <= row->maxval);
1963  }
1964 }
1965 
1966 /** update row norms after deletion of coefficient */
1967 static
1969  SCIP_ROW* row, /**< LP row */
1970  SCIP_SET* set, /**< global SCIP settings */
1971  SCIP_COL* col, /**< column of deleted coefficient */
1972  SCIP_Real val, /**< value of deleted coefficient */
1973  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1974  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1975  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1976  )
1977 {
1978  SCIP_Real absval;
1979 
1980  assert(row != NULL);
1981  assert(row->nummaxval >= 0);
1982  assert(row->numminval >= 0);
1983  assert(set != NULL);
1984  assert(col != NULL);
1985 
1986  absval = REALABS(val);
1987  assert(!SCIPsetIsZero(set, absval));
1988  assert(row->nummaxval == 0 || row->maxval >= absval);
1989  assert(row->numminval == 0 || row->minval <= absval);
1990 
1991  /* update min/maxidx validity */
1992  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
1993  row->validminmaxidx = FALSE;
1994 
1995  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1996  if( forcenormupdate || col->lppos >= 0 )
1997  {
1998  /* update squared Euclidean norm and sum norm */
1999  row->sqrnorm -= SQR(absval);
2000  row->sqrnorm = MAX(row->sqrnorm, 0.0);
2001  row->sumnorm -= absval;
2002  row->sumnorm = MAX(row->sumnorm, 0.0);
2003 
2004  /* update objective function scalar product */
2005  row->objprod -= val * col->unchangedobj;
2006  }
2007 
2008  if( updateval )
2009  {
2010  /* update maximal and minimal non-zero value */
2011  if( row->nummaxval > 0 )
2012  {
2013  if( SCIPsetIsGE(set, absval, row->maxval) )
2014  row->nummaxval--;
2015  }
2016  if( row->numminval > 0 )
2017  {
2018  if( SCIPsetIsLE(set, absval, row->minval) )
2019  row->numminval--;
2020  }
2021  }
2022 }
2023 
2024 /** adds a previously non existing coefficient to an LP row */
2025 static
2027  SCIP_ROW* row, /**< LP row */
2028  BMS_BLKMEM* blkmem, /**< block memory */
2029  SCIP_SET* set, /**< global SCIP settings */
2030  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2031  SCIP_LP* lp, /**< current LP data */
2032  SCIP_COL* col, /**< LP column */
2033  SCIP_Real val, /**< value of coefficient */
2034  int linkpos /**< position of row in the column's row array, or -1 */
2035  )
2036 {
2037  int pos;
2038 
2039  assert(row != NULL);
2040  assert(row->nlpcols <= row->len);
2041  assert(blkmem != NULL);
2042  assert(col != NULL);
2043  assert(col->var != NULL);
2044  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2045  assert(!SCIPsetIsZero(set, val));
2046  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2047 
2048  if( row->nlocks > 0 )
2049  {
2050  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2051  return SCIP_INVALIDDATA;
2052  }
2053 
2054  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2055  assert(row->cols != NULL);
2056  assert(row->vals != NULL);
2057 
2058  pos = row->len;
2059  row->len++;
2060 
2061  /* 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
2062  * part of the row's arrays
2063  */
2064  if( col->lppos >= 0 && linkpos >= 0 )
2065  {
2066  /* move the first non-LP/not linked column to the end */
2067  if( row->nlpcols < pos )
2068  {
2069  rowMoveCoef(row, row->nlpcols, pos);
2070  pos = row->nlpcols;
2071  }
2072  row->nlpcols++;
2073  }
2074 
2075  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2076  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2077 
2078  /* insert the column at the correct position and update the links */
2079  row->cols[pos] = col;
2080  row->cols_index[pos] = col->index;
2081  row->vals[pos] = val;
2082  row->linkpos[pos] = linkpos;
2083  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2084  if( linkpos == -1 )
2085  {
2086  row->nunlinked++;
2087 
2088  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2089  * of the column is not complete
2090  */
2091  if( row->lppos >= 0 )
2092  {
2093  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2094  * has to be updated
2095  */
2096  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2097  if( col->lppos >= 0 )
2098  pos = row->nlpcols-1;
2099  linkpos = row->linkpos[pos];
2100 
2101  assert(0 <= linkpos && linkpos < col->len);
2102  assert(col->rows[linkpos] == row);
2103  assert(row->cols[pos] == col);
2104  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2105  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2106  }
2107  }
2108  else
2109  {
2110  assert(col->linkpos[linkpos] == -1);
2111  assert(col->nunlinked > 0);
2112  col->linkpos[linkpos] = pos;
2113  col->nunlinked--;
2114 
2115  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2116  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2117  */
2118  if( row->lppos >= 0 )
2119  {
2120  col->nlprows++;
2121  colSwapCoefs(col, linkpos, col->nlprows-1);
2122 
2123  /* if no swap was necessary, mark lprows to be unsorted */
2124  if( linkpos == col->nlprows-1 )
2125  col->lprowssorted = FALSE;
2126  }
2127  }
2128 
2129  /* update the sorted flags */
2130  if( col->lppos >= 0 && linkpos >= 0 )
2131  {
2132  assert(row->nlpcols >= 1);
2133  assert(row->cols[row->nlpcols-1] == col);
2134  if( row->nlpcols > 1 )
2135  {
2136  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2137  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2138  }
2139  }
2140  else
2141  {
2142  assert(row->len - row->nlpcols >= 1);
2143  assert(row->cols[row->len-1] == col);
2144  if( row->len - row->nlpcols > 1 )
2145  {
2146  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2147  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2148  }
2149  }
2150 
2151  /* update row norm */
2152  rowAddNorms(row, set, col, val, TRUE);
2153 
2154  coefChanged(row, col, lp);
2155 
2156  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2157  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2158 
2159  /* issue row coefficient changed event */
2160  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2161 
2162  return SCIP_OKAY;
2163 }
2164 
2165 /** deletes coefficient at given position from row */
2166 static
2168  SCIP_ROW* row, /**< row to be changed */
2169  BMS_BLKMEM* blkmem, /**< block memory */
2170  SCIP_SET* set, /**< global SCIP settings */
2171  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2172  SCIP_LP* lp, /**< current LP data */
2173  int pos /**< position in row vector to delete */
2174  )
2175 {
2176  SCIP_COL* col;
2177  SCIP_Real val;
2178 
2179  assert(row != NULL);
2180  assert(set != NULL);
2181  assert(0 <= pos && pos < row->len);
2182  assert(row->cols[pos] != NULL);
2183  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2184 
2185  col = row->cols[pos];
2186  val = row->vals[pos];
2187  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2188 
2189  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2190  val, SCIPvarGetName(col->var), pos, row->name);*/
2191 
2192  if( row->nlocks > 0 )
2193  {
2194  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2195  return SCIP_INVALIDDATA;
2196  }
2197 
2198  if( row->linkpos[pos] == -1 )
2199  row->nunlinked--;
2200 
2201  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2202  if( pos < row->nlpcols )
2203  {
2204  rowMoveCoef(row, row->nlpcols-1, pos);
2205  assert(!row->lpcolssorted);
2206  row->nlpcols--;
2207  pos = row->nlpcols;
2208  }
2209 
2210  /* move last coefficient to position of empty slot */
2211  rowMoveCoef(row, row->len-1, pos);
2212  row->len--;
2213 
2214  /* update norms */
2215  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2216 
2217  coefChanged(row, col, lp);
2218 
2219  /* issue row coefficient changed event */
2220  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2221 
2222  return SCIP_OKAY;
2223 }
2224 
2225 /** changes a coefficient at given position of an LP row */
2226 static
2228  SCIP_ROW* row, /**< LP row */
2229  BMS_BLKMEM* blkmem, /**< block memory */
2230  SCIP_SET* set, /**< global SCIP settings */
2231  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2232  SCIP_LP* lp, /**< current LP data */
2233  int pos, /**< position in row vector to change */
2234  SCIP_Real val /**< value of coefficient */
2235  )
2236 {
2237  SCIP_COL* col;
2238 
2239  assert(row != NULL);
2240  assert(0 <= pos && pos < row->len);
2241 
2242  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2243  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2244 
2245  if( row->nlocks > 0 )
2246  {
2247  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2248  return SCIP_INVALIDDATA;
2249  }
2250 
2251  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2252  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2253  col = row->cols[pos];
2254  assert(row->cols[pos] != NULL);
2255 
2256  if( SCIPsetIsZero(set, val) )
2257  {
2258  /* delete existing coefficient */
2259  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2260  }
2261  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2262  {
2263  SCIP_Real oldval;
2264 
2265  oldval = row->vals[pos];
2266 
2267  /* change existing coefficient */
2268  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2269  row->vals[pos] = val;
2270  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2271  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2272  coefChanged(row, col, lp);
2273 
2274  /* issue row coefficient changed event */
2275  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2276  }
2277 
2278  return SCIP_OKAY;
2279 }
2280 
2281 /** notifies LP row, that its sides were changed */
2282 static
2284  SCIP_ROW* row, /**< LP row */
2285  SCIP_SET* set, /**< global SCIP settings */
2286  SCIP_LP* lp, /**< current LP data */
2287  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2288  )
2289 {
2290  assert(row != NULL);
2291  assert(lp != NULL);
2292 
2293  if( row->lpipos >= 0 )
2294  {
2295  /* insert row in the chgrows list (if not already there) */
2296  if( !row->lhschanged && !row->rhschanged )
2297  {
2298  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2299  lp->chgrows[lp->nchgrows] = row;
2300  lp->nchgrows++;
2301  }
2302 
2303  /* mark side change in the row */
2304  switch( sidetype )
2305  {
2306  case SCIP_SIDETYPE_LEFT:
2307  row->lhschanged = TRUE;
2308  break;
2309  case SCIP_SIDETYPE_RIGHT:
2310  row->rhschanged = TRUE;
2311  break;
2312  default:
2313  SCIPerrorMessage("unknown row side type\n");
2314  SCIPABORT();
2315  return SCIP_INVALIDDATA; /*lint !e527*/
2316  }
2317 
2318  /* mark the current LP unflushed */
2319  lp->flushed = FALSE;
2320 
2321  assert(lp->nchgrows > 0);
2322  }
2323 
2324  return SCIP_OKAY;
2325 }
2326 
2327 
2328 
2329 
2330 /*
2331  * double linked coefficient matrix methods
2332  */
2333 
2334 /** insert column coefficients in corresponding rows */
2335 static
2337  SCIP_COL* col, /**< column data */
2338  BMS_BLKMEM* blkmem, /**< block memory */
2339  SCIP_SET* set, /**< global SCIP settings */
2340  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2341  SCIP_LP* lp /**< current LP data */
2342  )
2343 {
2344  int i;
2345 
2346  assert(col != NULL);
2347  assert(col->var != NULL);
2348  assert(blkmem != NULL);
2349  assert(set != NULL);
2350  assert(lp != NULL);
2351 
2352  if( col->nunlinked > 0 )
2353  {
2354  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2355 
2356  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2357  for( i = col->nlprows; i < col->len; ++i )
2358  {
2359  assert(!SCIPsetIsZero(set, col->vals[i]));
2360  if( col->linkpos[i] == -1 )
2361  {
2362  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2363  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2364  }
2365  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2366  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2367  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2368  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2369  }
2370  }
2371  assert(col->nunlinked == 0);
2372 
2373  checkLinks(lp);
2374 
2375  return SCIP_OKAY;
2376 }
2377 
2378 /** removes column coefficients from corresponding rows */
2379 static
2381  SCIP_COL* col, /**< column data */
2382  BMS_BLKMEM* blkmem, /**< block memory */
2383  SCIP_SET* set, /**< global SCIP settings */
2384  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2385  SCIP_LP* lp /**< current LP data */
2386  )
2387 {
2388  int i;
2389 
2390  assert(col != NULL);
2391  assert(col->var != NULL);
2392  assert(blkmem != NULL);
2393  assert(set != NULL);
2394  assert(lp != NULL);
2395 
2396  if( col->nunlinked < col->len )
2397  {
2398  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2399  for( i = 0; i < col->len; ++i )
2400  {
2401  if( col->linkpos[i] >= 0 )
2402  {
2403  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2404  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2405  col->linkpos[i] = -1;
2406  col->nunlinked++;
2407  }
2408  }
2409  }
2410  assert(col->nunlinked == col->len);
2411 
2412  checkLinks(lp);
2413 
2414  return SCIP_OKAY;
2415 }
2416 
2417 /** insert row coefficients in corresponding columns */
2418 static
2420  SCIP_ROW* row, /**< row data */
2421  BMS_BLKMEM* blkmem, /**< block memory */
2422  SCIP_SET* set, /**< global SCIP settings */
2423  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2424  SCIP_LP* lp /**< current LP data */
2425  )
2426 {
2427  int i;
2428 
2429  assert(row != NULL);
2430  assert(blkmem != NULL);
2431  assert(set != NULL);
2432  assert(lp != NULL);
2433 
2434  if( row->nunlinked > 0 )
2435  {
2436  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2437 
2438  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2439  for( i = row->nlpcols; i < row->len; ++i )
2440  {
2441  assert(!SCIPsetIsZero(set, row->vals[i]));
2442  if( row->linkpos[i] == -1 )
2443  {
2444  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2445  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2446  }
2447  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2448  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2449  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2450  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2451  }
2452  }
2453  assert(row->nunlinked == 0);
2454 
2455  checkLinks(lp);
2456 
2457  return SCIP_OKAY;
2458 }
2459 
2460 /** removes row coefficients from corresponding columns */
2461 static
2463  SCIP_ROW* row, /**< row data */
2464  SCIP_SET* set, /**< global SCIP settings */
2465  SCIP_LP* lp /**< current LP data */
2466  )
2467 {
2468  int i;
2469 
2470  assert(row != NULL);
2471  assert(set != NULL);
2472  assert(lp != NULL);
2473 
2474  if( row->nunlinked < row->len )
2475  {
2476  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2477  for( i = 0; i < row->len; ++i )
2478  {
2479  if( row->linkpos[i] >= 0 )
2480  {
2481  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2482  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2483  row->nunlinked++;
2484  }
2485  }
2486  }
2487  assert(row->nunlinked == row->len);
2488 
2489  return SCIP_OKAY;
2490 }
2491 
2492 
2493 
2494 
2495 /*
2496  * local LP parameter methods
2497  */
2498 
2499 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2500 static
2502  SCIP_LP* lp, /**< current LP data */
2503  SCIP_LPPARAM lpparam, /**< LP parameter */
2504  int value, /**< value to set parameter to */
2505  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2506  )
2507 {
2508  SCIP_RETCODE retcode;
2509 
2510  assert(lp != NULL);
2511  assert(success != NULL);
2512 
2513  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2514 
2515  /* check, if parameter is unknown */
2516  if( retcode == SCIP_PARAMETERUNKNOWN )
2517  {
2518  *success = FALSE;
2519  return SCIP_OKAY;
2520  }
2521  *success = TRUE;
2522 
2523  return retcode;
2524 }
2525 
2526 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2527 static
2529  SCIP_LP* lp, /**< current LP data */
2530  SCIP_LPPARAM lpparam, /**< LP parameter */
2531  SCIP_Bool value, /**< value to set parameter to */
2532  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2533  )
2534 {
2535  return lpSetIntpar(lp, lpparam, (int)value, success);
2536 }
2537 
2538 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2539 static
2541  SCIP_LP* lp, /**< current LP data */
2542  SCIP_LPPARAM lpparam, /**< LP parameter */
2543  SCIP_Real value, /**< value to set parameter to */
2544  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2545  )
2546 {
2547  SCIP_RETCODE retcode;
2548 
2549  assert(lp != NULL);
2550  assert(success != NULL);
2551 
2552  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2553 
2554  /* check, if parameter is unknown */
2555  if( retcode == SCIP_PARAMETERUNKNOWN )
2556  {
2557  *success = FALSE;
2558  return SCIP_OKAY;
2559  }
2560  *success = TRUE;
2561 
2562  return retcode;
2563 }
2564 
2565 #ifndef NDEBUG
2566 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2567 static
2569  SCIP_LP* lp, /**< current LP data */
2570  SCIP_LPPARAM lpparam, /**< LP parameter */
2571  int value /**< value parameter should have */
2572  )
2573 {
2574  SCIP_RETCODE retcode;
2575  int lpivalue;
2576 
2577  assert(lp != NULL);
2578 
2579  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2580 
2581  /* ignore unknown parameter error */
2582  if( retcode == SCIP_PARAMETERUNKNOWN )
2583  return SCIP_OKAY;
2584 
2585  /* check value */
2586  assert(lpivalue == value);
2587 
2588  return retcode;
2589 }
2590 
2591 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2592 static
2594  SCIP_LP* lp, /**< current LP data */
2595  SCIP_LPPARAM lpparam, /**< LP parameter */
2596  SCIP_Bool value /**< value parameter should have */
2597  )
2598 {
2599  return lpCheckIntpar(lp, lpparam, (int)value);
2600 }
2601 
2602 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2603 static
2605  SCIP_LP* lp, /**< current LP data */
2606  SCIP_LPPARAM lpparam, /**< LP parameter */
2607  SCIP_Real value /**< value parameter should have */
2608  )
2609 {/*lint --e{715}*/
2610  SCIP_RETCODE retcode;
2611  SCIP_Real lpivalue;
2612 
2613  assert(lp != NULL);
2614 
2615  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2616 
2617  /* ignore unknown parameter error */
2618  if( retcode == SCIP_PARAMETERUNKNOWN )
2619  return SCIP_OKAY;
2620 
2621  /* This assert is currently disabled because it can happen that the feasibility tolerance is changed to a
2622  * value outside the interval allowed by the LP solver, in which case the lpi might project it to the bounds
2623  * of the LP solver and this assert will fail the next time.
2624  * It should be reenabled once this behaviour is unified among the lpis and handled explicitly in
2625  * lpSetFeastol() etc. with dedicated code instead of calling lpCheckRealpar().
2626  */
2627 #if SCIP_DISABLED_CODE/*lint !e553*/
2628  /* check value */
2629  assert(lpivalue == value); /*lint !e777*/
2630 #endif
2631 
2632  return retcode;
2633 }
2634 #else
2635 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2636 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2637 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2638 #endif
2639 
2640 /** should the objective limit of the LP solver be disabled */
2641 #define lpCutoffDisabled(set) (set->lp_disablecutoff == 1 || (set->nactivepricers > 0 && set->lp_disablecutoff == 2))
2642 
2643 /** sets the objective limit of the LP solver
2644  *
2645  * Note that we are always minimizing.
2646  */
2647 static
2649  SCIP_LP* lp, /**< current LP data */
2650  SCIP_SET* set, /**< global SCIP settings */
2651  SCIP_Real objlim /**< new objective limit */
2652  )
2653 {
2654  assert(lp != NULL);
2655  assert(set != NULL);
2656 
2657  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2658  * solver's objective limit handling, so we return here and do not apply the objective limit. */
2659  if( lpCutoffDisabled(set) || set->misc_exactsolve )
2660  return SCIP_OKAY;
2661 
2662  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2663  if( SCIPsetIsInfinity(set, objlim) )
2664  objlim = SCIPlpiInfinity(lp->lpi);
2665 
2667 
2668  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2669  {
2670  SCIP_Bool success;
2671 
2672  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, &success) );
2673  if( success )
2674  {
2675  /* mark the current solution invalid */
2676  lp->solved = FALSE;
2677  lp->primalfeasible = FALSE;
2678  lp->primalchecked = FALSE;
2679  lp->lpobjval = SCIP_INVALID;
2681  lp->lpiobjlim = objlim;
2682  }
2683  }
2684 
2685  return SCIP_OKAY;
2686 }
2687 
2688 /** sets the feasibility tolerance of the LP solver */
2689 static
2691  SCIP_LP* lp, /**< current LP data */
2692  SCIP_Real feastol, /**< new feasibility tolerance */
2693  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2694  )
2695 {
2696  assert(lp != NULL);
2697  assert(feastol >= 0.0);
2698  assert(success != NULL);
2699 
2701 
2702  if( feastol != lp->lpifeastol ) /*lint !e777*/
2703  {
2704  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2705  if( *success )
2706  {
2707  if( lp->nrows > 0 && feastol < lp->lpifeastol )
2708  {
2709  /* mark the current solution invalid */
2710  lp->solved = FALSE;
2711  lp->primalfeasible = FALSE;
2712  lp->primalchecked = FALSE;
2713  lp->lpobjval = SCIP_INVALID;
2715  }
2716  lp->lpifeastol = feastol;
2717  }
2718  }
2719  else
2720  *success = FALSE;
2721 
2722  return SCIP_OKAY;
2723 }
2724 
2725 /** sets the reduced costs feasibility tolerance of the LP solver */
2726 static
2728  SCIP_LP* lp, /**< current LP data */
2729  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2730  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2731  )
2732 {
2733  assert(lp != NULL);
2734  assert(dualfeastol >= 0.0);
2735  assert(success != NULL);
2736 
2738 
2739  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2740  {
2741  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2742  if( *success )
2743  {
2744  if( lp->nrows > 0 && dualfeastol < lp->lpidualfeastol )
2745  {
2746  /* mark the current solution invalid */
2747  lp->solved = FALSE;
2748  lp->dualfeasible = FALSE;
2749  lp->dualchecked = FALSE;
2750  lp->lpobjval = SCIP_INVALID;
2752  }
2753  lp->lpidualfeastol = dualfeastol;
2754  }
2755  }
2756  else
2757  *success = FALSE;
2758 
2759  return SCIP_OKAY;
2760 }
2761 
2762 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2763 static
2765  SCIP_LP* lp, /**< current LP data */
2766  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2767  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2768  )
2769 {
2770  assert(lp != NULL);
2771  assert(barrierconvtol >= 0.0);
2772  assert(success != NULL);
2773 
2775 
2776  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2777  {
2778  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2779  if( *success )
2780  {
2781  if( lp->nrows > 0 && barrierconvtol < lp->lpibarrierconvtol
2783  {
2784  /* mark the current solution invalid */
2785  lp->solved = FALSE;
2786  lp->dualfeasible = FALSE;
2787  lp->dualchecked = FALSE;
2788  lp->lpobjval = SCIP_INVALID;
2790  }
2791  lp->lpibarrierconvtol = barrierconvtol;
2792  }
2793  }
2794  else
2795  *success = FALSE;
2796 
2797  return SCIP_OKAY;
2798 }
2799 
2800 /** sets the FROMSCRATCH setting of the LP solver */
2801 static
2803  SCIP_LP* lp, /**< current LP data */
2804  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2805  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2806  )
2807 {
2808  assert(lp != NULL);
2809  assert(success != NULL);
2810 
2812 
2813  if( fromscratch != lp->lpifromscratch )
2814  {
2815  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2816  if( *success )
2817  lp->lpifromscratch = fromscratch;
2818  }
2819  else
2820  *success = FALSE;
2821 
2822  return SCIP_OKAY;
2823 }
2824 
2825 /** sets the FASTMIP setting of the LP solver */
2826 static
2828  SCIP_LP* lp, /**< current LP data */
2829  int fastmip, /**< new FASTMIP setting */
2830  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2831  )
2832 {
2833  assert(lp != NULL);
2834  assert(success != NULL);
2835  assert(0 <= fastmip && fastmip <= 1);
2836 
2838 
2839  if( fastmip != lp->lpifastmip )
2840  {
2841  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2842  if( *success )
2843  lp->lpifastmip = fastmip;
2844  }
2845  else
2846  *success = FALSE;
2847 
2848  return SCIP_OKAY;
2849 }
2850 
2851 /** sets the SCALING setting of the LP solver */
2852 static
2854  SCIP_LP* lp, /**< current LP data */
2855  int scaling, /**< new SCALING setting */
2856  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2857  )
2858 {
2859  assert(lp != NULL);
2860  assert(success != NULL);
2861 
2863 
2864  if( scaling != lp->lpiscaling )
2865  {
2866  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2867  if( *success )
2868  lp->lpiscaling = scaling;
2869  }
2870  else
2871  *success = FALSE;
2872 
2873  return SCIP_OKAY;
2874 }
2875 
2876 /** sets the number of THREADS of the LP solver */
2877 static
2879  SCIP_LP* lp, /**< current LP data */
2880  int threads, /**< new number of threads used to solve the LP */
2881  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2882  )
2883 {
2884  assert(lp != NULL);
2885  assert(success != NULL);
2886 
2888 
2889  if( threads != lp->lpithreads )
2890  {
2891  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2892  if( *success )
2893  lp->lpithreads = threads;
2894  }
2895  else
2896  *success = FALSE;
2897 
2898  return SCIP_OKAY;
2899 }
2900 
2901 /** sets the PRESOLVING setting of the LP solver */
2902 static
2904  SCIP_LP* lp, /**< current LP data */
2905  SCIP_Bool presolving, /**< new PRESOLVING setting */
2906  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2907  )
2908 {
2909  assert(lp != NULL);
2910  assert(success != NULL);
2911 
2913 
2914  if( presolving != lp->lpipresolving )
2915  {
2916  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2917  if( *success )
2918  lp->lpipresolving = presolving;
2919  }
2920  else
2921  *success = FALSE;
2922 
2923  return SCIP_OKAY;
2924 }
2925 
2926 /** sets the ROWREPSWITCH setting of the LP solver */
2927 static
2929  SCIP_LP* lp, /**< current LP data */
2930  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2931  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2932  )
2933 {
2934  assert(lp != NULL);
2935  assert(success != NULL);
2936 
2938 
2939  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2940  {
2941  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2942  if( *success )
2943  lp->lpirowrepswitch = rowrepswitch;
2944  }
2945  else
2946  *success = FALSE;
2947 
2948  return SCIP_OKAY;
2949 }
2950 
2951 /** sets the iteration limit of the LP solver */
2952 static
2954  SCIP_LP* lp, /**< current LP data */
2955  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2956  )
2957 {
2958  SCIP_Bool success;
2959 
2960  assert(lp != NULL);
2961  assert(itlim >= -1);
2962 
2963  if( itlim == -1 )
2964  itlim = INT_MAX;
2965 
2967 
2968  if( itlim != lp->lpiitlim )
2969  {
2970  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
2971  if( success )
2972  {
2973  if( itlim > lp->lpiitlim )
2974  {
2975  /* mark the current solution invalid */
2976  lp->solved = FALSE;
2977  lp->lpobjval = SCIP_INVALID;
2979  }
2980  lp->lpiitlim = itlim;
2981  }
2982  }
2983 
2984  return SCIP_OKAY;
2985 }
2986 
2987 /** sets the pricing strategy of the LP solver */
2988 static
2990  SCIP_LP* lp, /**< current LP data */
2991  SCIP_PRICING pricing /**< pricing strategy */
2992  )
2993 {
2994  SCIP_Bool success;
2995 
2996  assert(lp != NULL);
2997 
2999 
3000  if( pricing != lp->lpipricing )
3001  {
3002  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3003  if( success )
3004  lp->lpipricing = pricing;
3005  }
3006 
3007  return SCIP_OKAY;
3008 }
3009 
3010 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3011 static
3013  SCIP_LP* lp, /**< current LP data */
3014  char pricingchar /**< character representing the pricing strategy */
3015  )
3016 {
3018 
3019  switch( pricingchar )
3020  {
3021  case 'l':
3022  pricing = SCIP_PRICING_LPIDEFAULT;
3023  break;
3024  case 'a':
3025  pricing = SCIP_PRICING_AUTO;
3026  break;
3027  case 'f':
3028  pricing = SCIP_PRICING_FULL;
3029  break;
3030  case 'p':
3031  pricing = SCIP_PRICING_PARTIAL;
3032  break;
3033  case 's':
3034  pricing = SCIP_PRICING_STEEP;
3035  break;
3036  case 'q':
3037  pricing = SCIP_PRICING_STEEPQSTART;
3038  break;
3039  case 'd':
3040  pricing = SCIP_PRICING_DEVEX;
3041  break;
3042  default:
3043  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3044  return SCIP_INVALIDDATA;
3045  }
3046 
3047  SCIP_CALL( lpSetPricing(lp, pricing) );
3048 
3049  return SCIP_OKAY;
3050 }
3051 
3052 /** sets the verbosity of the LP solver */
3053 static
3055  SCIP_LP* lp, /**< current LP data */
3056  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3057  )
3058 {
3059  SCIP_Bool success;
3060 
3061  assert(lp != NULL);
3062 
3064 
3065  if( lpinfo != lp->lpilpinfo )
3066  {
3067  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3068  if( success )
3069  lp->lpilpinfo = lpinfo;
3070  }
3071 
3072  return SCIP_OKAY;
3073 }
3074 
3075 /** sets the CONDITIONLIMIT setting of the LP solver */
3076 static
3078  SCIP_LP* lp, /**< current LP data */
3079  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3080  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3081  )
3082 {
3083  assert(lp != NULL);
3084  assert(success != NULL);
3085 
3087 
3088  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3089  {
3090  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3091  if( *success )
3092  lp->lpiconditionlimit = condlimit;
3093  }
3094  else
3095  *success = FALSE;
3096 
3097  return SCIP_OKAY;
3098 }
3099 
3100 /** sets the type of timer of the LP solver */
3101 static
3103  SCIP_LP* lp, /**< current LP data */
3104  SCIP_CLOCKTYPE timing, /**< new timing value */
3105  SCIP_Bool enabled, /**< is timing enabled? */
3106  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3107  )
3108 {
3109  int lptiming;
3110 
3111  assert(lp != NULL);
3112  assert(success != NULL);
3113  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2);
3114 
3116 
3117  if( !enabled )
3118  lptiming = 0;
3119  else
3120  lptiming = (int) timing;
3121 
3122  if( lptiming != lp->lpitiming ) /*lint !e777*/
3123  {
3124  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3125  if( *success )
3126  lp->lpitiming = lptiming;
3127  }
3128  else
3129  *success = FALSE;
3130 
3131  return SCIP_OKAY;
3132 }
3133 
3134 /** sets the initial random seed of the LP solver */
3135 static
3137  SCIP_LP* lp, /**< current LP data */
3138  int randomseed, /**< new initial random seed */
3139  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3140  )
3141 {
3142  assert(lp != NULL);
3143  assert(success != NULL);
3144 
3145  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3146 
3147  if( randomseed == 0 )
3148  {
3149  lp->lpirandomseed = randomseed;
3150  *success = TRUE;
3151  }
3152  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3153  {
3154  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3155  if( *success )
3156  lp->lpirandomseed = randomseed;
3157  }
3158  else
3159  *success = FALSE;
3160 
3161  return SCIP_OKAY;
3162 }
3163 
3164 /** sets the LP solution polishing method */
3165 static
3167  SCIP_LP* lp, /**< current LP data */
3168  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3169  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3170  )
3171 {
3172  assert(lp != NULL);
3173  assert(success != NULL);
3174 
3175  if( polishing != lp->lpisolutionpolishing )
3176  {
3177  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3178  if( *success )
3179  lp->lpisolutionpolishing = polishing;
3180  }
3181  else
3182  *success = FALSE;
3183 
3184  return SCIP_OKAY;
3185 }
3186 
3187 /** sets the LP refactorization interval */
3188 static
3190  SCIP_LP* lp, /**< current LP data */
3191  int refactor, /**< LP refactorization interval (0: automatic) */
3192  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3193  )
3194 {
3195  assert(lp != NULL);
3196  assert(success != NULL);
3197 
3198  if( refactor != lp->lpirefactorinterval )
3199  {
3200  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3201  if( *success )
3202  lp->lpirefactorinterval = refactor;
3203  }
3204  else
3205  *success = FALSE;
3206 
3207  return SCIP_OKAY;
3208 }
3209 
3210 
3211 /*
3212  * Column methods
3213  */
3214 
3215 /** creates an LP column */
3217  SCIP_COL** col, /**< pointer to column data */
3218  BMS_BLKMEM* blkmem, /**< block memory */
3219  SCIP_SET* set, /**< global SCIP settings */
3220  SCIP_STAT* stat, /**< problem statistics */
3221  SCIP_VAR* var, /**< variable, this column represents */
3222  int len, /**< number of nonzeros in the column */
3223  SCIP_ROW** rows, /**< array with rows of column entries */
3224  SCIP_Real* vals, /**< array with coefficients of column entries */
3225  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3226  )
3227 {
3228  int i;
3229 
3230  assert(col != NULL);
3231  assert(blkmem != NULL);
3232  assert(set != NULL);
3233  assert(stat != NULL);
3234  assert(var != NULL);
3235  assert(len >= 0);
3236  assert(len == 0 || (rows != NULL && vals != NULL));
3237 
3238  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3239 
3240  if( len > 0 )
3241  {
3242  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3243  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3244  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3245 
3246  for( i = 0; i < len; ++i )
3247  {
3248  assert(rows[i] != NULL);
3249  assert(!SCIPsetIsZero(set, vals[i]));
3250  (*col)->linkpos[i] = -1;
3251  }
3252  }
3253  else
3254  {
3255  (*col)->rows = NULL;
3256  (*col)->vals = NULL;
3257  (*col)->linkpos = NULL;
3258  }
3259 
3260  (*col)->var = var;
3261  (*col)->obj = SCIPvarGetObj(var);
3262  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3263  (*col)->lb = SCIPvarGetLbLocal(var);
3264  (*col)->ub = SCIPvarGetUbLocal(var);
3265  (*col)->flushedobj = 0.0;
3266  (*col)->flushedlb = 0.0;
3267  (*col)->flushedub = 0.0;
3268  (*col)->index = stat->ncolidx;
3269  SCIPstatIncrement(stat, set, ncolidx);
3270  (*col)->size = len;
3271  (*col)->len = len;
3272  (*col)->nlprows = 0;
3273  (*col)->nunlinked = len;
3274  (*col)->lppos = -1;
3275  (*col)->lpipos = -1;
3276  (*col)->lpdepth = -1;
3277  (*col)->primsol = 0.0;
3278  (*col)->redcost = SCIP_INVALID;
3279  (*col)->farkascoef = SCIP_INVALID;
3280  (*col)->minprimsol = (*col)->ub;
3281  (*col)->maxprimsol = (*col)->lb;
3282  (*col)->sbdown = SCIP_INVALID;
3283  (*col)->sbup = SCIP_INVALID;
3284  (*col)->sbsolval = SCIP_INVALID;
3285  (*col)->sblpobjval = SCIP_INVALID;
3286  (*col)->sbnode = -1;
3287  (*col)->validredcostlp = -1;
3288  (*col)->validfarkaslp = -1;
3289  (*col)->validsblp = -1;
3290  (*col)->sbitlim = -1;
3291  (*col)->nsbcalls = 0;
3292  (*col)->age = 0;
3293  (*col)->obsoletenode = -1;
3294  (*col)->var_probindex = SCIPvarGetProbindex(var);
3295  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3296  (*col)->lprowssorted = TRUE;
3297  (*col)->nonlprowssorted = (len <= 1);
3298  (*col)->objchanged = FALSE;
3299  (*col)->lbchanged = FALSE;
3300  (*col)->ubchanged = FALSE;
3301  (*col)->coefchanged = FALSE;
3302  (*col)->integral = SCIPvarIsIntegral(var);
3303  (*col)->removable = removable;
3304  (*col)->sbdownvalid = FALSE;
3305  (*col)->sbupvalid = FALSE;
3306  (*col)->lazylb = SCIPvarGetLbLazy(var);
3307  (*col)->lazyub = SCIPvarGetUbLazy(var);
3308  (*col)->storedsolvals = NULL;
3309 
3310  return SCIP_OKAY;
3311 }
3312 
3313 /** frees an LP column */
3315  SCIP_COL** col, /**< pointer to LP column */
3316  BMS_BLKMEM* blkmem, /**< block memory */
3317  SCIP_SET* set, /**< global SCIP settings */
3318  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3319  SCIP_LP* lp /**< current LP data */
3320  )
3321 {
3322  assert(blkmem != NULL);
3323  assert(col != NULL);
3324  assert(*col != NULL);
3325  assert((*col)->var != NULL);
3326  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3327  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3328  assert((*col)->lppos == -1);
3329  assert((*col)->lpipos == -1);
3330 
3331  /* remove column indices from corresponding rows */
3332  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3333 
3334  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3335  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3336  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3337  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3338  BMSfreeBlockMemory(blkmem, col);
3339 
3340  return SCIP_OKAY;
3341 }
3342 
3343 /** output column to file stream */
3345  SCIP_COL* col, /**< LP column */
3346  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3347  FILE* file /**< output file (or NULL for standard output) */
3348  )
3349 {
3350  int r;
3351 
3352  assert(col != NULL);
3353  assert(col->var != NULL);
3354 
3355  /* print bounds */
3356  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3357 
3358  /* print coefficients */
3359  if( col->len == 0 )
3360  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3361  for( r = 0; r < col->len; ++r )
3362  {
3363  assert(col->rows[r] != NULL);
3364  assert(col->rows[r]->name != NULL);
3365  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3366  }
3367  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3368 }
3369 
3370 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3371  */
3373  SCIP_COL* col /**< column to be sorted */
3374  )
3375 {
3376  /* sort LP rows */
3377  colSortLP(col);
3378 
3379  /* sort non-LP rows */
3380  colSortNonLP(col);
3381 }
3382 
3383 /** adds a previously non existing coefficient to an LP column */
3385  SCIP_COL* col, /**< LP column */
3386  BMS_BLKMEM* blkmem, /**< block memory */
3387  SCIP_SET* set, /**< global SCIP settings */
3388  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3389  SCIP_LP* lp, /**< current LP data */
3390  SCIP_ROW* row, /**< LP row */
3391  SCIP_Real val /**< value of coefficient */
3392  )
3393 {
3394  assert(lp != NULL);
3395  assert(!lp->diving);
3396 
3397  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3398 
3399  checkLinks(lp);
3400 
3401  return SCIP_OKAY;
3402 }
3403 
3404 /** deletes existing coefficient from column */
3406  SCIP_COL* col, /**< column to be changed */
3407  BMS_BLKMEM* blkmem, /**< block memory */
3408  SCIP_SET* set, /**< global SCIP settings */
3409  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3410  SCIP_LP* lp, /**< current LP data */
3411  SCIP_ROW* row /**< coefficient to be deleted */
3412  )
3413 {
3414  int pos;
3415 
3416  assert(col != NULL);
3417  assert(col->var != NULL);
3418  assert(lp != NULL);
3419  assert(!lp->diving);
3420  assert(row != NULL);
3421 
3422  /* search the position of the row in the column's row vector */
3423  pos = colSearchCoef(col, row);
3424  if( pos == -1 )
3425  {
3426  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3427  return SCIP_INVALIDDATA;
3428  }
3429  assert(0 <= pos && pos < col->len);
3430  assert(col->rows[pos] == row);
3431 
3432  /* if row knows of the column, remove the column from the row's col vector */
3433  if( col->linkpos[pos] >= 0 )
3434  {
3435  assert(row->cols[col->linkpos[pos]] == col);
3436  assert(row->cols_index[col->linkpos[pos]] == col->index);
3437  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3438  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3439  }
3440 
3441  /* delete the row from the column's row vector */
3442  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3443 
3444  checkLinks(lp);
3445 
3446  return SCIP_OKAY;
3447 }
3448 
3449 /** changes or adds a coefficient to an LP column */
3451  SCIP_COL* col, /**< LP column */
3452  BMS_BLKMEM* blkmem, /**< block memory */
3453  SCIP_SET* set, /**< global SCIP settings */
3454  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3455  SCIP_LP* lp, /**< current LP data */
3456  SCIP_ROW* row, /**< LP row */
3457  SCIP_Real val /**< value of coefficient */
3458  )
3459 {
3460  int pos;
3461 
3462  assert(col != NULL);
3463  assert(lp != NULL);
3464  assert(!lp->diving);
3465  assert(row != NULL);
3466 
3467  /* search the position of the row in the column's row vector */
3468  pos = colSearchCoef(col, row);
3469 
3470  /* check, if row already exists in the column's row vector */
3471  if( pos == -1 )
3472  {
3473  /* add previously not existing coefficient */
3474  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3475  }
3476  else
3477  {
3478  /* modify already existing coefficient */
3479  assert(0 <= pos && pos < col->len);
3480  assert(col->rows[pos] == row);
3481 
3482  /* if row knows of the column, change the corresponding coefficient in the row */
3483  if( col->linkpos[pos] >= 0 )
3484  {
3485  assert(row->cols[col->linkpos[pos]] == col);
3486  assert(row->cols_index[col->linkpos[pos]] == col->index);
3487  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3488  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3489  }
3490 
3491  /* change the coefficient in the column */
3492  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3493  }
3494 
3495  checkLinks(lp);
3496 
3497  return SCIP_OKAY;
3498 }
3499 
3500 /** increases value of an existing or non-existing coefficient in an LP column */
3502  SCIP_COL* col, /**< LP column */
3503  BMS_BLKMEM* blkmem, /**< block memory */
3504  SCIP_SET* set, /**< global SCIP settings */
3505  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3506  SCIP_LP* lp, /**< current LP data */
3507  SCIP_ROW* row, /**< LP row */
3508  SCIP_Real incval /**< value to add to the coefficient */
3509  )
3510 {
3511  int pos;
3512 
3513  assert(col != NULL);
3514  assert(lp != NULL);
3515  assert(!lp->diving);
3516  assert(row != NULL);
3517 
3518  if( SCIPsetIsZero(set, incval) )
3519  return SCIP_OKAY;
3520 
3521  /* search the position of the row in the column's row vector */
3522  pos = colSearchCoef(col, row);
3523 
3524  /* check, if row already exists in the column's row vector */
3525  if( pos == -1 )
3526  {
3527  /* add previously not existing coefficient */
3528  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3529  }
3530  else
3531  {
3532  /* modify already existing coefficient */
3533  assert(0 <= pos && pos < col->len);
3534  assert(col->rows[pos] == row);
3535 
3536  /* if row knows of the column, change the corresponding coefficient in the row */
3537  if( col->linkpos[pos] >= 0 )
3538  {
3539  assert(row->cols[col->linkpos[pos]] == col);
3540  assert(row->cols_index[col->linkpos[pos]] == col->index);
3541  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3542  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3543  }
3544 
3545  /* change the coefficient in the column */
3546  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3547  }
3548 
3549  checkLinks(lp);
3550 
3551  return SCIP_OKAY;
3552 }
3553 
3554 /** insert column in the chgcols list (if not already there) */
3555 static
3557  SCIP_COL* col, /**< LP column to change */
3558  SCIP_SET* set, /**< global SCIP settings */
3559  SCIP_LP* lp /**< current LP data */
3560  )
3561 {
3562  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3563  {
3564  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3565  lp->chgcols[lp->nchgcols] = col;
3566  lp->nchgcols++;
3567  }
3568 
3569  /* mark the current LP unflushed */
3570  lp->flushed = FALSE;
3571 
3572  return SCIP_OKAY;
3573 }
3574 
3575 /** Is the new value reliable or may we have cancellation?
3576  *
3577  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3578  * cancellations which can occur during increasing the oldvalue to the newvalue
3579  */
3580 static
3582  SCIP_SET* set, /**< global SCIP settings */
3583  SCIP_Real newvalue, /**< new value */
3584  SCIP_Real oldvalue /**< old reliable value */
3585  )
3586 {
3587  SCIP_Real quotient;
3588 
3589  assert(set != NULL);
3590  assert(oldvalue < SCIP_INVALID);
3591 
3592  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3593 
3594  return SCIPsetIsZero(set, quotient);
3595 }
3596 
3597 /** update norms of objective function vector */
3598 static
3600  SCIP_LP* lp, /**< current LP data */
3601  SCIP_SET* set, /**< global SCIP settings */
3602  SCIP_Real oldobj, /**< old objective value of variable */
3603  SCIP_Real newobj /**< new objective value of variable */
3604  )
3605 {
3606  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3607  {
3608  if( !lp->objsqrnormunreliable )
3609  {
3610  SCIP_Real oldvalue;
3611 
3612  oldvalue = lp->objsqrnorm;
3613  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3614 
3615  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3616  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3617  lp->objsqrnormunreliable = TRUE;
3618  else
3619  {
3620  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3621 
3622  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3623  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3624 
3625  assert(lp->objsqrnorm >= 0.0);
3626  }
3627  }
3628 
3629  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3630  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3631  }
3632 }
3633 
3634 /** changes objective value of column */
3636  SCIP_COL* col, /**< LP column to change */
3637  SCIP_SET* set, /**< global SCIP settings */
3638  SCIP_LP* lp, /**< current LP data */
3639  SCIP_Real newobj /**< new objective value */
3640  )
3641 {
3642  assert(col != NULL);
3643  assert(col->var != NULL);
3644  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3645  assert(SCIPvarGetCol(col->var) == col);
3646  assert(lp != NULL);
3647 
3648  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3649 
3650  /* only add actual changes */
3651  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3652  {
3653  /* only variables with a real position in the LPI can be inserted */
3654  if( col->lpipos >= 0 )
3655  {
3656  /* insert column in the chgcols list (if not already there) */
3657  SCIP_CALL( insertColChgcols(col, set, lp) );
3658 
3659  /* mark objective value change in the column */
3660  col->objchanged = TRUE;
3661 
3662  assert(lp->nchgcols > 0);
3663  }
3664  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3665  * LP and the LP has to be flushed
3666  */
3667  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3668  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3669  {
3670  /* mark the LP unflushed */
3671  lp->flushed = FALSE;
3672  }
3673  }
3674 
3675  /* store new objective function value */
3676  col->obj = newobj;
3677 
3678  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3679  if( !lp->divingobjchg )
3680  {
3681  SCIP_Real oldobj = col->unchangedobj;
3682 
3683  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3684  col->unchangedobj = newobj;
3685 
3686  /* update the objective function vector norms */
3687  lpUpdateObjNorms(lp, set, oldobj, newobj);
3688  }
3689 
3690  return SCIP_OKAY;
3691 }
3692 
3693 /** changes lower bound of column */
3695  SCIP_COL* col, /**< LP column to change */
3696  SCIP_SET* set, /**< global SCIP settings */
3697  SCIP_LP* lp, /**< current LP data */
3698  SCIP_Real newlb /**< new lower bound value */
3699  )
3700 {
3701  assert(col != NULL);
3702  assert(col->var != NULL);
3703  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3704  assert(SCIPvarGetCol(col->var) == col);
3705  assert(lp != NULL);
3706 
3707  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3708 
3709  /* only add actual changes */
3710  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3711  {
3712  /* only variables with a real position in the LPI can be inserted */
3713  if( col->lpipos >= 0 )
3714  {
3715  /* insert column in the chgcols list (if not already there) */
3716  SCIP_CALL( insertColChgcols(col, set, lp) );
3717 
3718  /* mark bound change in the column */
3719  col->lbchanged = TRUE;
3720 
3721  assert(lp->nchgcols > 0);
3722  }
3723  /* 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
3724  * flushed
3725  */
3726  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3727  {
3728  /* mark the LP unflushed */
3729  lp->flushed = FALSE;
3730  }
3731  }
3732 
3733  col->lb = newlb;
3734 
3735  return SCIP_OKAY;
3736 }
3737 
3738 /** changes upper bound of column */
3740  SCIP_COL* col, /**< LP column to change */
3741  SCIP_SET* set, /**< global SCIP settings */
3742  SCIP_LP* lp, /**< current LP data */
3743  SCIP_Real newub /**< new upper bound value */
3744  )
3745 {
3746  assert(col != NULL);
3747  assert(col->var != NULL);
3748  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3749  assert(SCIPvarGetCol(col->var) == col);
3750  assert(lp != NULL);
3751 
3752  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3753 
3754  /* only add actual changes */
3755  if( !SCIPsetIsEQ(set, col->ub, newub) )
3756  {
3757  /* only variables with a real position in the LPI can be inserted */
3758  if( col->lpipos >= 0 )
3759  {
3760  /* insert column in the chgcols list (if not already there) */
3761  SCIP_CALL( insertColChgcols(col, set, lp) );
3762 
3763  /* mark bound change in the column */
3764  col->ubchanged = TRUE;
3765 
3766  assert(lp->nchgcols > 0);
3767  }
3768  /* 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
3769  * flushed
3770  */
3771  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3772  {
3773  /* mark the LP unflushed */
3774  lp->flushed = FALSE;
3775  }
3776  }
3777 
3778  col->ub = newub;
3779 
3780  return SCIP_OKAY;
3781 }
3782 
3783 /** calculates the reduced costs of a column using the given dual solution vector */
3785  SCIP_COL* col, /**< LP column */
3786  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3787  )
3788 {
3789  SCIP_ROW* row;
3790  SCIP_Real redcost;
3791  int i;
3792 
3793  assert(col != NULL);
3794  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3795  assert(SCIPvarGetCol(col->var) == col);
3796  assert(dualsol != NULL);
3797 
3798  redcost = col->obj;
3799  for( i = 0; i < col->nlprows; ++i )
3800  {
3801  row = col->rows[i];
3802  assert(row != NULL);
3803  assert(row->lppos >= 0);
3804  redcost -= col->vals[i] * dualsol[row->lppos];
3805  }
3806 
3807  if( col->nunlinked > 0 )
3808  {
3809  for( i = col->nlprows; i < col->len; ++i )
3810  {
3811  row = col->rows[i];
3812  assert(row != NULL);
3813  assert(row->lppos == -1 || col->linkpos[i] == -1);
3814  if( row->lppos >= 0 )
3815  redcost -= col->vals[i] * dualsol[row->lppos];
3816  }
3817  }
3818 #ifndef NDEBUG
3819  else
3820  {
3821  for( i = col->nlprows; i < col->len; ++i )
3822  {
3823  row = col->rows[i];
3824  assert(row != NULL);
3825  assert(row->lppos == -1);
3826  assert(col->linkpos[i] >= 0);
3827  }
3828  }
3829 #endif
3830 
3831  return redcost;
3832 }
3833 
3834 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3835 static
3837  SCIP_COL* col /**< LP column */
3838  )
3839 {
3840  SCIP_ROW* row;
3841  SCIP_Real redcost;
3842  int i;
3843 
3844  assert(col != NULL);
3845  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3846  assert(SCIPvarGetCol(col->var) == col);
3847 
3848  redcost = col->obj;
3849  for( i = 0; i < col->nlprows; ++i )
3850  {
3851  row = col->rows[i];
3852  assert(row != NULL);
3853  assert(row->dualsol < SCIP_INVALID);
3854  assert(row->lppos >= 0);
3855  assert(col->linkpos[i] >= 0);
3856  redcost -= col->vals[i] * row->dualsol;
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 >= 0 || row->dualsol == 0.0);
3866  assert(row->lppos == -1 || col->linkpos[i] == -1);
3867  if( row->lppos >= 0 )
3868  redcost -= col->vals[i] * row->dualsol;
3869  }
3870  }
3871 #ifndef NDEBUG
3872  else
3873  {
3874  for( i = col->nlprows; i < col->len; ++i )
3875  {
3876  row = col->rows[i];
3877  assert(row != NULL);
3878  assert(row->dualsol == 0.0);
3879  assert(row->lppos == -1);
3880  assert(col->linkpos[i] >= 0);
3881  }
3882  }
3883 #endif
3884 
3885  return redcost;
3886 }
3887 
3888 /** gets the reduced costs of a column in last LP or after recalculation */
3890  SCIP_COL* col, /**< LP column */
3891  SCIP_STAT* stat, /**< problem statistics */
3892  SCIP_LP* lp /**< current LP data */
3893  )
3894 {
3895  assert(col != NULL);
3896  assert(stat != NULL);
3897  assert(lp != NULL);
3898  assert(col->validredcostlp <= stat->lpcount);
3899  assert(lp->validsollp == stat->lpcount);
3900 
3901  if( col->validredcostlp < stat->lpcount )
3902  {
3903  col->redcost = colCalcInternalRedcost(col);
3904  col->validredcostlp = stat->lpcount;
3905  }
3906  assert(col->validredcostlp == stat->lpcount);
3907  assert(col->redcost < SCIP_INVALID);
3908 
3909  return col->redcost;
3910 }
3911 
3912 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3914  SCIP_COL* col, /**< LP column */
3915  SCIP_SET* set, /**< global SCIP settings */
3916  SCIP_STAT* stat, /**< problem statistics */
3917  SCIP_LP* lp /**< current LP data */
3918  )
3919 {
3920  assert(col != NULL);
3921  assert(set != NULL);
3922  assert(stat != NULL);
3923  assert(lp != NULL);
3924  assert(lp->validsollp == stat->lpcount);
3925 
3926  /* A column's reduced cost is defined as
3927  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3928  * The activity is equal to the activity of the corresponding row in the dual LP.
3929  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3930  * The sides of the dual row depend on the bounds of the column:
3931  * - lb == ub : dual row is a free row with infinite sides
3932  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3933  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3934  * - lb < ub <= 0: obj <= activity => redcost <= 0
3935  */
3936  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3937  {
3938  /* dual row is free */
3939  return SCIPsetInfinity(set);
3940  }
3941  else
3942  {
3943  SCIP_Real redcost;
3944 
3945  /* calculate reduced costs */
3946  redcost = SCIPcolGetRedcost(col, stat, lp);
3947 
3948  if( !SCIPsetIsNegative(set, col->lb) )
3949  {
3950  /* dual row is activity <= obj <=> redcost >= 0 */
3951  return redcost;
3952  }
3953  else if( SCIPsetIsPositive(set, col->ub) )
3954  {
3955  /* dual row is activity == obj <=> redcost == 0 */
3956  return -REALABS(redcost);
3957  }
3958  else
3959  {
3960  /* dual row is activity >= obj <=> redcost <= 0 */
3961  return -redcost;
3962  }
3963  }
3964 }
3965 
3966 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
3968  SCIP_COL* col, /**< LP column */
3969  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
3970  )
3971 {
3972  SCIP_ROW* row;
3973  SCIP_Real farkas;
3974  int i;
3975 
3976  assert(col != NULL);
3977  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3978  assert(SCIPvarGetCol(col->var) == col);
3979  assert(dualfarkas != NULL);
3980 
3981  farkas = 0.0;
3982  for( i = 0; i < col->nlprows; ++i )
3983  {
3984  row = col->rows[i];
3985  assert(row != NULL);
3986  assert(row->lppos >= 0);
3987  farkas += col->vals[i] * dualfarkas[row->lppos];
3988  }
3989 
3990  if( col->nunlinked > 0 )
3991  {
3992  for( i = col->nlprows; i < col->len; ++i )
3993  {
3994  row = col->rows[i];
3995  assert(row != NULL);
3996  assert(row->lppos == -1 || col->linkpos[i] == -1);
3997  if( row->lppos >= 0 )
3998  farkas += col->vals[i] * dualfarkas[row->lppos];
3999  }
4000  }
4001 #ifndef NDEBUG
4002  else
4003  {
4004  for( i = col->nlprows; i < col->len; ++i )
4005  {
4006  row = col->rows[i];
4007  assert(row != NULL);
4008  assert(row->lppos == -1);
4009  assert(col->linkpos[i] >= 0);
4010  }
4011  }
4012 #endif
4013 
4014  return farkas;
4015 }
4016 
4017 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4018 static
4020  SCIP_COL* col /**< LP column */
4021  )
4022 {
4023  SCIP_ROW* row;
4024  SCIP_Real farkas;
4025  int i;
4026 
4027  assert(col != NULL);
4028  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4029  assert(SCIPvarGetCol(col->var) == col);
4030 
4031  farkas = 0.0;
4032  for( i = 0; i < col->nlprows; ++i )
4033  {
4034  row = col->rows[i];
4035  assert(row != NULL);
4036  assert(row->dualfarkas < SCIP_INVALID);
4037  assert(row->lppos >= 0);
4038  assert(col->linkpos[i] >= 0);
4039  farkas += col->vals[i] * row->dualfarkas;
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 >= 0 || row->dualfarkas == 0.0);
4049  assert(row->lppos == -1 || col->linkpos[i] == -1);
4050  if( row->lppos >= 0 )
4051  farkas += col->vals[i] * row->dualfarkas;
4052  }
4053  }
4054 #ifndef NDEBUG
4055  else
4056  {
4057  for( i = col->nlprows; i < col->len; ++i )
4058  {
4059  row = col->rows[i];
4060  assert(row != NULL);
4061  assert(row->dualfarkas == 0.0);
4062  assert(row->lppos == -1);
4063  assert(col->linkpos[i] >= 0);
4064  }
4065  }
4066 #endif
4067 
4068  return farkas;
4069 }
4070 
4071 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4073  SCIP_COL* col, /**< LP column */
4074  SCIP_STAT* stat, /**< problem statistics */
4075  SCIP_LP* lp /**< current LP data */
4076  )
4077 {
4078  assert(col != NULL);
4079  assert(stat != NULL);
4080  assert(lp != NULL);
4081  assert(col->validfarkaslp <= stat->lpcount);
4082  assert(lp->validfarkaslp == stat->lpcount);
4083 
4084  if( col->validfarkaslp < stat->lpcount )
4085  {
4087  col->validfarkaslp = stat->lpcount;
4088  }
4089  assert(col->validfarkaslp == stat->lpcount);
4090  assert(col->farkascoef < SCIP_INVALID);
4091 
4092  return col->farkascoef;
4093 }
4094 
4095 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4096  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4097  */
4099  SCIP_COL* col, /**< LP column */
4100  SCIP_STAT* stat, /**< problem statistics */
4101  SCIP_LP* lp /**< current LP data */
4102  )
4103 {
4104  SCIP_Real farkascoef;
4105 
4106  assert(col != NULL);
4107 
4108  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4109 
4110  if( farkascoef > 0.0 )
4111  return col->ub * farkascoef;
4112  else
4113  return col->lb * farkascoef;
4114 }
4115 
4116 /** start strong branching - call before any strong branching */
4118  SCIP_LP* lp /**< LP data */
4119  )
4120 {
4121  assert(lp != NULL);
4122  assert(!lp->strongbranching);
4123 
4124  lp->strongbranching = TRUE;
4125  SCIPdebugMessage("starting strong branching ...\n");
4127 
4128  return SCIP_OKAY;
4129 }
4130 
4131 /** end strong branching - call after any strong branching */
4133  SCIP_LP* lp /**< LP data */
4134  )
4135 {
4136  assert(lp != NULL);
4137  assert(lp->strongbranching);
4138 
4139  lp->strongbranching = FALSE;
4140  SCIPdebugMessage("ending strong branching ...\n");
4142 
4143  return SCIP_OKAY;
4144 }
4145 
4146 /** sets strong branching information for a column variable */
4148  SCIP_COL* col, /**< LP column */
4149  SCIP_SET* set, /**< global SCIP settings */
4150  SCIP_STAT* stat, /**< dynamic problem statistics */
4151  SCIP_LP* lp, /**< LP data */
4152  SCIP_Real lpobjval, /**< objective value of the current LP */
4153  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4154  SCIP_Real sbdown, /**< dual bound after branching column down */
4155  SCIP_Real sbup, /**< dual bound after branching column up */
4156  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4157  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4158  SCIP_Longint iter, /**< total number of strong branching iterations */
4159  int itlim /**< iteration limit applied to the strong branching call */
4160  )
4161 {
4162  assert(col != NULL);
4163  assert(col->var != NULL);
4164  assert(SCIPcolIsIntegral(col));
4165  assert(SCIPvarIsIntegral(col->var));
4166  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4167  assert(SCIPvarGetCol(col->var) == col);
4168  assert(col->lpipos >= 0);
4169  assert(col->lppos >= 0);
4170  assert(set != NULL);
4171  assert(stat != NULL);
4172  assert(lp != NULL);
4173  assert(lp->strongbranchprobing);
4174  assert(col->lppos < lp->ncols);
4175  assert(lp->cols[col->lppos] == col);
4176  assert(itlim >= 1);
4177 
4178  col->sblpobjval = lpobjval;
4179  col->sbsolval = primsol;
4180  col->validsblp = stat->nlps;
4181  col->sbnode = stat->nnodes;
4182 
4183  col->sbitlim = itlim;
4184  col->nsbcalls++;
4185 
4186  col->sbdown = MIN(sbdown, lp->cutoffbound);
4187  col->sbup = MIN(sbup, lp->cutoffbound);
4188  col->sbdownvalid = sbdownvalid;
4189  col->sbupvalid = sbupvalid;
4190 
4191  SCIPstatIncrement(stat, set, nstrongbranchs);
4192  SCIPstatAdd(stat, set, nsblpiterations, iter);
4193  if( stat->nnodes == 1 )
4194  {
4195  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4196  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4197  }
4198 }
4199 
4200 /** invalidates strong branching information for a column variable */
4202  SCIP_COL* col, /**< LP column */
4203  SCIP_SET* set, /**< global SCIP settings */
4204  SCIP_STAT* stat, /**< dynamic problem statistics */
4205  SCIP_LP* lp /**< LP data */
4206  )
4207 {
4208  assert(col != NULL);
4209  assert(col->var != NULL);
4210  assert(SCIPcolIsIntegral(col));
4211  assert(SCIPvarIsIntegral(col->var));
4212  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4213  assert(SCIPvarGetCol(col->var) == col);
4214  assert(col->lpipos >= 0);
4215  assert(col->lppos >= 0);
4216  assert(set != NULL);
4217  assert(stat != NULL);
4218  assert(lp != NULL);
4219  assert(lp->strongbranchprobing);
4220  assert(col->lppos < lp->ncols);
4221  assert(lp->cols[col->lppos] == col);
4222 
4223  col->sbdown = SCIP_INVALID;
4224  col->sbup = SCIP_INVALID;
4225  col->sbdownvalid = FALSE;
4226  col->sbupvalid = FALSE;
4227  col->validsblp = -1;
4228  col->sbsolval = SCIP_INVALID;
4229  col->sblpobjval = SCIP_INVALID;
4230  col->sbnode = -1;
4231  col->sbitlim = -1;
4232 }
4233 
4234 
4235 /** gets strong branching information on a column variable */
4237  SCIP_COL* col, /**< LP column */
4238  SCIP_Bool integral, /**< should integral strong branching be performed? */
4239  SCIP_SET* set, /**< global SCIP settings */
4240  SCIP_STAT* stat, /**< dynamic problem statistics */
4241  SCIP_PROB* prob, /**< problem data */
4242  SCIP_LP* lp, /**< LP data */
4243  int itlim, /**< iteration limit for strong branchings */
4244  SCIP_Real* down, /**< stores dual bound after branching column down */
4245  SCIP_Real* up, /**< stores dual bound after branching column up */
4246  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4247  * otherwise, it can only be used as an estimate value */
4248  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4249  * otherwise, it can only be used as an estimate value */
4250  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4251  )
4252 {
4253  assert(col != NULL);
4254  assert(col->var != NULL);
4255  assert(SCIPcolIsIntegral(col));
4256  assert(SCIPvarIsIntegral(col->var));
4257  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4258  assert(SCIPvarGetCol(col->var) == col);
4259  assert(col->primsol < SCIP_INVALID);
4260  assert(col->lpipos >= 0);
4261  assert(col->lppos >= 0);
4262  assert(set != NULL);
4263  assert(stat != NULL);
4264  assert(lp != NULL);
4265  assert(lp->flushed);
4266  assert(lp->solved);
4267  assert(lp->strongbranching);
4268  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4269  assert(lp->validsollp == stat->lpcount);
4270  assert(col->lppos < lp->ncols);
4271  assert(lp->cols[col->lppos] == col);
4272  assert(itlim >= 1);
4273  /* assert(down != NULL);
4274  * assert(up != NULL); temporary hack for cloud branching
4275  */
4276  assert(lperror != NULL);
4277 
4278  *lperror = FALSE;
4279 
4280  if( col->validsblp != stat->nlps || itlim > col->sbitlim )
4281  {
4282  col->validsblp = stat->nlps;
4283  col->sbsolval = col->primsol;
4284  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4285  col->sbnode = stat->nnodes;
4286  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4287 
4288  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4289  if( lp->looseobjvalinf > 0 )
4290  {
4291  col->sbdown = -SCIPsetInfinity(set);
4292  col->sbup = -SCIPsetInfinity(set);
4293  col->sbdownvalid = FALSE;
4294  col->sbupvalid = FALSE;
4295  }
4296  else
4297  {
4298  SCIP_RETCODE retcode;
4299  SCIP_Real sbdown;
4300  SCIP_Real sbup;
4301  SCIP_Bool sbdownvalid;
4302  SCIP_Bool sbupvalid;
4303  int iter;
4304 
4305  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4306  SCIPvarGetName(col->var), col->primsol, itlim);
4307 
4308  /* start timing */
4309  SCIPclockStart(stat->strongbranchtime, set);
4310 
4311  /* call LPI strong branching */
4312  col->sbitlim = itlim;
4313  col->nsbcalls++;
4314 
4315  sbdown = lp->lpobjval;
4316  sbup = lp->lpobjval;
4317 
4318  if( integral )
4319  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4320  else
4321  {
4322  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4323  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4324  }
4325 
4326  /* check return code for errors */
4327  if( retcode == SCIP_LPERROR )
4328  {
4329  *lperror = TRUE;
4330  col->sbdown = SCIP_INVALID;
4331  col->sbup = SCIP_INVALID;
4332  col->sbdownvalid = FALSE;
4333  col->sbupvalid = FALSE;
4334  col->validsblp = -1;
4335  col->sbsolval = SCIP_INVALID;
4336  col->sblpobjval = SCIP_INVALID;
4337  col->sbnode = -1;
4338  }
4339  else
4340  {
4341  SCIP_Real looseobjval;
4342 
4343  *lperror = FALSE;
4344  SCIP_CALL( retcode );
4345 
4346  looseobjval = getFiniteLooseObjval(lp, set, prob);
4347  col->sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4348  col->sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4349 
4350  col->sbdownvalid = sbdownvalid;
4351  col->sbupvalid = sbupvalid;
4352 
4353  /* update strong branching statistics */
4354  if( iter == -1 )
4355  {
4356  /* calculate average iteration number */
4357  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4358  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4359  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4360  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4361  : 0;
4362  if( iter/2 >= itlim )
4363  iter = 2*itlim;
4364  }
4365  SCIPstatIncrement(stat, set, nstrongbranchs);
4366  SCIPstatAdd(stat, set, nsblpiterations, iter);
4367  if( stat->nnodes == 1 )
4368  {
4369  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4370  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4371  }
4372  }
4373 
4374  /* stop timing */
4375  SCIPclockStop(stat->strongbranchtime, set);
4376  }
4377  }
4378  assert(*lperror || col->sbdown < SCIP_INVALID);
4379  assert(*lperror || col->sbup < SCIP_INVALID);
4380 
4381  if( down != NULL)
4382  *down = col->sbdown;
4383  if( up != NULL )
4384  *up = col->sbup;
4385  if( downvalid != NULL )
4386  *downvalid = col->sbdownvalid;
4387  if( upvalid != NULL )
4388  *upvalid = col->sbupvalid;
4389 
4390  return SCIP_OKAY;
4391 }
4392 
4393 /** gets strong branching information on column variables */
4395  SCIP_COL** cols, /**< LP columns */
4396  int ncols, /**< number of columns */
4397  SCIP_Bool integral, /**< should integral strong branching be performed? */
4398  SCIP_SET* set, /**< global SCIP settings */
4399  SCIP_STAT* stat, /**< dynamic problem statistics */
4400  SCIP_PROB* prob, /**< problem data */
4401  SCIP_LP* lp, /**< LP data */
4402  int itlim, /**< iteration limit for strong branchings */
4403  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4404  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4405  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4406  * otherwise, they can only be used as an estimate value */
4407  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4408  * otherwise, they can only be used as an estimate value */
4409  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4410  )
4411 {
4412  SCIP_RETCODE retcode;
4413  SCIP_Real* sbdown;
4414  SCIP_Real* sbup;
4415  SCIP_Bool* sbdownvalid;
4416  SCIP_Bool* sbupvalid;
4417  SCIP_Real* primsols;
4418  SCIP_COL** subcols;
4419  int* lpipos;
4420  int* subidx;
4421  int nsubcols;
4422  int iter;
4423  int j;
4424 
4425  assert(cols != NULL);
4426  assert(set != NULL);
4427  assert(stat != NULL);
4428  assert(lp != NULL);
4429  assert(lp->flushed);
4430  assert(lp->solved);
4431  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4432  assert(lp->validsollp == stat->lpcount);
4433  assert(itlim >= 1);
4434  assert(down != NULL);
4435  assert(up != NULL);
4436  assert(lperror != NULL);
4437 
4438  *lperror = FALSE;
4439 
4440  if ( ncols <= 0 )
4441  return SCIP_OKAY;
4442 
4443  /* start timing */
4444  SCIPclockStart(stat->strongbranchtime, set);
4445 
4446  /* initialize storage */
4447  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4448  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4449  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4450  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4451  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4452  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4453  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4454  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4455 
4456  nsubcols = 0;
4457  for( j = 0; j < ncols; ++j )
4458  {
4459  SCIP_COL* col;
4460  col = cols[j];
4461 
4462  assert(col->lppos < lp->ncols);
4463  assert(lp->cols[col->lppos] == col);
4464  assert(SCIPcolIsIntegral(col));
4465  assert(SCIPvarIsIntegral(col->var));
4466  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4467  assert(SCIPvarGetCol(col->var) == col);
4468  assert(col->primsol < SCIP_INVALID);
4469  assert(col->lpipos >= 0);
4470  assert(col->lppos >= 0);
4471 
4472  if( col->validsblp != stat->nlps || itlim > col->sbitlim )
4473  {
4474  col->validsblp = stat->nlps;
4475  col->sbsolval = col->primsol;
4476  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4477  col->sbnode = stat->nnodes;
4478  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4479 
4480  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4481  if( lp->looseobjvalinf > 0 )
4482  {
4483  /* directly set up column and result vectors*/
4484  col->sbdown = -SCIPsetInfinity(set);
4485  col->sbup = -SCIPsetInfinity(set);
4486  col->sbdownvalid = FALSE;
4487  col->sbupvalid = FALSE;
4488  down[j] = col->sbdown;
4489  up[j] = col->sbup;
4490  if( downvalid != NULL )
4491  downvalid[j] = col->sbdownvalid;
4492  if( upvalid != NULL )
4493  upvalid[j] = col->sbupvalid;
4494  }
4495  else
4496  {
4497  col->sbitlim = itlim;
4498  col->nsbcalls++;
4499 
4500  lpipos[nsubcols] = col->lpipos;
4501  primsols[nsubcols] = col->primsol;
4502  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4503  subidx[nsubcols] = j;
4504  subcols[nsubcols++] = col;
4505  }
4506  }
4507  else
4508  {
4509  /* directly set up resulting values (use stored values) */
4510  down[j] = col->sbdown;
4511  up[j] = col->sbup;
4512  if( downvalid != NULL )
4513  downvalid[j] = col->sbdownvalid;
4514  if( upvalid != NULL )
4515  upvalid[j] = col->sbupvalid;
4516  }
4517  }
4518 
4519  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4520 
4521  /* call LPI strong branching */
4522  if ( integral )
4523  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4524  else
4525  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4526 
4527  /* check return code for errors */
4528  if( retcode == SCIP_LPERROR )
4529  {
4530  *lperror = TRUE;
4531 
4532  for( j = 0; j < nsubcols; ++j )
4533  {
4534  SCIP_COL* col;
4535  int idx;
4536 
4537  col = subcols[j];
4538  idx = subidx[j];
4539 
4540  col->sbdown = SCIP_INVALID;
4541  col->sbup = SCIP_INVALID;
4542  col->sbdownvalid = FALSE;
4543  col->sbupvalid = FALSE;
4544  col->validsblp = -1;
4545  col->sbsolval = SCIP_INVALID;
4546  col->sblpobjval = SCIP_INVALID;
4547  col->sbnode = -1;
4548 
4549  down[idx] = col->sbdown;
4550  up[idx] = col->sbup;
4551  if( downvalid != NULL )
4552  downvalid[idx] = col->sbdownvalid;
4553  if( upvalid != NULL )
4554  upvalid[idx] = col->sbupvalid;
4555  }
4556  }
4557  else
4558  {
4559  SCIP_Real looseobjval;
4560 
4561  *lperror = FALSE;
4562  SCIP_CALL( retcode );
4563 
4564  looseobjval = getFiniteLooseObjval(lp, set, prob);
4565 
4566  for( j = 0; j < nsubcols; ++j )
4567  {
4568  SCIP_COL* col;
4569  int idx;
4570 
4571  col = subcols[j];
4572  idx = subidx[j];
4573 
4574  assert( col->sbdown < SCIP_INVALID);
4575  assert( col->sbup < SCIP_INVALID);
4576 
4577  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4578  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4579  col->sbdownvalid = sbdownvalid[j];
4580  col->sbupvalid = sbupvalid[j];
4581 
4582  down[idx] = col->sbdown;
4583  up[idx] = col->sbup;
4584  if( downvalid != NULL )
4585  downvalid[idx] = col->sbdownvalid;
4586  if( upvalid != NULL )
4587  upvalid[idx] = col->sbupvalid;
4588  }
4589 
4590  /* update strong branching statistics */
4591  if( iter == -1 )
4592  {
4593  /* calculate average iteration number */
4594  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4595  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4596  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4597  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4598  : 0;
4599  if( iter/2 >= itlim )
4600  iter = 2*itlim;
4601  }
4602  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4603  SCIPstatAdd(stat, set, nsblpiterations, iter);
4604  if( stat->nnodes == 1 )
4605  {
4606  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4607  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4608  }
4609  }
4610 
4611  SCIPsetFreeBufferArray(set, &sbupvalid);
4612  SCIPsetFreeBufferArray(set, &sbdownvalid);
4613  SCIPsetFreeBufferArray(set, &sbup);
4614  SCIPsetFreeBufferArray(set, &sbdown);
4615  SCIPsetFreeBufferArray(set, &primsols);
4616  SCIPsetFreeBufferArray(set, &lpipos);
4617  SCIPsetFreeBufferArray(set, &subidx);
4618  SCIPsetFreeBufferArray(set, &subcols);
4619 
4620  /* stop timing */
4621  SCIPclockStop(stat->strongbranchtime, set);
4622 
4623  return SCIP_OKAY;
4624 }
4625 
4626 /** gets last strong branching information available for a column variable;
4627  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4628  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4629  */
4631  SCIP_COL* col, /**< LP column */
4632  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4633  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4634  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4635  * otherwise, it can only be used as an estimate value */
4636  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4637  * otherwise, it can only be used as an estimate value */
4638  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4639  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4640  )
4641 {
4642  assert(col != NULL);
4643 
4644  if( down != NULL )
4645  *down = col->sbdown;
4646  if( up != NULL )
4647  *up = col->sbup;
4648  if( downvalid != NULL )
4649  *downvalid = col->sbdownvalid;
4650  if( upvalid != NULL )
4651  *upvalid = col->sbupvalid;
4652  if( solval != NULL )
4653  *solval = col->sbsolval;
4654  if( lpobjval != NULL )
4655  *lpobjval = col->sblpobjval;
4656 }
4657 
4658 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4659  * the LP where the strong branching on this column was applied;
4660  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4661  */
4663  SCIP_COL* col, /**< LP column */
4664  SCIP_STAT* stat /**< dynamic problem statistics */
4665  )
4666 {
4667  assert(col != NULL);
4668  assert(stat != NULL);
4669 
4670  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4671 }
4672 
4673 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4675  SCIP_COL* col, /**< LP column */
4676  SCIP_STAT* stat /**< problem statistics */
4677  )
4678 {
4679  assert(col != NULL);
4680  assert(stat != NULL);
4681  assert(stat->nnodes > 0);
4682 
4683  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4684  col->obsoletenode = stat->nnodes;
4685 }
4686 
4687 
4688 /*
4689  * Row methods
4690  */
4691 
4692 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4693 static
4695  SCIP_ROW* row, /**< LP row */
4696  SCIP_SET* set /**< global SCIP settings */
4697  )
4698 {
4699  int i;
4700 
4701  assert(row != NULL);
4702  assert(set != NULL);
4703 
4704  row->sqrnorm = 0.0;
4705  row->sumnorm = 0.0;
4706  row->objprod = 0.0;
4707  row->maxval = 0.0;
4708  row->nummaxval = 1;
4709  row->minval = SCIPsetInfinity(set);
4710  row->numminval = 1;
4711  row->minidx = INT_MAX;
4712  row->maxidx = INT_MIN;
4713  row->validminmaxidx = TRUE;
4714  row->lpcolssorted = TRUE;
4715  row->nonlpcolssorted = TRUE;
4716 
4717  /* check, if row is sorted
4718  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4719  */
4720  for( i = 0; i < row->nlpcols; ++i )
4721  {
4722  assert(row->cols[i] != NULL);
4723  assert(!SCIPsetIsZero(set, row->vals[i]));
4724  assert(row->cols[i]->lppos >= 0);
4725  assert(row->linkpos[i] >= 0);
4726  assert(row->cols[i]->index == row->cols_index[i]);
4727 
4728  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4729  if( i > 0 )
4730  {
4731  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4732  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4733  }
4734  }
4735  for( i = row->nlpcols; i < row->len; ++i )
4736  {
4737  assert(row->cols[i] != NULL);
4738  assert(!SCIPsetIsZero(set, row->vals[i]));
4739  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4740  assert(row->cols[i]->index == row->cols_index[i]);
4741 
4742  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4743  if( i > row->nlpcols )
4744  {
4745  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4746  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4747  }
4748  }
4749 }
4750 
4751 /** calculates min/maxval and min/maxidx from scratch */
4752 static
4754  SCIP_ROW* row, /**< LP row */
4755  SCIP_SET* set /**< global SCIP settings */
4756  )
4757 {
4758  SCIP_COL* col;
4759  SCIP_Real absval;
4760  int i;
4761 
4762  assert(row != NULL);
4763  assert(set != NULL);
4764 
4765  row->maxval = 0.0;
4766  row->nummaxval = 1;
4767  row->numintcols = 0;
4768  row->minval = SCIPsetInfinity(set);
4769  row->numminval = 1;
4770  row->minidx = INT_MAX;
4771  row->maxidx = INT_MIN;
4772  row->validminmaxidx = TRUE;
4773 
4774  /* calculate maxval, minval, minidx, and maxidx */
4775  for( i = 0; i < row->len; ++i )
4776  {
4777  col = row->cols[i];
4778  assert(col != NULL);
4779  assert(!SCIPsetIsZero(set, row->vals[i]));
4780 
4781  absval = REALABS(row->vals[i]);
4782  assert(!SCIPsetIsZero(set, absval));
4783 
4784  /* update min/maxidx */
4785  row->minidx = MIN(row->minidx, col->index);
4786  row->maxidx = MAX(row->maxidx, col->index);
4787  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4788 
4789  /* update maximal and minimal non-zero value */
4790  if( row->nummaxval > 0 )
4791  {
4792  if( SCIPsetIsGT(set, absval, row->maxval) )
4793  {
4794  row->maxval = absval;
4795  row->nummaxval = 1;
4796  }
4797  else if( SCIPsetIsGE(set, absval, row->maxval) )
4798  {
4799  /* make sure the maxval is always exactly the same */
4800  row->maxval = MAX(absval, row->maxval);
4801  row->nummaxval++;
4802  }
4803  }
4804  if( row->numminval > 0 )
4805  {
4806  if( SCIPsetIsLT(set, absval, row->minval) )
4807  {
4808  row->minval = absval;
4809  row->numminval = 1;
4810  }
4811  else if( SCIPsetIsLE(set, absval, row->minval) )
4812  {
4813  /* make sure the minval is always exactly the same */
4814  row->minval = MIN(absval, row->minval);
4815  row->numminval++;
4816  }
4817  }
4818  }
4819 }
4820 
4821 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4822 static
4824  SCIP_Real val, /**< value that should be scaled to an integral value */
4825  SCIP_Real scalar, /**< scalar that should be tried */
4826  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4827  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4828  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4829  )
4830 {
4831  SCIP_Real sval;
4832  SCIP_Real downval;
4833  SCIP_Real upval;
4834 
4835  assert(mindelta <= 0.0);
4836  assert(maxdelta >= 0.0);
4837 
4838  sval = val * scalar;
4839  downval = floor(sval);
4840  upval = ceil(sval);
4841 
4842  if( SCIPrelDiff(sval, downval) <= maxdelta )
4843  {
4844  if( intval != NULL )
4845  *intval = downval;
4846  return TRUE;
4847  }
4848  else if( SCIPrelDiff(sval, upval) >= mindelta )
4849  {
4850  if( intval != NULL )
4851  *intval = upval;
4852  return TRUE;
4853  }
4854 
4855  return FALSE;
4856 }
4857 
4858 /** scales row with given factor, and rounds coefficients to integers if close enough;
4859  * the constant is automatically moved to the sides;
4860  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4861  */
4862 static
4864  SCIP_ROW* row, /**< LP row */
4865  BMS_BLKMEM* blkmem, /**< block memory */
4866  SCIP_SET* set, /**< global SCIP settings */
4867  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4868  SCIP_STAT* stat, /**< problem statistics */
4869  SCIP_LP* lp, /**< current LP data */
4870  SCIP_Real scaleval, /**< value to scale row with */
4871  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4872  * if they are close to integral values? */
4873  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4874  * upto which the integral is used instead of the scaled real coefficient */
4875  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4876  * upto which the integral is used instead of the scaled real coefficient */
4877  )
4878 {
4879  SCIP_COL* col;
4880  SCIP_Real val;
4881  SCIP_Real newval;
4882  SCIP_Real intval;
4883  SCIP_Real mindelta;
4884  SCIP_Real maxdelta;
4885  SCIP_Real lb;
4886  SCIP_Real ub;
4887  SCIP_Bool mindeltainf;
4888  SCIP_Bool maxdeltainf;
4889  int oldlen;
4890  int c;
4891 
4892  assert(row != NULL);
4893  assert(row->len == 0 || row->cols != NULL);
4894  assert(row->len == 0 || row->vals != NULL);
4895  assert(SCIPsetIsPositive(set, scaleval));
4896  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4897  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4898 
4899  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4900 
4901  mindelta = 0.0;
4902  maxdelta = 0.0;
4903  mindeltainf = FALSE;
4904  maxdeltainf = FALSE;
4905  oldlen = row->len;
4906 
4907  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4908  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4909  * this rounding can lead to
4910  */
4911  row->integral = TRUE;
4912 
4913  c = 0;
4914  while( c < row->len )
4915  {
4916  col = row->cols[c];
4917  val = row->vals[c];
4918  assert(!SCIPsetIsZero(set, val));
4919 
4920  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4921  if( row->local )
4922  {
4923  lb = col->lb;
4924  ub = col->ub;
4925  }
4926  else
4927  {
4928  lb = SCIPvarGetLbGlobal(col->var);
4929  ub = SCIPvarGetUbGlobal(col->var);
4930  }
4931 
4932  /* calculate scaled coefficient */
4933  newval = val * scaleval;
4934  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
4935  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
4936  {
4937  if( !SCIPsetIsEQ(set, intval, newval) )
4938  {
4939  if( intval < newval )
4940  {
4941  mindelta += (intval - newval)*ub;
4942  maxdelta += (intval - newval)*lb;
4943  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
4944  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
4945  }
4946  else
4947  {
4948  mindelta += (intval - newval)*lb;
4949  maxdelta += (intval - newval)*ub;
4950  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
4951  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
4952  }
4953  }
4954  newval = intval;
4955  }
4956 
4957  if( !SCIPsetIsEQ(set, val, newval) )
4958  {
4959  /* if column knows of the row, change the corresponding coefficient in the column */
4960  if( row->linkpos[c] >= 0 )
4961  {
4962  assert(col->rows[row->linkpos[c]] == row);
4963  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
4964  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
4965  }
4966 
4967  /* change the coefficient in the row, and update the norms and integrality status */
4968  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
4969 
4970  /* current coefficient has been deleted from the row because it was almost zero */
4971  if( oldlen != row->len )
4972  {
4973  assert(row->len == oldlen - 1);
4974  c--;
4975  oldlen = row->len;
4976  }
4977  }
4978  else
4979  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
4980 
4981  ++c;
4982  }
4983 
4984  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
4985  * to not destroy feasibility due to rounding
4986  */
4987  /**@todo ensure that returned cut does not have infinite lhs and rhs */
4988  if( !SCIPsetIsInfinity(set, -row->lhs) )
4989  {
4990  if( mindeltainf )
4991  newval = -SCIPsetInfinity(set);
4992  else
4993  {
4994  newval = (row->lhs - row->constant) * scaleval + mindelta;
4995  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
4996  newval = SCIPsetSumCeil(set, newval);
4997  }
4998  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
4999  }
5000  if( !SCIPsetIsInfinity(set, row->rhs) )
5001  {
5002  if( maxdeltainf )
5003  newval = SCIPsetInfinity(set);
5004  else
5005  {
5006  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5007  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5008  newval = SCIPsetSumFloor(set, newval);
5009  }
5010  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5011  }
5012 
5013  /* clear the row constant */
5014  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5015 
5016  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5017  debugRowPrint(set, row);
5018 
5019 #ifdef SCIP_DEBUG
5020  /* check integrality status of row */
5021  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5022  {}
5023  assert(row->integral == (c == row->len));
5024 #endif
5025 
5026  /* invalid the activity */
5027  row->validactivitylp = -1;
5028 
5029  return SCIP_OKAY;
5030 }
5031 
5032 /** creates and captures an LP row */
5034  SCIP_ROW** row, /**< pointer to LP row data */
5035  BMS_BLKMEM* blkmem, /**< block memory */
5036  SCIP_SET* set, /**< global SCIP settings */
5037  SCIP_STAT* stat, /**< problem statistics */
5038  SCIP_LP* lp, /**< current LP data */
5039  const char* name, /**< name of row */
5040  int len, /**< number of nonzeros in the row */
5041  SCIP_COL** cols, /**< array with columns of row entries */
5042  SCIP_Real* vals, /**< array with coefficients of row entries */
5043  SCIP_Real lhs, /**< left hand side of row */
5044  SCIP_Real rhs, /**< right hand side of row */
5045  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5046  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5047  SCIP_Bool local, /**< is row only valid locally? */
5048  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5049  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5050  )
5051 {
5052  assert(row != NULL);
5053  assert(blkmem != NULL);
5054  assert(stat != NULL);
5055  assert(len >= 0);
5056  assert(len == 0 || (cols != NULL && vals != NULL));
5057  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5058  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5059  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5060  */
5061  assert(lhs <= rhs);
5062 
5063  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5064 
5065  (*row)->integral = TRUE;
5066  if( len > 0 )
5067  {
5068  SCIP_VAR* var;
5069  int i;
5070 
5071  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5072  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5073  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5074  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5075 
5076  for( i = 0; i < len; ++i )
5077  {
5078  assert(cols[i] != NULL);
5079  assert(!SCIPsetIsZero(set, vals[i]));
5080 
5081  var = cols[i]->var;
5082  (*row)->cols_index[i] = cols[i]->index;
5083  (*row)->linkpos[i] = -1;
5084  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5085  {
5086  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5087  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5088  }
5089  else
5090  {
5091  (*row)->integral = FALSE;
5092  }
5093  }
5094  }
5095  else
5096  {
5097  (*row)->cols = NULL;
5098  (*row)->cols_index = NULL;
5099  (*row)->vals = NULL;
5100  (*row)->linkpos = NULL;
5101  }
5102 
5103  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5104  (*row)->constant = 0.0;
5105  (*row)->lhs = lhs;
5106  (*row)->rhs = rhs;
5107  (*row)->flushedlhs = -SCIPsetInfinity(set);
5108  (*row)->flushedrhs = SCIPsetInfinity(set);
5109  (*row)->sqrnorm = 0.0;
5110  (*row)->sumnorm = 0.0;
5111  (*row)->objprod = 0.0;
5112  (*row)->maxval = 0.0;
5113  (*row)->minval = SCIPsetInfinity(set);
5114  (*row)->dualsol = 0.0;
5115  (*row)->activity = SCIP_INVALID;
5116  (*row)->dualfarkas = 0.0;
5117  (*row)->pseudoactivity = SCIP_INVALID;
5118  (*row)->minactivity = SCIP_INVALID;
5119  (*row)->maxactivity = SCIP_INVALID;
5120  (*row)->origin = origin;
5121  (*row)->eventfilter = NULL;
5122  (*row)->index = stat->nrowidx;
5123  SCIPstatIncrement(stat, set, nrowidx);
5124  (*row)->size = len;
5125  (*row)->len = len;
5126  (*row)->nlpcols = 0;
5127  (*row)->nunlinked = len;
5128  (*row)->nuses = 0;
5129  (*row)->lppos = -1;
5130  (*row)->lpipos = -1;
5131  (*row)->lpdepth = -1;
5132  (*row)->minidx = INT_MAX;
5133  (*row)->maxidx = INT_MIN;
5134  (*row)->nummaxval = 0;
5135  (*row)->numminval = 0;
5136  (*row)->numintcols = -1;
5137  (*row)->validactivitylp = -1;
5138  (*row)->validpsactivitydomchg = -1;
5139  (*row)->validactivitybdsdomchg = -1;
5140  (*row)->nlpsaftercreation = 0L;
5141  (*row)->activeinlpcounter = 0L;
5142  (*row)->age = 0;
5143  (*row)->rank = 0;
5144  (*row)->obsoletenode = -1;
5145  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5146  (*row)->lpcolssorted = TRUE;
5147  (*row)->nonlpcolssorted = (len <= 1);
5148  (*row)->delaysort = FALSE;
5149  (*row)->validminmaxidx = FALSE;
5150  (*row)->lhschanged = FALSE;
5151  (*row)->rhschanged = FALSE;
5152  (*row)->coefchanged = FALSE;
5153  (*row)->local = local;
5154  (*row)->modifiable = modifiable;
5155  (*row)->nlocks = 0;
5156  (*row)->origintype = origintype; /*lint !e641*/
5157  (*row)->removable = removable;
5158  (*row)->inglobalcutpool = FALSE;
5159  (*row)->storedsolvals = NULL;
5160 
5161  /* calculate row norms and min/maxidx, and check if row is sorted */
5162  rowCalcNorms(*row, set);
5163 
5164  /* capture the row */
5165  SCIProwCapture(*row);
5166 
5167  /* create event filter */
5168  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5169 
5170  return SCIP_OKAY;
5171 } /*lint !e715*/
5172 
5173 /** frees an LP row */
5175  SCIP_ROW** row, /**< pointer to LP row */
5176  BMS_BLKMEM* blkmem, /**< block memory */
5177  SCIP_SET* set, /**< global SCIP settings */
5178  SCIP_LP* lp /**< current LP data */
5179  )
5180 {
5181  assert(blkmem != NULL);
5182  assert(row != NULL);
5183  assert(*row != NULL);
5184  assert((*row)->nuses == 0);
5185  assert((*row)->lppos == -1);
5186  assert((*row)->eventfilter != NULL);
5187 
5188  /* remove column indices from corresponding rows */
5189  SCIP_CALL( rowUnlink(*row, set, lp) );
5190 
5191  /* free event filter */
5192  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5193 
5194  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5195  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5196  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5197  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5198  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5199  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5200  BMSfreeBlockMemory(blkmem, row);
5201 
5202  return SCIP_OKAY;
5203 }
5204 
5205 /** output row to file stream */
5207  SCIP_ROW* row, /**< LP row */
5208  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5209  FILE* file /**< output file (or NULL for standard output) */
5210  )
5211 {
5212  int i;
5213 
5214  assert(row != NULL);
5215 
5216  /* print row name */
5217  if( row->name != NULL && row->name[0] != '\0' )
5218  {
5219  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5220  }
5221 
5222  /* print left hand side */
5223  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5224 
5225  /* print coefficients */
5226  if( row->len == 0 )
5227  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5228  for( i = 0; i < row->len; ++i )
5229  {
5230  assert(row->cols[i] != NULL);
5231  assert(row->cols[i]->var != NULL);
5232  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5233  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5234  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5235  }
5236 
5237  /* print constant */
5238  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5239  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5240 
5241  /* print right hand side */
5242  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5243 }
5244 
5245 /** increases usage counter of LP row */
5247  SCIP_ROW* row /**< LP row */
5248  )
5249 {
5250  assert(row != NULL);
5251  assert(row->nuses >= 0);
5252  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5253 
5254  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5255  row->nuses++;
5256 }
5257 
5258 /** decreases usage counter of LP row, and frees memory if necessary */
5260  SCIP_ROW** row, /**< pointer to LP row */
5261  BMS_BLKMEM* blkmem, /**< block memory */
5262  SCIP_SET* set, /**< global SCIP settings */
5263  SCIP_LP* lp /**< current LP data */
5264  )
5265 {
5266  assert(blkmem != NULL);
5267  assert(row != NULL);
5268  assert(*row != NULL);
5269  assert((*row)->nuses >= 1);
5270  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5271 
5272  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5273  (*row)->nuses--;
5274  if( (*row)->nuses == 0 )
5275  {
5276  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5277  }
5278 
5279  *row = NULL;
5280 
5281  return SCIP_OKAY;
5282 }
5283 
5284 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5286  SCIP_ROW* row /**< LP row */
5287  )
5288 {
5289  assert(row != NULL);
5290 
5291  /* check, if row is modifiable */
5292  if( !row->modifiable )
5293  {
5294  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5295  row->nlocks++;
5296  }
5297 }
5298 
5299 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5301  SCIP_ROW* row /**< LP row */
5302  )
5303 {
5304  assert(row != NULL);
5305 
5306  /* check, if row is modifiable */
5307  if( !row->modifiable )
5308  {
5309  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5310  assert(row->nlocks > 0);
5311  row->nlocks--;
5312  }
5313 }
5314 
5315 /** adds a previously non existing coefficient to an LP row */
5317  SCIP_ROW* row, /**< LP row */
5318  BMS_BLKMEM* blkmem, /**< block memory */
5319  SCIP_SET* set, /**< global SCIP settings */
5320  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5321  SCIP_LP* lp, /**< current LP data */
5322  SCIP_COL* col, /**< LP column */
5323  SCIP_Real val /**< value of coefficient */
5324  )
5325 {
5326  assert(lp != NULL);
5327  assert(!lp->diving || row->lppos == -1);
5328 
5329  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5330 
5331  checkLinks(lp);
5332 
5333  return SCIP_OKAY;
5334 }
5335 
5336 /** deletes coefficient from row */
5338  SCIP_ROW* row, /**< row to be changed */
5339  BMS_BLKMEM* blkmem, /**< block memory */
5340  SCIP_SET* set, /**< global SCIP settings */
5341  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5342  SCIP_LP* lp, /**< current LP data */
5343  SCIP_COL* col /**< coefficient to be deleted */
5344  )
5345 {
5346  int pos;
5347 
5348  assert(row != NULL);
5349  assert(!row->delaysort);
5350  assert(lp != NULL);
5351  assert(!lp->diving || row->lppos == -1);
5352  assert(col != NULL);
5353  assert(col->var != NULL);
5354 
5355  /* search the position of the column in the row's col vector */
5356  pos = rowSearchCoef(row, col);
5357  if( pos == -1 )
5358  {
5359  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5360  return SCIP_INVALIDDATA;
5361  }
5362  assert(0 <= pos && pos < row->len);
5363  assert(row->cols[pos] == col);
5364  assert(row->cols_index[pos] == col->index);
5365 
5366  /* if column knows of the row, remove the row from the column's row vector */
5367  if( row->linkpos[pos] >= 0 )
5368  {
5369  assert(col->rows[row->linkpos[pos]] == row);
5370  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5371  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5372  }
5373 
5374  /* delete the column from the row's col vector */
5375  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5376 
5377  checkLinks(lp);
5378 
5379  return SCIP_OKAY;
5380 }
5381 
5382 /** changes or adds a coefficient to an LP row */
5384  SCIP_ROW* row, /**< LP row */
5385  BMS_BLKMEM* blkmem, /**< block memory */
5386  SCIP_SET* set, /**< global SCIP settings */
5387  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5388  SCIP_LP* lp, /**< current LP data */
5389  SCIP_COL* col, /**< LP column */
5390  SCIP_Real val /**< value of coefficient */
5391  )
5392 {
5393  int pos;
5394 
5395  assert(row != NULL);
5396  assert(!row->delaysort);
5397  assert(lp != NULL);
5398  assert(!lp->diving || row->lppos == -1);
5399  assert(col != NULL);
5400 
5401  /* search the position of the column in the row's col vector */
5402  pos = rowSearchCoef(row, col);
5403 
5404  /* check, if column already exists in the row's col vector */
5405  if( pos == -1 )
5406  {
5407  /* add previously not existing coefficient */
5408  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5409  }
5410  else
5411  {
5412  /* modify already existing coefficient */
5413  assert(0 <= pos && pos < row->len);
5414  assert(row->cols[pos] == col);
5415  assert(row->cols_index[pos] == col->index);
5416 
5417  /* if column knows of the row, change the corresponding coefficient in the column */
5418  if( row->linkpos[pos] >= 0 )
5419  {
5420  assert(col->rows[row->linkpos[pos]] == row);
5421  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5422  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5423  }
5424 
5425  /* change the coefficient in the row */
5426  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5427  }
5428 
5429  checkLinks(lp);
5430 
5431  return SCIP_OKAY;
5432 }
5433 
5434 /** increases value of an existing or non-existing coefficient in an LP row */
5436  SCIP_ROW* row, /**< LP row */
5437  BMS_BLKMEM* blkmem, /**< block memory */
5438  SCIP_SET* set, /**< global SCIP settings */
5439  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5440  SCIP_LP* lp, /**< current LP data */
5441  SCIP_COL* col, /**< LP column */
5442  SCIP_Real incval /**< value to add to the coefficient */
5443  )
5444 {
5445  int pos;
5446 
5447  assert(row != NULL);
5448  assert(lp != NULL);
5449  assert(!lp->diving || row->lppos == -1);
5450  assert(col != NULL);
5451 
5452  if( SCIPsetIsZero(set, incval) )
5453  return SCIP_OKAY;
5454 
5455  /* search the position of the column in the row's col vector */
5456  pos = rowSearchCoef(row, col);
5457 
5458  /* check, if column already exists in the row's col vector */
5459  if( pos == -1 )
5460  {
5461  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5462  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5463  }
5464  else
5465  {
5466  /* modify already existing coefficient */
5467  assert(0 <= pos && pos < row->len);
5468  assert(row->cols[pos] == col);
5469  assert(row->cols_index[pos] == col->index);
5470 
5471  /* if column knows of the row, change the corresponding coefficient in the column */
5472  if( row->linkpos[pos] >= 0 )
5473  {
5474  assert(col->rows[row->linkpos[pos]] == row);
5475  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5476  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5477  }
5478 
5479  /* change the coefficient in the row */
5480  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5481  }
5482 
5483  checkLinks(lp);
5484 
5485  /* invalid the activity */
5486  row->validactivitylp = -1;
5487 
5488  return SCIP_OKAY;
5489 }
5490 
5491 /** changes constant value of a row */
5493  SCIP_ROW* row, /**< LP row */
5494  BMS_BLKMEM* blkmem, /**< block memory */
5495  SCIP_SET* set, /**< global SCIP settings */
5496  SCIP_STAT* stat, /**< problem statistics */
5497  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5498  SCIP_LP* lp, /**< current LP data */
5499  SCIP_Real constant /**< new constant value */
5500  )
5501 {
5502  assert(row != NULL);
5503  assert(row->lhs <= row->rhs);
5504  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5505  assert(stat != NULL);
5506  assert(lp != NULL);
5507  assert(!lp->diving || row->lppos == -1);
5508 
5509  if( !SCIPsetIsEQ(set, constant, row->constant) )
5510  {
5511  SCIP_Real oldconstant;
5512 
5513  if( row->validpsactivitydomchg == stat->domchgcount )
5514  {
5515  assert(row->pseudoactivity < SCIP_INVALID);
5516  row->pseudoactivity += constant - row->constant;
5517  }
5518  if( row->validactivitybdsdomchg == stat->domchgcount )
5519  {
5520  assert(row->minactivity < SCIP_INVALID);
5521  assert(row->maxactivity < SCIP_INVALID);
5522  row->minactivity += constant - row->constant;
5523  row->maxactivity += constant - row->constant;
5524  }
5525 
5526  if( !SCIPsetIsInfinity(set, -row->lhs) )
5527  {
5528  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5529  }
5530  if( !SCIPsetIsInfinity(set, row->rhs) )
5531  {
5532  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5533  }
5534 
5535  oldconstant = row->constant;
5536 
5537  row->constant = constant;
5538 
5539  /* issue row constant changed event */
5540  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5541  }
5542 
5543  return SCIP_OKAY;
5544 }
5545 
5546 /** add constant value to a row */
5548  SCIP_ROW* row, /**< LP row */
5549  BMS_BLKMEM* blkmem, /**< block memory */
5550  SCIP_SET* set, /**< global SCIP settings */
5551  SCIP_STAT* stat, /**< problem statistics */
5552  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5553  SCIP_LP* lp, /**< current LP data */
5554  SCIP_Real addval /**< constant value to add to the row */
5555  )
5556 {
5557  assert(row != NULL);
5558  assert(row->lhs <= row->rhs);
5559  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5560  assert(stat != NULL);
5561  assert(lp != NULL);
5562  assert(!lp->diving || row->lppos == -1);
5563 
5564  if( !SCIPsetIsZero(set, addval) )
5565  {
5566  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5567  }
5568 
5569  return SCIP_OKAY;
5570 }
5571 
5572 /** changes left hand side of LP row */
5574  SCIP_ROW* row, /**< LP row */
5575  BMS_BLKMEM* blkmem, /**< block memory */
5576  SCIP_SET* set, /**< global SCIP settings */
5577  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5578  SCIP_LP* lp, /**< current LP data */
5579  SCIP_Real lhs /**< new left hand side */
5580  )
5581 {
5582  assert(row != NULL);
5583  assert(lp != NULL);
5584 
5585  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5586  {
5587  SCIP_Real oldlhs;
5588 
5589  oldlhs = row->lhs;
5590 
5591  row->lhs = lhs;
5592  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5593 
5594  if( !lp->diving )
5595  {
5596  /* issue row side changed event */
5597  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5598  }
5599  }
5600 
5601  return SCIP_OKAY;
5602 }
5603 
5604 /** changes right hand side of LP row */
5606  SCIP_ROW* row, /**< LP row */
5607  BMS_BLKMEM* blkmem, /**< block memory */
5608  SCIP_SET* set, /**< global SCIP settings */
5609  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5610  SCIP_LP* lp, /**< current LP data */
5611  SCIP_Real rhs /**< new right hand side */
5612  )
5613 {
5614  assert(row != NULL);
5615  assert(lp != NULL);
5616 
5617  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5618  {
5619  SCIP_Real oldrhs;
5620 
5621  oldrhs = row->rhs;
5622 
5623  row->rhs = rhs;
5624  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5625 
5626  if( !lp->diving )
5627  {
5628  /* issue row side changed event */
5629  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5630  }
5631  }
5632 
5633  return SCIP_OKAY;
5634 }
5635 
5636 /** changes the local flag of LP row */
5638  SCIP_ROW* row, /**< LP row */
5639  SCIP_Bool local /**< new value for local flag */
5640  )
5641 {
5642  assert(row != NULL);
5643 
5644  row->local = local;
5645 
5646  return SCIP_OKAY;
5647 }
5648 
5649 /** additional scalars that are tried in integrality scaling */
5650 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5651 static const int nscalars = 9;
5652 
5653 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5655  SCIP_ROW* row, /**< LP row */
5656  SCIP_SET* set, /**< global SCIP settings */
5657  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5658  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5659  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5660  SCIP_Real maxscale, /**< maximal allowed scalar */
5661  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5662  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5663  SCIP_Bool* success /**< stores whether returned value is valid */
5664  )
5665 {
5666 #ifndef NDEBUG
5667  SCIP_COL* col;
5668 #endif
5669  SCIP_Longint gcd;
5670  SCIP_Longint scm;
5671  SCIP_Longint nominator;
5672  SCIP_Longint denominator;
5673  SCIP_Real val;
5674  SCIP_Real absval;
5675  SCIP_Real minval;
5676  SCIP_Real scaleval;
5677  SCIP_Real twomultval;
5678  SCIP_Bool scalable;
5679  SCIP_Bool twomult;
5680  SCIP_Bool rational;
5681  int c;
5682  int s;
5683 
5684  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5685  assert(row != NULL);
5686  assert(row->len == 0 || row->cols != NULL);
5687  assert(row->len == 0 || row->cols_index != NULL);
5688  assert(row->len == 0 || row->vals != NULL);
5689  assert(maxdnom >= 1);
5690  assert(mindelta < 0.0);
5691  assert(maxdelta > 0.0);
5692  assert(success != NULL);
5693 
5694  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5695  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5696 
5697  if( intscalar != NULL )
5698  *intscalar = SCIP_INVALID;
5699  *success = FALSE;
5700 
5701  /* get minimal absolute non-zero value */
5702  minval = SCIP_REAL_MAX;
5703  for( c = 0; c < row->len; ++c )
5704  {
5705 #ifndef NDEBUG
5706  col = row->cols[c];
5707  assert(col != NULL);
5708  assert(col->var != NULL);
5709  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5710  assert(SCIPvarGetCol(col->var) == col);
5711 #endif
5712  val = row->vals[c];
5713  assert(!SCIPsetIsZero(set, val));
5714 
5715  if( val < mindelta || val > maxdelta )
5716  {
5717  absval = REALABS(val);
5718  minval = MIN(minval, absval);
5719  }
5720  }
5721  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5722  {
5723  /* all coefficients are zero (inside tolerances) */
5724  if( intscalar != NULL )
5725  *intscalar = 1.0;
5726  *success = TRUE;
5727  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5728 
5729  return SCIP_OKAY;
5730  }
5731  assert(minval > MIN(-mindelta, maxdelta));
5732  assert(SCIPsetIsPositive(set, minval));
5733  assert(!SCIPsetIsInfinity(set, minval));
5734 
5735  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5736  * and a power of 2
5737  */
5738  scaleval = 1.0/minval;
5739  scalable = (scaleval <= maxscale);
5740  for( c = 0; c < row->len && scalable; ++c )
5741  {
5742  /* don't look at continuous variables, if we don't have to */
5743  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5744  continue;
5745 
5746  /* check, if the coefficient can be scaled with a simple scalar */
5747  val = row->vals[c];
5748  absval = REALABS(val);
5749  while( scaleval <= maxscale
5750  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5751  {
5752  for( s = 0; s < nscalars; ++s )
5753  {
5754  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5755  {
5756  scaleval *= scalars[s];
5757  break;
5758  }
5759  }
5760  if( s >= nscalars )
5761  scaleval *= 2.0;
5762  }
5763  scalable = (scaleval <= maxscale);
5764  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5765  }
5766  if( scalable )
5767  {
5768  /* make row coefficients integral by dividing them by the smallest coefficient
5769  * (and multiplying them with a power of 2)
5770  */
5771  assert(scaleval <= maxscale);
5772  if( intscalar != NULL )
5773  *intscalar = scaleval;
5774  *success = TRUE;
5775  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5776 
5777  return SCIP_OKAY;
5778  }
5779 
5780  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5781  twomultval = 1.0;
5782  twomult = (twomultval <= maxscale);
5783  for( c = 0; c < row->len && twomult; ++c )
5784  {
5785  /* don't look at continuous variables, if we don't have to */
5786  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5787  continue;
5788 
5789  /* check, if the coefficient can be scaled with a simple scalar */
5790  val = row->vals[c];
5791  absval = REALABS(val);
5792  while( twomultval <= maxscale
5793  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5794  {
5795  for( s = 0; s < nscalars; ++s )
5796  {
5797  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5798  {
5799  twomultval *= scalars[s];
5800  break;
5801  }
5802  }
5803  if( s >= nscalars )
5804  twomultval *= 2.0;
5805  }
5806  twomult = (twomultval <= maxscale);
5807  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5808  val, twomultval, val*twomultval, twomult);
5809  }
5810  if( twomult )
5811  {
5812  /* make row coefficients integral by multiplying them with a power of 2 */
5813  assert(twomultval <= maxscale);
5814  if( intscalar != NULL )
5815  *intscalar = twomultval;
5816  *success = TRUE;
5817  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5818 
5819  return SCIP_OKAY;
5820  }
5821 
5822  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5823  * and the smallest common multiple of the denominators
5824  */
5825  gcd = 1;
5826  scm = 1;
5827  rational = (maxdnom > 1);
5828 
5829  /* first coefficient (to initialize gcd) */
5830  for( c = 0; c < row->len && rational; ++c )
5831  {
5832  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5833  {
5834  val = row->vals[c];
5835  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5836  if( rational && nominator != 0 )
5837  {
5838  assert(denominator > 0);
5839  gcd = ABS(nominator);
5840  scm = denominator;
5841  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5842  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5843  val, nominator, denominator, gcd, scm, rational);
5844  break;
5845  }
5846  }
5847  }
5848 
5849  /* remaining coefficients */
5850  for( ++c; c < row->len && rational; ++c )
5851  {
5852  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5853  {
5854  val = row->vals[c];
5855  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5856  if( rational && nominator != 0 )
5857  {
5858  assert(denominator > 0);
5859  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5860  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5861  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5862  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5863  val, nominator, denominator, gcd, scm, rational);
5864  }
5865  }
5866  }
5867 
5868  if( rational )
5869  {
5870  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5871  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5872  if( intscalar != NULL )
5873  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5874  *success = TRUE;
5875  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5876  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5877  }
5878  else
5879  {
5880  assert(!(*success));
5881  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5882  }
5883 
5884  return SCIP_OKAY;
5885 }
5886 
5887 /** tries to scale row, s.t. all coefficients become integral */
5889  SCIP_ROW* row, /**< LP row */
5890  BMS_BLKMEM* blkmem, /**< block memory */
5891  SCIP_SET* set, /**< global SCIP settings */
5892  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5893  SCIP_STAT* stat, /**< problem statistics */
5894  SCIP_LP* lp, /**< current LP data */
5895  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5896  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5897  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5898  SCIP_Real maxscale, /**< maximal value to scale row with */
5899  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5900  SCIP_Bool* success /**< stores whether row could be made rational */
5901  )
5902 {
5903  SCIP_Real intscalar;
5904 
5905  assert(success != NULL);
5906 
5907  /* calculate scalar to make coefficients integral */
5908  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5909  &intscalar, success) );
5910 
5911  if( *success )
5912  {
5913  /* scale the row */
5914  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
5915  }
5916 
5917  return SCIP_OKAY;
5918 }
5919 
5920 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
5921  * higher ones
5922  */
5924  SCIP_ROW* row /**< row to be sorted */
5925  )
5926 {
5927  assert(row != NULL);
5928 
5929  /* sort LP columns */
5930  rowSortLP(row);
5931 
5932  /* sort non-LP columns */
5933  rowSortNonLP(row);
5934 
5935 #ifdef SCIP_MORE_DEBUG
5936  /* check the sorting */
5937  {
5938  int c;
5939  if( !row->delaysort )
5940  {
5941  for( c = 1; c < row->nlpcols; ++c )
5942  assert(row->cols[c]->index >= row->cols[c-1]->index);
5943  for( c = row->nlpcols + 1; c < row->len; ++c )
5944  assert(row->cols[c]->index >= row->cols[c-1]->index);
5945  }
5946  }
5947 #endif
5948 }
5949 
5950 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
5951  * zero entries from row
5952  * the row must not be linked to the columns; otherwise, we would need to update the columns as
5953  * well, which is too expensive
5954  */
5955 static
5957  SCIP_ROW* row, /**< row to be sorted */
5958  SCIP_SET* set /**< global SCIP settings */
5959  )
5960 {
5961  assert(row != NULL);
5962  assert(!row->delaysort);
5963  assert(row->nunlinked == row->len);
5964  assert(row->nlpcols == 0);
5965 
5966  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
5967 
5968  /* do nothing on empty rows; if row is sorted, nothing has to be done */
5969  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
5970  {
5971  SCIP_COL** cols;
5972  int* cols_index;
5973  SCIP_Real* vals;
5974  int s;
5975  int t;
5976 
5977  /* make sure, the row is sorted */
5978  SCIProwSort(row);
5979  assert(row->lpcolssorted);
5980  assert(row->nonlpcolssorted);
5981 
5982  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
5983  cols = row->cols;
5984  cols_index = row->cols_index;
5985  vals = row->vals;
5986  assert(cols != NULL);
5987  assert(cols_index != NULL);
5988  assert(vals != NULL);
5989 
5990  t = 0;
5991  row->integral = TRUE;
5992  assert(!SCIPsetIsZero(set, vals[0]));
5993  assert(row->linkpos[0] == -1);
5994 
5995  for( s = 1; s < row->len; ++s )
5996  {
5997  assert(!SCIPsetIsZero(set, vals[s]));
5998  assert(row->linkpos[s] == -1);
5999 
6000  if( cols[s] == cols[t] )
6001  {
6002  /* merge entries with equal column */
6003  vals[t] += vals[s];
6004  }
6005  else
6006  {
6007  /* go to the next entry, overwriting current entry if coefficient is zero */
6008  if( !SCIPsetIsZero(set, vals[t]) )
6009  {
6010  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6011  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6012 
6013  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6014  t++;
6015  }
6016  cols[t] = cols[s];
6017  cols_index[t] = cols_index[s];
6018  vals[t] = vals[s];
6019  }
6020  }
6021  if( !SCIPsetIsZero(set, vals[t]) )
6022  {
6023  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6024  t++;
6025  }
6026  assert(s == row->len);
6027  assert(t <= row->len);
6028 
6029  row->len = t;
6030  row->nunlinked = t;
6031 
6032  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6033  if( t < s )
6034  rowCalcNorms(row, set);
6035  }
6036 
6037 #ifndef NDEBUG
6038  /* check for double entries */
6039  {
6040  int i;
6041  int j;
6042 
6043  for( i = 0; i < row->len; ++i )
6044  {
6045  assert(row->cols[i] != NULL);
6046  assert(row->cols[i]->index == row->cols_index[i]);
6047  for( j = i+1; j < row->len; ++j )
6048  assert(row->cols[i] != row->cols[j]);
6049  }
6050  }
6051 #endif
6052 }
6053 
6054 /** enables delaying of row sorting */
6056  SCIP_ROW* row /**< LP row */
6057  )
6058 {
6059  assert(row != NULL);
6060  assert(!row->delaysort);
6061 
6062  row->delaysort = TRUE;
6063 }
6064 
6065 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6067  SCIP_ROW* row, /**< LP row */
6068  SCIP_SET* set /**< global SCIP settings */
6069  )
6070 {
6071  assert(row != NULL);
6072  assert(row->delaysort);
6073 
6074  row->delaysort = FALSE;
6075  rowMerge(row, set);
6076 }
6077 
6078 /** recalculates the current activity of a row */
6080  SCIP_ROW* row, /**< LP row */
6081  SCIP_STAT* stat /**< problem statistics */
6082  )
6083 {
6084  SCIP_COL* col;
6085  int c;
6086 
6087  assert(row != NULL);
6088  assert(stat != NULL);
6089 
6090  row->activity = row->constant;
6091  for( c = 0; c < row->nlpcols; ++c )
6092  {
6093  col = row->cols[c];
6094  assert(col != NULL);
6095  assert(col->primsol < SCIP_INVALID);
6096  assert(col->lppos >= 0);
6097  assert(row->linkpos[c] >= 0);
6098  row->activity += row->vals[c] * col->primsol;
6099  }
6100 
6101  if( row->nunlinked > 0 )
6102  {
6103  for( c = row->nlpcols; c < row->len; ++c )
6104  {
6105  col = row->cols[c];
6106  assert(col != NULL);
6107  assert(col->lppos >= 0 || col->primsol == 0.0);
6108  assert(col->lppos == -1 || row->linkpos[c] == -1);
6109  if( col->lppos >= 0 )
6110  row->activity += row->vals[c] * col->primsol;
6111  }
6112  }
6113 #ifndef NDEBUG
6114  else
6115  {
6116  for( c = row->nlpcols; c < row->len; ++c )
6117  {
6118  col = row->cols[c];
6119  assert(col != NULL);
6120  assert(col->primsol == 0.0);
6121  assert(col->lppos == -1);
6122  assert(row->linkpos[c] >= 0);
6123  }
6124  }
6125 #endif
6126 
6127  row->validactivitylp = stat->lpcount;
6128 }
6129 
6130 /** returns the activity of a row in the current LP solution */
6132  SCIP_ROW* row, /**< LP row */
6133  SCIP_SET* set, /**< global SCIP settings */
6134  SCIP_STAT* stat, /**< problem statistics */
6135  SCIP_LP* lp /**< current LP data */
6136  )
6137 {
6138  SCIP_Real inf;
6139  SCIP_Real activity;
6140 
6141  assert(row != NULL);
6142  assert(stat != NULL);
6143  assert(lp != NULL);
6144  assert(row->validactivitylp <= stat->lpcount);
6145  assert(lp->validsollp == stat->lpcount);
6146 
6147  if( row->validactivitylp != stat->lpcount )
6148  SCIProwRecalcLPActivity(row, stat);
6149  assert(row->validactivitylp == stat->lpcount);
6150  assert(row->activity < SCIP_INVALID);
6151 
6152  activity = row->activity;
6153  inf = SCIPsetInfinity(set);
6154  activity = MAX(activity, -inf);
6155  activity = MIN(activity, +inf);
6156 
6157  return activity;
6158 }
6159 
6160 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6162  SCIP_ROW* row, /**< LP row */
6163  SCIP_SET* set, /**< global SCIP settings */
6164  SCIP_STAT* stat, /**< problem statistics */
6165  SCIP_LP* lp /**< current LP data */
6166  )
6167 {
6168  SCIP_Real activity;
6169 
6170  assert(row != NULL);
6171 
6172  activity = SCIProwGetLPActivity(row, set, stat, lp);
6173 
6174  return MIN(row->rhs - activity, activity - row->lhs);
6175 }
6176 
6177 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6178  *
6179  * @todo Implement calculation of activities similar to LPs.
6180  */
6182  SCIP_ROW* row, /**< LP row */
6183  SCIP_SET* set, /**< global SCIP settings */
6184  SCIP_STAT* stat /**< problem statistics */
6185  )
6186 {
6187  SCIP_Real inf;
6188  SCIP_Real activity;
6189  SCIP_COL* col;
6190  int c;
6191 
6192  assert( row != NULL );
6193  assert( stat != NULL );
6194 
6195  activity = row->constant;
6196  for (c = 0; c < row->nlpcols; ++c)
6197  {
6198  col = row->cols[c];
6199  assert( col != NULL );
6200  assert( col->lppos >= 0 );
6201  assert( col->var != NULL );
6202  assert( row->linkpos[c] >= 0 );
6203  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6204  }
6205 
6206  if ( row->nunlinked > 0 )
6207  {
6208  for (c = row->nlpcols; c < row->len; ++c)
6209  {
6210  col = row->cols[c];
6211  assert( col != NULL );
6212  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6213  if ( col->lppos >= 0 )
6214  {
6215  assert( col->var != NULL );
6216  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6217  }
6218  }
6219  }
6220 #ifndef NDEBUG
6221  else
6222  {
6223  for (c = row->nlpcols; c < row->len; ++c)
6224  {
6225  col = row->cols[c];
6226  assert( col != NULL );
6227  assert( col->lppos == -1 );
6228  assert( row->linkpos[c] >= 0 );
6229  }
6230  }
6231 #endif
6232  inf = SCIPsetInfinity(set);
6233  activity = MAX(activity, -inf);
6234  activity = MIN(activity, +inf);
6235 
6236  return MIN(row->rhs - activity, activity - row->lhs);
6237 }
6238 
6239 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6240  *
6241  * @todo Implement calculation of activities similar to LPs.
6242  */
6244  SCIP_ROW* row, /**< LP row */
6245  SCIP_SET* set, /**< global SCIP settings */
6246  SCIP_STAT* stat /**< problem statistics */
6247  )
6248 {
6249  SCIP_Real inf;
6250  SCIP_Real activity;
6251  SCIP_COL* col;
6252  int c;
6253 
6254  assert( row != NULL );
6255  assert( stat != NULL );
6256 
6257  activity = row->constant;
6258  for (c = 0; c < row->nlpcols; ++c)
6259  {
6260  col = row->cols[c];
6261  assert( col != NULL );
6262  assert( col->lppos >= 0 );
6263  assert( col->var != NULL );
6264  assert( row->linkpos[c] >= 0 );
6265  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6266  }
6267 
6268  if ( row->nunlinked > 0 )
6269  {
6270  for (c = row->nlpcols; c < row->len; ++c)
6271  {
6272  col = row->cols[c];
6273  assert( col != NULL );
6274  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6275  if ( col->lppos >= 0 )
6276  {
6277  assert( col->var != NULL );
6278  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6279  }
6280  }
6281  }
6282 #ifndef NDEBUG
6283  else
6284  {
6285  for (c = row->nlpcols; c < row->len; ++c)
6286  {
6287  col = row->cols[c];
6288  assert( col != NULL );
6289  assert( col->lppos == -1 );
6290  assert( row->linkpos[c] >= 0 );
6291  }
6292  }
6293 #endif
6294  inf = SCIPsetInfinity(set);
6295  activity = MAX(activity, -inf);
6296  activity = MIN(activity, +inf);
6297 
6298  return MIN(row->rhs - activity, activity - row->lhs);
6299 }
6300 
6301 /** calculates the current pseudo activity of a row */
6303  SCIP_ROW* row, /**< row data */
6304  SCIP_STAT* stat /**< problem statistics */
6305  )
6306 {
6307  SCIP_COL* col;
6308  int i;
6309 
6310  assert(row != NULL);
6311  assert(stat != NULL);
6312 
6313  row->pseudoactivity = row->constant;
6314  for( i = 0; i < row->len; ++i )
6315  {
6316  col = row->cols[i];
6317  assert(col != NULL);
6318  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6319  assert(col->var != NULL);
6320  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6321 
6322  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6323  }
6324  row->validpsactivitydomchg = stat->domchgcount;
6325  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6326 }
6327 
6328 /** returns the pseudo activity of a row in the current pseudo solution */
6330  SCIP_ROW* row, /**< LP row */
6331  SCIP_SET* set, /**< global SCIP settings */
6332  SCIP_STAT* stat /**< problem statistics */
6333  )
6334 {
6335  SCIP_Real inf;
6336  SCIP_Real activity;
6337 
6338  assert(row != NULL);
6339  assert(stat != NULL);
6340  assert(row->validpsactivitydomchg <= stat->domchgcount);
6341 
6342  /* check, if pseudo activity has to be calculated */
6343  if( row->validpsactivitydomchg != stat->domchgcount )
6344  SCIProwRecalcPseudoActivity(row, stat);
6345  assert(row->validpsactivitydomchg == stat->domchgcount);
6346  assert(row->pseudoactivity < SCIP_INVALID);
6347 
6348  activity = row->pseudoactivity;
6349  inf = SCIPsetInfinity(set);
6350  activity = MAX(activity, -inf);
6351  activity = MIN(activity, +inf);
6352 
6353  return activity;
6354 }
6355 
6356 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6358  SCIP_ROW* row, /**< LP row */
6359  SCIP_SET* set, /**< global SCIP settings */
6360  SCIP_STAT* stat /**< problem statistics */
6361  )
6362 {
6363  SCIP_Real pseudoactivity;
6364 
6365  assert(row != NULL);
6366 
6367  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6368 
6369  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6370 }
6371 
6372 /** returns the activity of a row for a given solution */
6374  SCIP_ROW* row, /**< LP row */
6375  SCIP_SET* set, /**< global SCIP settings */
6376  SCIP_STAT* stat, /**< problem statistics data */
6377  SCIP_SOL* sol /**< primal CIP solution */
6378  )
6379 {
6380  SCIP_COL* col;
6381  SCIP_Real inf;
6382  SCIP_Real activity;
6383  SCIP_Real solval;
6384  int i;
6385 
6386  assert(row != NULL);
6387 
6388  activity = row->constant;
6389  for( i = 0; i < row->len; ++i )
6390  {
6391  col = row->cols[i];
6392  assert(col != NULL);
6393  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6394  solval = SCIPsolGetVal(sol, set, stat, col->var);
6395  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6396  {
6397  if( SCIPsetIsInfinity(set, -row->lhs) )
6398  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6399  else if( SCIPsetIsInfinity(set, row->rhs) )
6400  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6401  else
6402  solval = (col->lb + col->ub)/2.0;
6403  }
6404  activity += row->vals[i] * solval;
6405  }
6406 
6407  inf = SCIPsetInfinity(set);
6408  activity = MAX(activity, -inf);
6409  activity = MIN(activity, +inf);
6410 
6411  return activity;
6412 }
6413 
6414 /** returns the feasibility of a row for the given solution */
6416  SCIP_ROW* row, /**< LP row */
6417  SCIP_SET* set, /**< global SCIP settings */
6418  SCIP_STAT* stat, /**< problem statistics data */
6419  SCIP_SOL* sol /**< primal CIP solution */
6420  )
6421 {
6422  SCIP_Real activity;
6423 
6424  assert(row != NULL);
6425 
6426  activity = SCIProwGetSolActivity(row, set, stat, sol);
6427 
6428  return MIN(row->rhs - activity, activity - row->lhs);
6429 }
6430 
6431 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6432 static
6434  SCIP_ROW* row, /**< row data */
6435  SCIP_SET* set, /**< global SCIP settings */
6436  SCIP_STAT* stat /**< problem statistics data */
6437  )
6438 {
6439  SCIP_COL* col;
6440  SCIP_Real val;
6441  SCIP_Bool mininfinite;
6442  SCIP_Bool maxinfinite;
6443  int i;
6444 
6445  assert(row != NULL);
6446  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6447  assert(stat != NULL);
6448 
6449  /* calculate activity bounds */
6450  mininfinite = FALSE;
6451  maxinfinite = FALSE;
6452  row->minactivity = row->constant;
6453  row->maxactivity = row->constant;
6454  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6455  {
6456  col = row->cols[i];
6457  assert(col != NULL);
6458  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6459  val = row->vals[i];
6460  if( val >= 0.0 )
6461  {
6462  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6463  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6464  if( !mininfinite )
6465  row->minactivity += val * col->lb;
6466  if( !maxinfinite )
6467  row->maxactivity += val * col->ub;
6468  }
6469  else
6470  {
6471  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6472  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6473  if( !mininfinite )
6474  row->minactivity += val * col->ub;
6475  if( !maxinfinite )
6476  row->maxactivity += val * col->lb;
6477  }
6478  }
6479 
6480  if( mininfinite )
6481  row->minactivity = -SCIPsetInfinity(set);
6482  if( maxinfinite )
6483  row->maxactivity = SCIPsetInfinity(set);
6484  row->validactivitybdsdomchg = stat->domchgcount;
6485 
6486 #ifndef NDEBUG
6487  {
6488  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6489 
6490  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6491  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6492  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6493  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6494  * tolerance as a proxy to account for the accumulation effect
6495  */
6496  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6497  || EPSISINT(row->minactivity - row->constant, inttol));
6498  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6499  || EPSISINT(row->maxactivity - row->constant, inttol));
6500  }
6501 #endif
6502 }
6503 
6504 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6506  SCIP_ROW* row, /**< LP row */
6507  SCIP_SET* set, /**< global SCIP settings */
6508  SCIP_STAT* stat /**< problem statistics data */
6509  )
6510 {
6511  assert(row != NULL);
6512  assert(stat != NULL);
6513  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6514 
6515  /* check, if activity bounds has to be calculated */
6516  if( row->validactivitybdsdomchg != stat->domchgcount )
6517  rowCalcActivityBounds(row, set, stat);
6518  assert(row->validactivitybdsdomchg == stat->domchgcount);
6519  assert(row->minactivity < SCIP_INVALID);
6520  assert(row->maxactivity < SCIP_INVALID);
6521 
6522  return row->minactivity;
6523 }
6524 
6525 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6527  SCIP_ROW* row, /**< LP row */
6528  SCIP_SET* set, /**< global SCIP settings */
6529  SCIP_STAT* stat /**< problem statistics data */
6530  )
6531 {
6532  assert(row != NULL);
6533  assert(stat != NULL);
6534  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6535 
6536  /* check, if activity bounds has to be calculated */
6537  if( row->validactivitybdsdomchg != stat->domchgcount )
6538  rowCalcActivityBounds(row, set, stat);
6539  assert(row->validactivitybdsdomchg == stat->domchgcount);
6540  assert(row->minactivity < SCIP_INVALID);
6541  assert(row->maxactivity < SCIP_INVALID);
6542 
6543  return row->maxactivity;
6544 }
6545 
6546 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6548  SCIP_ROW* row, /**< LP row */
6549  SCIP_SET* set, /**< global SCIP settings */
6550  SCIP_STAT* stat /**< problem statistics data */
6551  )
6552 {
6553  assert(row != NULL);
6554 
6555  if( row->modifiable )
6556  return FALSE;
6557  if( !SCIPsetIsInfinity(set, -row->lhs) )
6558  {
6559  SCIP_Real minactivity;
6560 
6561  minactivity = SCIProwGetMinActivity(row, set, stat);
6562  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6563  return FALSE;
6564  }
6565  if( !SCIPsetIsInfinity(set, row->rhs) )
6566  {
6567  SCIP_Real maxactivity;
6568 
6569  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6570  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6571  return FALSE;
6572  }
6573 
6574  return TRUE;
6575 }
6576 
6577 /** gets maximal absolute value of row vector coefficients */
6579  SCIP_ROW* row, /**< LP row */
6580  SCIP_SET* set /**< global SCIP settings */
6581  )
6582 {
6583  assert(row != NULL);
6584 
6585  if( row->nummaxval == 0 )
6586  rowCalcIdxsAndVals(row, set);
6587  assert(row->nummaxval > 0);
6588  assert(row->maxval >= 0.0 || row->len == 0);
6589 
6590  return row->maxval;
6591 }
6592 
6593 /** gets minimal absolute value of row vector's non-zero coefficients */
6595  SCIP_ROW* row, /**< LP row */
6596  SCIP_SET* set /**< global SCIP settings */
6597  )
6598 {
6599  assert(row != NULL);
6600 
6601  if( row->numminval == 0 )
6602  rowCalcIdxsAndVals(row, set);
6603  assert(row->numminval > 0);
6604  assert(row->minval >= 0.0 || row->len == 0);
6605 
6606  return row->minval;
6607 }
6608 
6609 /** gets maximal column index of row entries */
6611  SCIP_ROW* row, /**< LP row */
6612  SCIP_SET* set /**< global SCIP settings */
6613  )
6614 {
6615  assert(row != NULL);
6616 
6617  if( row->validminmaxidx == 0 )
6618  rowCalcIdxsAndVals(row, set);
6619  assert(row->maxidx >= 0 || row->len == 0);
6620  assert(row->validminmaxidx);
6621 
6622  return row->maxidx;
6623 }
6624 
6625 /** gets minimal column index of row entries */
6627  SCIP_ROW* row, /**< LP row */
6628  SCIP_SET* set /**< global SCIP settings */
6629  )
6630 {
6631  assert(row != NULL);
6632 
6633  if( row->validminmaxidx == 0 )
6634  rowCalcIdxsAndVals(row, set);
6635  assert(row->minidx >= 0 || row->len == 0);
6636  assert(row->validminmaxidx);
6637 
6638  return row->minidx;
6639 }
6640 
6641 /** gets number of integral columns in row */
6643  SCIP_ROW* row, /**< LP row */
6644  SCIP_SET* set /**< global SCIP settings */
6645  )
6646 {
6647  assert(row != NULL);
6648 
6649  if( row->numintcols == -1 )
6650  rowCalcIdxsAndVals(row, set);
6651 
6652  assert(row->numintcols <= row->len && row->numintcols >= 0);
6653 
6654  return row->numintcols;
6655 }
6656 
6657 /** returns row's cutoff distance in the direction of the given primal solution */
6659  SCIP_ROW* row, /**< LP row */
6660  SCIP_SET* set, /**< global SCIP settings */
6661  SCIP_STAT* stat, /**< problem statistics data */
6662  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6663  SCIP_LP* lp /**< current LP data */
6664  )
6665 {
6666  SCIP_Real solcutoffdist;
6667  int k;
6668 
6669  assert(sol != NULL);
6670 
6671  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6672  {
6673  SCIP_Real scale = 0.0;
6674 
6675  lp->validsoldirlp = stat->lpcount;
6676  lp->validsoldirsol = sol;
6677 
6679 
6680  for( k = 0; k < lp->ncols; ++k )
6681  {
6682  assert(lp->cols[k]->lppos == k);
6683  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6684  scale += SQR(lp->soldirection[k]);
6685  }
6686 
6687  if( scale > 0.0 )
6688  {
6689  scale = 1.0 / SQRT(scale);
6690 
6691  for( k = 0; k < lp->ncols; ++k )
6692  lp->soldirection[k] *= scale;
6693  }
6694  }
6695 
6696  solcutoffdist = 0.0;
6697  for( k = 0; k < row->nlpcols; ++k )
6698  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6699 
6700  for( k = row->nlpcols; k < row->len; ++k )
6701  {
6702  if( row->cols[k]->lppos >= 0 )
6703  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6704  }
6705 
6706  if( SCIPsetIsSumZero(set, solcutoffdist) )
6707  solcutoffdist = COPYSIGN(set->num_sumepsilon, solcutoffdist);
6708 
6709  solcutoffdist = SCIProwGetLPFeasibility(row, set, stat, lp) / solcutoffdist; /*lint !e795*/
6710 
6711  return solcutoffdist;
6712 }
6713 
6714 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6716  SCIP_ROW* row, /**< LP row */
6717  SCIP_SET* set, /**< global SCIP settings */
6718  SCIP_STAT* stat, /**< problem statistics data */
6719  SCIP_LP* lp /**< current LP data */
6720  )
6721 {
6722  SCIP_Real norm;
6723  SCIP_Real feasibility;
6724  SCIP_Real eps;
6725 
6726  assert(set != NULL);
6727 
6728  switch( set->sepa_efficacynorm )
6729  {
6730  case 'e':
6731  norm = SCIProwGetNorm(row);
6732  break;
6733  case 'm':
6734  norm = SCIProwGetMaxval(row, set);
6735  break;
6736  case 's':
6737  norm = SCIProwGetSumNorm(row);
6738  break;
6739  case 'd':
6740  norm = (row->len == 0 ? 0.0 : 1.0);
6741  break;
6742  default:
6743  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6744  SCIPABORT();
6745  norm = 0.0; /*lint !e527*/
6746  }
6747 
6748  eps = SCIPsetSumepsilon(set);
6749  norm = MAX(norm, eps);
6750  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6751 
6752  return -feasibility / norm;
6753 }
6754 
6755 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6757  SCIP_ROW* row, /**< LP row */
6758  SCIP_SET* set, /**< global SCIP settings */
6759  SCIP_STAT* stat, /**< problem statistics data */
6760  SCIP_LP* lp, /**< current LP data */
6761  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6762  )
6763 {
6764  SCIP_Real efficacy;
6765 
6766  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6767 
6768  return SCIPsetIsEfficacious(set, root, efficacy);
6769 }
6770 
6771 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6773  SCIP_ROW* row, /**< LP row */
6774  SCIP_SET* set, /**< global SCIP settings */
6775  SCIP_STAT* stat, /**< problem statistics data */
6776  SCIP_SOL* sol /**< primal CIP solution */
6777  )
6778 {
6779  SCIP_Real norm;
6780  SCIP_Real feasibility;
6781  SCIP_Real eps;
6782 
6783  assert(set != NULL);
6784 
6785  switch( set->sepa_efficacynorm )
6786  {
6787  case 'e':
6788  norm = SCIProwGetNorm(row);
6789  break;
6790  case 'm':
6791  norm = SCIProwGetMaxval(row, set);
6792  break;
6793  case 's':
6794  norm = SCIProwGetSumNorm(row);
6795  break;
6796  case 'd':
6797  norm = (row->len == 0 ? 0.0 : 1.0);
6798  break;
6799  default:
6800  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6801  SCIPABORT();
6802  norm = 0.0; /*lint !e527*/
6803  }
6804 
6805  eps = SCIPsetSumepsilon(set);
6806  norm = MAX(norm, eps);
6807  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6808 
6809  return -feasibility / norm;
6810 }
6811 
6812 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6813  * efficacy
6814  */
6816  SCIP_ROW* row, /**< LP row */
6817  SCIP_SET* set, /**< global SCIP settings */
6818  SCIP_STAT* stat, /**< problem statistics data */
6819  SCIP_SOL* sol, /**< primal CIP solution */
6820  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6821  )
6822 {
6823  SCIP_Real efficacy;
6824 
6825  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6826 
6827  return SCIPsetIsEfficacious(set, root, efficacy);
6828 }
6829 
6830 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6832  SCIP_ROW* row, /**< LP row */
6833  SCIP_SET* set, /**< global SCIP settings */
6834  SCIP_STAT* stat /**< problem statistics data */
6835  )
6836 {
6837  SCIP_Real norm;
6838  SCIP_Real feasibility;
6839  SCIP_Real eps;
6840 
6841  assert(set != NULL);
6842 
6843  switch( set->sepa_efficacynorm )
6844  {
6845  case 'e':
6846  norm = SCIProwGetNorm(row);
6847  break;
6848  case 'm':
6849  norm = SCIProwGetMaxval(row, set);
6850  break;
6851  case 's':
6852  norm = SCIProwGetSumNorm(row);
6853  break;
6854  case 'd':
6855  norm = (row->len == 0 ? 0.0 : 1.0);
6856  break;
6857  default:
6858  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6859  SCIPABORT();
6860  norm = 0.0; /*lint !e527*/
6861  }
6862 
6863  eps = SCIPsetSumepsilon(set);
6864  norm = MAX(norm, eps);
6865  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6866 
6867  return -feasibility / norm;
6868 }
6869 
6870 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6872  SCIP_ROW* row, /**< LP row */
6873  SCIP_SET* set, /**< global SCIP settings */
6874  SCIP_STAT* stat /**< problem statistics data */
6875  )
6876 {
6877  SCIP_Real norm;
6878  SCIP_Real feasibility;
6879  SCIP_Real eps;
6880 
6881  assert(set != NULL);
6882 
6883  switch( set->sepa_efficacynorm )
6884  {
6885  case 'e':
6886  norm = SCIProwGetNorm(row);
6887  break;
6888  case 'm':
6889  norm = SCIProwGetMaxval(row, set);
6890  break;
6891  case 's':
6892  norm = SCIProwGetSumNorm(row);
6893  break;
6894  case 'd':
6895  norm = (row->len == 0 ? 0.0 : 1.0);
6896  break;
6897  default:
6898  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6899  SCIPABORT();
6900  norm = 0.0; /*lint !e527*/
6901  }
6902 
6903  eps = SCIPsetSumepsilon(set);
6904  norm = MAX(norm, eps);
6905  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6906 
6907  return -feasibility / norm;
6908 }
6909 
6910 /** returns the scalar product of the coefficient vectors of the two given rows
6911  *
6912  * @note the scalar product is computed w.r.t. the current LP columns only
6913  * @todo also consider non-LP columns for the computation?
6914  */
6916  SCIP_ROW* row1, /**< first LP row */
6917  SCIP_ROW* row2 /**< second LP row */
6918  )
6919 {
6920  SCIP_Real scalarprod;
6921  int* row1colsidx;
6922  int* row2colsidx;
6923  int i1;
6924  int i2;
6925 
6926  assert(row1 != NULL);
6927  assert(row2 != NULL);
6928 
6929  /* Sort the column indices of both rows.
6930  *
6931  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
6932  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
6933  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
6934  * for both or one of the non-LP columns for both.
6935  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
6936  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
6937  * columns can be added later and remain unlinked while all previously added columns might already be linked.
6938  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
6939  *
6940  * We distinguish the following cases:
6941  *
6942  * 1) both rows have no unlinked columns
6943  * -> we just check the LP partitions
6944  *
6945  * 2) exactly one row is completely unlinked, the other one is completely linked
6946  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
6947  * (thus all common LP columns are regarded)
6948  *
6949  * 3) we have unlinked and LP columns in both rows
6950  * -> we need to compare four partitions at once
6951  *
6952  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
6953  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
6954  * other row
6955  *
6956  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
6957  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
6958  *
6959  * 5) both rows are completely unlinked
6960  * -> we need to compare two partitions: both complete rows
6961  */
6962  SCIProwSort(row1);
6963  assert(row1->lpcolssorted);
6964  assert(row1->nonlpcolssorted);
6965  SCIProwSort(row2);
6966  assert(row2->lpcolssorted);
6967  assert(row2->nonlpcolssorted);
6968 
6969  assert(row1->nunlinked <= row1->len - row1->nlpcols);
6970  assert(row2->nunlinked <= row2->len - row2->nlpcols);
6971 
6972  row1colsidx = row1->cols_index;
6973  row2colsidx = row2->cols_index;
6974 
6975 #ifndef NDEBUG
6976  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
6977  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
6978  {
6979  i1 = 0;
6980  i2 = row2->nlpcols;
6981  while( i1 < row1->nlpcols && i2 < row2->len )
6982  {
6983  assert(row1->cols[i1] != row2->cols[i2]);
6984  if( row1->cols[i1]->index < row2->cols[i2]->index )
6985  ++i1;
6986  else
6987  {
6988  assert(row1->cols[i1]->index > row2->cols[i2]->index);
6989  ++i2;
6990  }
6991  }
6992  assert(i1 == row1->nlpcols || i2 == row2->len);
6993 
6994  i1 = row1->nlpcols;
6995  i2 = 0;
6996  while( i1 < row1->len && i2 < row2->nlpcols )
6997  {
6998  assert(row1->cols[i1] != row2->cols[i2]);
6999  if( row1->cols[i1]->index < row2->cols[i2]->index )
7000  ++i1;
7001  else
7002  {
7003  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7004  ++i2;
7005  }
7006  }
7007  assert(i1 == row1->len || i2 == row2->nlpcols);
7008  }
7009 #endif
7010 
7011  /* The "easy" cases 1) and 2) */
7012  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7013  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7014  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7015  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7016  {
7017  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7018  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7019 
7020  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7021  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7022  */
7023  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7024  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7025  scalarprod = 0.0;
7026 
7027  /* calculate the scalar product */
7028  while( i1 >= 0 && i2 >= 0 )
7029  {
7030  assert(row1->cols[i1]->index == row1colsidx[i1]);
7031  assert(row2->cols[i2]->index == row2colsidx[i2]);
7032  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7033  if( row1colsidx[i1] < row2colsidx[i2] )
7034  --i2;
7035  else if( row1colsidx[i1] > row2colsidx[i2] )
7036  --i1;
7037  else
7038  {
7039  scalarprod += row1->vals[i1] * row2->vals[i2];
7040  --i1;
7041  --i2;
7042  }
7043  }
7044  }
7045  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7046  else
7047  {
7048  SCIP_Bool lpcols;
7049  int ilp1;
7050  int inlp1;
7051  int ilp2;
7052  int inlp2;
7053  int end1;
7054  int end2;
7055 
7056  scalarprod = 0;
7057  ilp1 = 0;
7058  ilp2 = 0;
7059 
7060  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7061  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7062  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7063 
7064  /* handle the case of four partitions (case 3) until one partition is finished;
7065  * cases 4a), 4b), and 5) will fail the while-condition
7066  */
7067  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7068  {
7069  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7070  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7071  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7072  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7073  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7074  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7075  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7076  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7077 
7078  /* rows have the same linked LP columns */
7079  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7080  {
7081  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7082  ++ilp1;
7083  ++ilp2;
7084  }
7085  /* LP column of row1 is the same as unlinked column of row2 */
7086  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7087  {
7088  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7089  ++ilp1;
7090  ++inlp2;
7091  }
7092  /* unlinked column of row1 is the same as LP column of row2 */
7093  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7094  {
7095  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7096  ++inlp1;
7097  ++ilp2;
7098  }
7099  /* two unlinked LP columns are the same */
7100  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7101  {
7102  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7103  ++inlp1;
7104  ++inlp2;
7105  }
7106  /* increase smallest counter */
7107  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7108  {
7109  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7110  {
7111  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7112  ++ilp1;
7113  else
7114  ++ilp2;
7115  }
7116  else
7117  {
7118  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7119  ++ilp1;
7120  else
7121  ++inlp2;
7122  }
7123  }
7124  else
7125  {
7126  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7127  {
7128  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7129  ++inlp1;
7130  else
7131  ++ilp2;
7132  }
7133  else
7134  {
7135  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7136  ++inlp1;
7137  else
7138  ++inlp2;
7139  }
7140  }
7141  }
7142 
7143  /* One partition was completely handled, we just have to handle the three remaining partitions:
7144  * the remaining partition of this row and the two partitions of the other row.
7145  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7146  */
7147  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7148  {
7149  int tmpilp;
7150  int tmpinlp;
7151 
7152  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7153 
7154  SCIPswapPointers((void**) &row1, (void**) &row2);
7155  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7156  tmpilp = ilp1;
7157  tmpinlp = inlp1;
7158  ilp1 = ilp2;
7159  inlp1 = inlp2;
7160  ilp2 = tmpilp;
7161  inlp2 = tmpinlp;
7162  }
7163 
7164  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7165  * -> this merges cases 4a) and 4b)
7166  */
7167  if( ilp1 == row1->nlpcols )
7168  {
7169  i1 = inlp1;
7170  end1 = row1->len;
7171  lpcols = FALSE;
7172  }
7173  else
7174  {
7175  assert(inlp1 == row1->len);
7176 
7177  i1 = ilp1;
7178  end1 = row1->nlpcols;
7179  lpcols = TRUE;
7180  }
7181 
7182  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7183  * case 5) will fail the while-condition
7184  */
7185  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7186  {
7187  assert(row1->cols[i1]->index == row1colsidx[i1]);
7188  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7189  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7190  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7191  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7192 
7193  /* current column in row 1 is the same as the current LP column in row 2 */
7194  if( row1colsidx[i1] == row2colsidx[ilp2] )
7195  {
7196  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7197  ++i1;
7198  ++ilp2;
7199  }
7200  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7201  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7202  {
7203  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7204  ++i1;
7205  ++inlp2;
7206  }
7207  /* increase smallest counter */
7208  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7209  {
7210  if( row1colsidx[i1] < row2colsidx[ilp2] )
7211  ++i1;
7212  else
7213  ++ilp2;
7214  }
7215  else
7216  {
7217  if( row1colsidx[i1] < row2colsidx[inlp2] )
7218  ++i1;
7219  else
7220  ++inlp2;
7221  }
7222  }
7223 
7224  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7225  * the two rows
7226  */
7227  if( i1 < end1 )
7228  {
7229  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7230  if( ilp2 == row2->nlpcols )
7231  {
7232  i2 = inlp2;
7233  end2 = row2->len;
7234  lpcols = FALSE;
7235  }
7236  else
7237  {
7238  assert(inlp2 == row2->len);
7239 
7240  i2 = ilp2;
7241  end2 = row2->nlpcols;
7242  }
7243 
7244  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7245  while( i1 < end1 && i2 < end2 )
7246  {
7247  assert(row1->cols[i1]->index == row1colsidx[i1]);
7248  assert(row2->cols[i2]->index == row2colsidx[i2]);
7249  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7250 
7251  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7252  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7253  {
7254  scalarprod += row1->vals[i1] * row2->vals[i2];
7255  ++i1;
7256  ++i2;
7257  }
7258  /* increase smallest counter */
7259  else if( row1colsidx[i1] < row2colsidx[i2] )
7260  ++i1;
7261  else
7262  ++i2;
7263  }
7264  }
7265  }
7266 
7267  return scalarprod;
7268 }
7269 
7270 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7271 static
7273  SCIP_ROW* row1, /**< first LP row */
7274  SCIP_ROW* row2 /**< second LP row */
7275  )
7276 {
7277  int prod;
7278  int* row1colsidx;
7279  int* row2colsidx;
7280  int i1;
7281  int i2;
7282 
7283  assert(row1 != NULL);
7284  assert(row2 != NULL);
7285 
7286  /* Sort the column indices of both rows.
7287  *
7288  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7289  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7290  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7291  * for both or one of the non-LP columns for both.
7292  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7293  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7294  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7295  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7296  *
7297  * We distinguish the following cases:
7298  *
7299  * 1) both rows have no unlinked columns
7300  * -> we just check the LP partitions
7301  *
7302  * 2) exactly one row is completely unlinked, the other one is completely linked
7303  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7304  * (thus all common LP columns are regarded)
7305  *
7306  * 3) we have unlinked and LP columns in both rows
7307  * -> we need to compare four partitions at once
7308  *
7309  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7310  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7311  * other row
7312  *
7313  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7314  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7315  *
7316  * 5) both rows are completely unlinked
7317  * -> we need to compare two partitions: both complete rows
7318  */
7319  SCIProwSort(row1);
7320  assert(row1->lpcolssorted);
7321  assert(row1->nonlpcolssorted);
7322  SCIProwSort(row2);
7323  assert(row2->lpcolssorted);
7324  assert(row2->nonlpcolssorted);
7325 
7326  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7327  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7328 
7329  row1colsidx = row1->cols_index;
7330  row2colsidx = row2->cols_index;
7331 
7332 #ifndef NDEBUG
7333  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7334  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7335  {
7336  i1 = 0;
7337  i2 = row2->nlpcols;
7338  while( i1 < row1->nlpcols && i2 < row2->len )
7339  {
7340  assert(row1->cols[i1] != row2->cols[i2]);
7341  if( row1->cols[i1]->index < row2->cols[i2]->index )
7342  ++i1;
7343  else
7344  {
7345  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7346  ++i2;
7347  }
7348  }
7349  assert(i1 == row1->nlpcols || i2 == row2->len);
7350 
7351  i1 = row1->nlpcols;
7352  i2 = 0;
7353  while( i1 < row1->len && i2 < row2->nlpcols )
7354  {
7355  assert(row1->cols[i1] != row2->cols[i2]);
7356  if( row1->cols[i1]->index < row2->cols[i2]->index )
7357  ++i1;
7358  else
7359  {
7360  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7361  ++i2;
7362  }
7363  }
7364  assert(i1 == row1->len || i2 == row2->nlpcols);
7365  }
7366 #endif
7367 
7368  /* The "easy" cases 1) and 2) */
7369  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7370  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7371  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7372  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7373  {
7374  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7375  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7376 
7377  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7378  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7379  */
7380  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7381  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7382  prod = 0;
7383 
7384  /* calculate the scalar product */
7385  while( i1 >= 0 && i2 >= 0 )
7386  {
7387  assert(row1->cols[i1]->index == row1colsidx[i1]);
7388  assert(row2->cols[i2]->index == row2colsidx[i2]);
7389  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7390  if( row1colsidx[i1] < row2colsidx[i2] )
7391  --i2;
7392  else if( row1colsidx[i1] > row2colsidx[i2] )
7393  --i1;
7394  else
7395  {
7396  ++prod;
7397  --i1;
7398  --i2;
7399  }
7400  }
7401  }
7402  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7403  else
7404  {
7405  SCIP_Bool lpcols;
7406  int ilp1;
7407  int inlp1;
7408  int ilp2;
7409  int inlp2;
7410  int end1;
7411  int end2;
7412 
7413  prod = 0;
7414  ilp1 = 0;
7415  ilp2 = 0;
7416 
7417  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7418  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7419  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7420 
7421  /* handle the case of four partitions (case 3) until one partition is finished;
7422  * cases 4a), 4b), and 5) will fail the while-condition
7423  */
7424  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7425  {
7426  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7427  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7428  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7429  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7430  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7431  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7432  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7433  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7434 
7435  /* rows have the same linked LP columns */
7436  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7437  {
7438  ++prod;
7439  ++ilp1;
7440  ++ilp2;
7441  }
7442  /* LP column of row1 is the same as unlinked column of row2 */
7443  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7444  {
7445  ++prod;
7446  ++ilp1;
7447  ++inlp2;
7448  }
7449  /* unlinked column of row1 is the same as LP column of row2 */
7450  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7451  {
7452  ++prod;
7453  ++inlp1;
7454  ++ilp2;
7455  }
7456  /* two unlinked LP columns are the same */
7457  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7458  {
7459  ++prod;
7460  ++inlp1;
7461  ++inlp2;
7462  }
7463  /* increase smallest counter */
7464  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7465  {
7466  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7467  {
7468  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7469  ++ilp1;
7470  else
7471  ++ilp2;
7472  }
7473  else
7474  {
7475  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7476  ++ilp1;
7477  else
7478  ++inlp2;
7479  }
7480  }
7481  else
7482  {
7483  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7484  {
7485  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7486  ++inlp1;
7487  else
7488  ++ilp2;
7489  }
7490  else
7491  {
7492  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7493  ++inlp1;
7494  else
7495  ++inlp2;
7496  }
7497  }
7498  }
7499 
7500  /* One partition was completely handled, we just have to handle the three remaining partitions:
7501  * the remaining partition of this row and the two partitions of the other row.
7502  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7503  */
7504  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7505  {
7506  int tmpilp;
7507  int tmpinlp;
7508 
7509  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7510 
7511  SCIPswapPointers((void**) &row1, (void**) &row2);
7512  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7513  tmpilp = ilp1;
7514  tmpinlp = inlp1;
7515  ilp1 = ilp2;
7516  inlp1 = inlp2;
7517  ilp2 = tmpilp;
7518  inlp2 = tmpinlp;
7519  }
7520 
7521  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7522  * -> this merges cases 4a) and 4b)
7523  */
7524  if( ilp1 == row1->nlpcols )
7525  {
7526  i1 = inlp1;
7527  end1 = row1->len;
7528  lpcols = FALSE;
7529  }
7530  else
7531  {
7532  assert(inlp1 == row1->len);
7533 
7534  i1 = ilp1;
7535  end1 = row1->nlpcols;
7536  lpcols = TRUE;
7537  }
7538 
7539  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7540  * case 5) will fail the while-condition
7541  */
7542  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7543  {
7544  assert(row1->cols[i1]->index == row1colsidx[i1]);
7545  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7546  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7547  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7548  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7549 
7550  /* current column in row 1 is the same as the current LP column in row 2 */
7551  if( row1colsidx[i1] == row2colsidx[ilp2] )
7552  {
7553  ++prod;
7554  ++i1;
7555  ++ilp2;
7556  }
7557  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7558  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7559  {
7560  ++prod;
7561  ++i1;
7562  ++inlp2;
7563  }
7564  /* increase smallest counter */
7565  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7566  {
7567  if( row1colsidx[i1] < row2colsidx[ilp2] )
7568  ++i1;
7569  else
7570  ++ilp2;
7571  }
7572  else
7573  {
7574  if( row1colsidx[i1] < row2colsidx[inlp2] )
7575  ++i1;
7576  else
7577  ++inlp2;
7578  }
7579  }
7580 
7581  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7582  * the two rows
7583  */
7584  if( i1 < end1 )
7585  {
7586  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7587  if( ilp2 == row2->nlpcols )
7588  {
7589  i2 = inlp2;
7590  end2 = row2->len;
7591  lpcols = FALSE;
7592  }
7593  else
7594  {
7595  assert(inlp2 == row2->len);
7596 
7597  i2 = ilp2;
7598  end2 = row2->nlpcols;
7599  }
7600 
7601  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7602  while( i1 < end1 && i2 < end2 )
7603  {
7604  assert(row1->cols[i1]->index == row1colsidx[i1]);
7605  assert(row2->cols[i2]->index == row2colsidx[i2]);
7606  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7607 
7608  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7609  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7610  {
7611  ++prod;
7612  ++i1;
7613  ++i2;
7614  }
7615  /* increase smallest counter */
7616  else if( row1colsidx[i1] < row2colsidx[i2] )
7617  ++i1;
7618  else
7619  ++i2;
7620  }
7621  }
7622  }
7623 
7624  return prod;
7625 }
7626 
7627 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7628  * p = |v*w|/(|v|*|w|);
7629  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7630  */
7632  SCIP_ROW* row1, /**< first LP row */
7633  SCIP_ROW* row2, /**< second LP row */
7634  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7635  )
7636 {
7637  SCIP_Real parallelism;
7638  SCIP_Real scalarprod;
7639 
7640  switch( orthofunc )
7641  {
7642  case 'e':
7643  scalarprod = SCIProwGetScalarProduct(row1, row2);
7644  if( scalarprod == 0.0 )
7645  {
7646  parallelism = 0.0;
7647  break;
7648  }
7649 
7650  if( SCIProwGetNorm(row1) == 0.0 )
7651  {
7652  /* In theory, this should not happen if the scalarproduct is not zero
7653  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7654  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7655  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7656  */
7657  int i;
7658  for( i = 0; i < row1->len; ++i )
7659  if( row1->cols[i]->lppos >= 0 )
7660  row1->sqrnorm += SQR(row1->vals[i]);
7661  assert(SCIProwGetNorm(row1) != 0.0);
7662  }
7663 
7664  if( SCIProwGetNorm(row2) == 0.0 )
7665  {
7666  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7667  int i;
7668  for( i = 0; i < row2->len; ++i )
7669  if( row2->cols[i]->lppos >= 0 )
7670  row2->sqrnorm += SQR(row2->vals[i]);
7671  assert(SCIProwGetNorm(row2) != 0.0);
7672  }
7673 
7674  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7675  break;
7676 
7677  case 'd':
7678  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7679  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7680  break;
7681 
7682  default:
7683  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7684  SCIPABORT();
7685  parallelism = 0.0; /*lint !e527*/
7686  }
7687 
7688  return parallelism;
7689 }
7690 
7691 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7692  * o = 1 - |v*w|/(|v|*|w|);
7693  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7694  */
7696  SCIP_ROW* row1, /**< first LP row */
7697  SCIP_ROW* row2, /**< second LP row */
7698  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7699  )
7700 {
7701  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7702 }
7703 
7704 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7705  * function, if the value is 0, it is orthogonal to the objective function
7706  */
7708  SCIP_ROW* row, /**< LP row */
7709  SCIP_SET* set, /**< global SCIP settings */
7710  SCIP_LP* lp /**< current LP data */
7711  )
7712 {
7713  SCIP_Real prod;
7714  SCIP_Real parallelism;
7715 
7716  assert(row != NULL);
7717  assert(lp != NULL);
7718 
7719  if( lp->objsqrnormunreliable )
7720  SCIPlpRecalculateObjSqrNorm(set, lp);
7721 
7722  assert(!lp->objsqrnormunreliable);
7723  assert(lp->objsqrnorm >= 0.0);
7724 
7725  checkRowSqrnorm(row);
7726  checkRowObjprod(row);
7727 
7728  prod = row->sqrnorm * lp->objsqrnorm;
7729 
7730  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7731  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7732  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7733  parallelism = MIN(parallelism, 1.0);
7734  parallelism = MAX(parallelism, 0.0);
7735 
7736  return parallelism;
7737 }
7738 
7739 /** includes event handler with given data in row's event filter */
7741  SCIP_ROW* row, /**< row */
7742  BMS_BLKMEM* blkmem, /**< block memory */
7743  SCIP_SET* set, /**< global SCIP settings */
7744  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7745  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7746  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7747  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7748  )
7749 {
7750  assert(row != NULL);
7751  assert(row->eventfilter != NULL);
7752  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7753  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7754 
7755  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7756  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7757 
7758  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7759 
7760  return SCIP_OKAY;
7761 }
7762 
7763 /** deletes event handler with given data from row's event filter */
7765  SCIP_ROW* row, /**< row */
7766  BMS_BLKMEM* blkmem, /**< block memory */
7767  SCIP_SET* set, /**< global SCIP settings */
7768  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7769  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7770  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7771  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7772  )
7773 {
7774  assert(row != NULL);
7775  assert(row->eventfilter != NULL);
7776 
7777  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7778 
7779  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7780 
7781  return SCIP_OKAY;
7782 }
7783 
7784 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7786  SCIP_ROW* row, /**< LP row */
7787  SCIP_STAT* stat /**< problem statistics */
7788  )
7789 {
7790  assert(row != NULL);
7791  assert(stat != NULL);
7792  assert(stat->nnodes > 0);
7793 
7794  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7795  row->obsoletenode = stat->nnodes;
7796 }
7797 
7798 /*
7799  * LP solver data update
7800  */
7801 
7802 /** resets column data to represent a column not in the LP solver */
7803 static
7805  SCIP_COL* col /**< column to be marked deleted */
7806  )
7807 {
7808  assert(col != NULL);
7809 
7810  col->lpipos = -1;
7811  col->primsol = 0.0;
7812  col->redcost = SCIP_INVALID;
7813  col->farkascoef = SCIP_INVALID;
7814  col->sbdown = SCIP_INVALID;
7815  col->sbup = SCIP_INVALID;
7816  col->sbdownvalid = FALSE;
7817  col->sbupvalid = FALSE;
7818  col->validredcostlp = -1;
7819  col->validfarkaslp = -1;
7820  col->sbitlim = -1;
7821  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7822 }
7823 
7824 /** applies all cached column removals to the LP solver */
7825 static
7827  SCIP_LP* lp /**< current LP data */
7828  )
7829 {
7830  assert(lp != NULL);
7831  assert(lp->lpifirstchgcol <= lp->nlpicols);
7832  assert(lp->lpifirstchgcol <= lp->ncols);
7833 
7834  /* find the first column to change */
7835  while( lp->lpifirstchgcol < lp->nlpicols
7836  && lp->lpifirstchgcol < lp->ncols
7837  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7838  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7839  {
7840  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7841  lp->lpifirstchgcol++;
7842  }
7843 
7844  /* shrink LP to the part which didn't change */
7845  if( lp->lpifirstchgcol < lp->nlpicols )
7846  {
7847  int i;
7848 
7849  assert(!lp->diving);
7850  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7851  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7852  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7853  {
7854  markColDeleted(lp->lpicols[i]);
7855  }
7856  lp->nlpicols = lp->lpifirstchgcol;
7857  lp->flushdeletedcols = TRUE;
7858  lp->updateintegrality = TRUE;
7859 
7860  /* mark the LP unsolved */
7861  lp->solved = FALSE;
7862  lp->primalfeasible = FALSE;
7863  lp->primalchecked = FALSE;
7864  lp->lpobjval = SCIP_INVALID;
7866  }
7867  assert(lp->nlpicols == lp->lpifirstchgcol);
7868 
7869  return SCIP_OKAY;
7870 }
7871 
7872 /** computes for the given column the lower and upper bound that should be flushed into the LP
7873  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7874  * the bounds are explicitly added to the LP in any case
7875  */
7876 static
7878  SCIP_LP* lp, /**< current LP data */
7879  SCIP_SET* set, /**< global SCIP settings */
7880  SCIP_COL* col, /**< column to compute bounds for */
7881  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7882  SCIP_Real* lb, /**< pointer to store the new lower bound */
7883  SCIP_Real* ub /**< pointer to store the new upper bound */
7884  )
7885 {
7886  assert(lp != NULL);
7887  assert(set != NULL);
7888  assert(col != NULL);
7889  assert(lb != NULL);
7890  assert(ub != NULL);
7891 
7892  /* get the correct new lower bound:
7893  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7894  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7895  */
7896  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7897  (*lb) = -lpiinf;
7898  else
7899  (*lb) = col->lb;
7900  /* get the correct new upper bound:
7901  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7902  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7903  */
7904  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7905  (*ub) = lpiinf;
7906  else
7907  (*ub) = col->ub;
7908 }
7909 
7910 /** applies all cached column additions to the LP solver */
7911 static
7913  SCIP_LP* lp, /**< current LP data */
7914  BMS_BLKMEM* blkmem, /**< block memory */
7915  SCIP_SET* set, /**< global SCIP settings */
7916  SCIP_EVENTQUEUE* eventqueue /**< event queue */
7917  )
7918 {
7919  SCIP_Real* obj;
7920  SCIP_Real* lb;
7921  SCIP_Real* ub;
7922  int* beg;
7923  int* ind;
7924  SCIP_Real* val;
7925  char** name;
7926  SCIP_COL* col;
7927  SCIP_Real lpiinf;
7928  int c;
7929  int pos;
7930  int nnonz;
7931  int naddcols;
7932  int naddcoefs;
7933  int i;
7934  int lpipos;
7935 
7936  assert(lp != NULL);
7937  assert(lp->lpifirstchgcol == lp->nlpicols);
7938  assert(blkmem != NULL);
7939  assert(set != NULL);
7940 
7941  /* if there are no columns to add, we are ready */
7942  if( lp->ncols == lp->nlpicols )
7943  return SCIP_OKAY;
7944 
7945  /* add the additional columns */
7946  assert(!lp->diving);
7947  assert(lp->ncols > lp->nlpicols);
7948  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
7949 
7950  /* get the solver's infinity value */
7951  lpiinf = SCIPlpiInfinity(lp->lpi);
7952 
7953  /* count the (maximal) number of added coefficients, calculate the number of added columns */
7954  naddcols = lp->ncols - lp->nlpicols;
7955  naddcoefs = 0;
7956  for( c = lp->nlpicols; c < lp->ncols; ++c )
7957  naddcoefs += lp->cols[c]->len;
7958  assert(naddcols > 0);
7959 
7960  /* get temporary memory for changes */
7961  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
7962  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
7963  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
7964  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
7965  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
7966  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
7967  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
7968 
7969  /* fill temporary memory with column data */
7970  nnonz = 0;
7971  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
7972  {
7973  col = lp->cols[c];
7974  assert(col != NULL);
7975  assert(col->var != NULL);
7976  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
7977  assert(SCIPvarGetCol(col->var) == col);
7978  assert(col->lppos == c);
7979  assert(nnonz + col->nlprows <= naddcoefs);
7980 
7981  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
7982  debugColPrint(set, col);
7983 
7984  /* Because the column becomes a member of the LP solver, it now can take values
7985  * different from zero. That means, we have to include the column in the corresponding
7986  * row vectors.
7987  */
7988  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
7989 
7990  lp->lpicols[c] = col;
7991  col->lpipos = c;
7992  col->primsol = SCIP_INVALID;
7993  col->redcost = SCIP_INVALID;
7994  col->farkascoef = SCIP_INVALID;
7995  col->sbdown = SCIP_INVALID;
7996  col->sbup = SCIP_INVALID;
7997  col->sbdownvalid = FALSE;
7998  col->sbupvalid = FALSE;
7999  col->validredcostlp = -1;
8000  col->validfarkaslp = -1;
8001  col->sbitlim = -1;
8002  col->objchanged = FALSE;
8003  col->lbchanged = FALSE;
8004  col->ubchanged = FALSE;
8005  col->coefchanged = FALSE;
8006  obj[pos] = col->obj;
8007 
8008  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8009  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8010 
8011  beg[pos] = nnonz;
8012  name[pos] = (char*)SCIPvarGetName(col->var);
8013 
8014  col->flushedobj = obj[pos];
8015  col->flushedlb = lb[pos];
8016  col->flushedub = ub[pos];
8017 
8018  for( i = 0; i < col->nlprows; ++i )
8019  {
8020  assert(col->rows[i] != NULL);
8021  lpipos = col->rows[i]->lpipos;
8022  if( lpipos >= 0 )
8023  {
8024  assert(lpipos < lp->nrows);
8025  assert(nnonz < naddcoefs);
8026  ind[nnonz] = lpipos;
8027  val[nnonz] = col->vals[i];
8028  nnonz++;
8029  }
8030  }
8031 #ifndef NDEBUG
8032  for( i = col->nlprows; i < col->len; ++i )
8033  {
8034  assert(col->rows[i] != NULL);
8035  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8036  }
8037 #endif
8038  }
8039 
8040  /* call LP interface */
8041  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8042  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8043  lp->nlpicols = lp->ncols;
8044  lp->lpifirstchgcol = lp->nlpicols;
8045 
8046  /* free temporary memory */
8047  SCIPsetFreeBufferArray(set, &name);
8048  SCIPsetFreeBufferArray(set, &val);
8049  SCIPsetFreeBufferArray(set, &ind);
8050  SCIPsetFreeBufferArray(set, &beg);
8051  SCIPsetFreeBufferArray(set, &ub);
8052  SCIPsetFreeBufferArray(set, &lb);
8053  SCIPsetFreeBufferArray(set, &obj);
8054 
8055  lp->flushaddedcols = TRUE;
8056  lp->updateintegrality = TRUE;
8057 
8058  /* mark the LP unsolved */
8059  lp->solved = FALSE;
8060  lp->dualfeasible = FALSE;
8061  lp->dualchecked = FALSE;
8062  lp->lpobjval = SCIP_INVALID;
8064 
8065  return SCIP_OKAY;
8066 }
8067 
8068 /** resets row data to represent a row not in the LP solver */
8069 static
8071  SCIP_ROW* row /**< row to be marked deleted */
8072  )
8073 {
8074  assert(row != NULL);
8075 
8076  row->lpipos = -1;
8077  row->dualsol = 0.0;
8078  row->activity = SCIP_INVALID;
8079  row->dualfarkas = 0.0;
8080  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8081  row->validactivitylp = -1;
8082 }
8083 
8084 /** applies all cached row removals to the LP solver */
8085 static
8087  SCIP_LP* lp, /**< current LP data */
8088  BMS_BLKMEM* blkmem, /**< block memory */
8089  SCIP_SET* set /**< global SCIP settings */
8090  )
8091 {
8092  assert(lp != NULL);
8093  assert(lp->lpifirstchgrow <= lp->nlpirows);
8094  assert(lp->lpifirstchgrow <= lp->nrows);
8095 
8096  /* find the first row to change */
8097  while( lp->lpifirstchgrow < lp->nlpirows
8098  && lp->lpifirstchgrow < lp->nrows
8099  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8100  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8101  {
8102  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8103  lp->lpifirstchgrow++;
8104  }
8105 
8106  /* shrink LP to the part which didn't change */
8107  if( lp->lpifirstchgrow < lp->nlpirows )
8108  {
8109  int i;
8110 
8111  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8112  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8113  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8114  {
8115  markRowDeleted(lp->lpirows[i]);
8116  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8117  }
8118  lp->nlpirows = lp->lpifirstchgrow;
8119  lp->flushdeletedrows = TRUE;
8120 
8121  /* mark the LP unsolved */
8122  lp->solved = FALSE;
8123  lp->dualfeasible = FALSE;
8124  lp->dualchecked = FALSE;
8125  lp->lpobjval = SCIP_INVALID;
8127  }
8128  assert(lp->nlpirows == lp->lpifirstchgrow);
8129 
8130  return SCIP_OKAY;
8131 }
8132 
8133 /** applies all cached row additions and removals to the LP solver */
8134 static
8136  SCIP_LP* lp, /**< current LP data */
8137  BMS_BLKMEM* blkmem, /**< block memory */
8138  SCIP_SET* set, /**< global SCIP settings */
8139  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8140  )
8141 {
8142  SCIP_Real* lhs;
8143  SCIP_Real* rhs;
8144  int* beg;
8145  int* ind;
8146  SCIP_Real* val;
8147  char** name;
8148  SCIP_ROW* row;
8149  SCIP_Real lpiinf;
8150  int r;
8151  int pos;
8152  int nnonz;
8153  int naddrows;
8154  int naddcoefs;
8155  int i;
8156  int lpipos;
8157 
8158  assert(lp != NULL);
8159  assert(lp->lpifirstchgrow == lp->nlpirows);
8160  assert(blkmem != NULL);
8161 
8162  /* if there are no rows to add, we are ready */
8163  if( lp->nrows == lp->nlpirows )
8164  return SCIP_OKAY;
8165 
8166  /* add the additional rows */
8167  assert(lp->nrows > lp->nlpirows);
8168  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8169 
8170  /* get the solver's infinity value */
8171  lpiinf = SCIPlpiInfinity(lp->lpi);
8172 
8173  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8174  naddrows = lp->nrows - lp->nlpirows;
8175  naddcoefs = 0;
8176  for( r = lp->nlpirows; r < lp->nrows; ++r )
8177  naddcoefs += lp->rows[r]->len;
8178  assert(naddrows > 0);
8179 
8180  /* get temporary memory for changes */
8181  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8182  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8183  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8184  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8185  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8186  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8187 
8188  /* fill temporary memory with row data */
8189  nnonz = 0;
8190  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8191  {
8192  row = lp->rows[r];
8193  assert(row != NULL);
8194  assert(row->lppos == r);
8195  assert(nnonz + row->nlpcols <= naddcoefs);
8196 
8197  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8198  debugRowPrint(set, row);
8199 
8200  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8201  * different from zero. That means, we have to include the row in the corresponding
8202  * column vectors.
8203  */
8204  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8205 
8206  SCIProwCapture(row);
8207  lp->lpirows[r] = row;
8208  row->lpipos = r;
8209  row->dualsol = SCIP_INVALID;
8210  row->activity = SCIP_INVALID;
8211  row->dualfarkas = SCIP_INVALID;
8212  row->validactivitylp = -1;
8213  row->lhschanged = FALSE;
8214  row->rhschanged = FALSE;
8215  row->coefchanged = FALSE;
8216  if( SCIPsetIsInfinity(set, -row->lhs) )
8217  lhs[pos] = -lpiinf;
8218  else
8219  lhs[pos] = row->lhs - row->constant;
8220  if( SCIPsetIsInfinity(set, row->rhs) )
8221  rhs[pos] = lpiinf;
8222  else
8223  rhs[pos] = row->rhs - row->constant;
8224  beg[pos] = nnonz;
8225  name[pos] = row->name;
8226 
8227  row->flushedlhs = lhs[pos];
8228  row->flushedrhs = rhs[pos];
8229 
8230  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8231  for( i = 0; i < row->nlpcols; ++i )
8232  {
8233  assert(row->cols[i] != NULL);
8234  lpipos = row->cols[i]->lpipos;
8235  if( lpipos >= 0 )
8236  {
8237  assert(lpipos < lp->ncols);
8238  assert(nnonz < naddcoefs);
8239  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8240  ind[nnonz] = lpipos;
8241  val[nnonz] = row->vals[i];
8242  nnonz++;
8243  }
8244  }
8245  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8246 #ifndef NDEBUG
8247  for( i = row->nlpcols; i < row->len; ++i )
8248  {
8249  assert(row->cols[i] != NULL);
8250  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8251  }
8252 #endif
8253  }
8254 
8255  /* call LP interface */
8256  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8257  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8258  lp->nlpirows = lp->nrows;
8259  lp->lpifirstchgrow = lp->nlpirows;
8260 
8261  /* free temporary memory */
8262  SCIPsetFreeBufferArray(set, &name);
8263  SCIPsetFreeBufferArray(set, &val);
8264  SCIPsetFreeBufferArray(set, &ind);
8265  SCIPsetFreeBufferArray(set, &beg);
8266  SCIPsetFreeBufferArray(set, &rhs);
8267  SCIPsetFreeBufferArray(set, &lhs);
8268 
8269  lp->flushaddedrows = TRUE;
8270 
8271  /* mark the LP unsolved */
8272  lp->solved = FALSE;
8273  lp->primalfeasible = FALSE;
8274  lp->primalchecked = FALSE;
8275  lp->lpobjval = SCIP_INVALID;
8277 
8278  return SCIP_OKAY;
8279 }
8280 
8281 /** applies all cached column bound and objective changes to the LP */
8282 static
8284  SCIP_LP* lp, /**< current LP data */
8285  SCIP_SET* set /**< global SCIP settings */
8286  )
8287 {
8288 #ifndef NDEBUG
8289  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8290 #endif
8291  SCIP_COL* col;
8292  int* objind;
8293  int* bdind;
8294  SCIP_Real* obj;
8295  SCIP_Real* lb;
8296  SCIP_Real* ub;
8297  SCIP_Real lpiinf;
8298  int nobjchg;
8299  int nbdchg;
8300  int i;
8301 
8302  assert(lp != NULL);
8303 
8304  if( lp->nchgcols == 0 )
8305  return SCIP_OKAY;
8306 
8307  /* get the solver's infinity value */
8308  lpiinf = SCIPlpiInfinity(lp->lpi);
8309 
8310  /* get temporary memory for changes */
8311  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8312  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8313  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8314  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8315  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8316 
8317  /* collect all cached bound and objective changes */
8318  nobjchg = 0;
8319  nbdchg = 0;
8320  for( i = 0; i < lp->nchgcols; ++i )
8321  {
8322  col = lp->chgcols[i];
8323  assert(col != NULL);
8324  assert(col->var != NULL);
8325  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8326  assert(SCIPvarGetCol(col->var) == col);
8327 
8328  if( col->lpipos >= 0 )
8329  {
8330 #ifndef NDEBUG
8331  /* do not check consistency of data with LPI in case of LPI=none */
8332  if( !lpinone )
8333  {
8334  SCIP_Real lpiobj;
8335  SCIP_Real lpilb;
8336  SCIP_Real lpiub;
8337 
8338  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8339  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8340  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8341  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8342  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8343  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8344  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8345  }
8346 #endif
8347 
8348  if( col->objchanged )
8349  {
8350  SCIP_Real newobj;
8351 
8352  newobj = col->obj;
8353  if( col->flushedobj != newobj ) /*lint !e777*/
8354  {
8355  assert(nobjchg < lp->ncols);
8356  objind[nobjchg] = col->lpipos;
8357  obj[nobjchg] = newobj;
8358  nobjchg++;
8359  col->flushedobj = newobj;
8360  }
8361  col->objchanged = FALSE;
8362  }
8363 
8364  if( col->lbchanged || col->ubchanged )
8365  {
8366  SCIP_Real newlb;
8367  SCIP_Real newub;
8368 
8369  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8370  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8371 
8372  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8373  {
8374  assert(nbdchg < lp->ncols);
8375  bdind[nbdchg] = col->lpipos;
8376  lb[nbdchg] = newlb;
8377  ub[nbdchg] = newub;
8378  nbdchg++;
8379  col->flushedlb = newlb;
8380  col->flushedub = newub;
8381  }
8382  col->lbchanged = FALSE;
8383  col->ubchanged = FALSE;
8384  }
8385  }
8386  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8387  }
8388 
8389  /* change objective values in LP */
8390  if( nobjchg > 0 )
8391  {
8392  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8393  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8394 
8395  /* mark the LP unsolved */
8396  lp->solved = FALSE;
8397  lp->dualfeasible = FALSE;
8398  lp->dualchecked = FALSE;
8399  lp->lpobjval = SCIP_INVALID;
8401  }
8402 
8403  /* change bounds in LP */
8404  if( nbdchg > 0 )
8405  {
8406  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8407  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8408 
8409  /* mark the LP unsolved */
8410  lp->solved = FALSE;
8411  lp->primalfeasible = FALSE;
8412  lp->primalchecked = FALSE;
8413  lp->lpobjval = SCIP_INVALID;
8415  }
8416 
8417  lp->nchgcols = 0;
8418 
8419  /* free temporary memory */
8420  SCIPsetFreeBufferArray(set, &ub);
8421  SCIPsetFreeBufferArray(set, &lb);
8422  SCIPsetFreeBufferArray(set, &bdind);
8423  SCIPsetFreeBufferArray(set, &obj);
8424  SCIPsetFreeBufferArray(set, &objind);
8425 
8426  return SCIP_OKAY;
8427 }
8428 
8429 /** applies all cached row side changes to the LP */
8430 static
8432  SCIP_LP* lp, /**< current LP data */
8433  SCIP_SET* set /**< global SCIP settings */
8434  )
8435 {
8436 #ifndef NDEBUG
8437  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8438 #endif
8439  SCIP_ROW* row;
8440  int* ind;
8441  SCIP_Real* lhs;
8442  SCIP_Real* rhs;
8443  SCIP_Real lpiinf;
8444  int i;
8445  int nchg;
8446 
8447  assert(lp != NULL);
8448 
8449  if( lp->nchgrows == 0 )
8450  return SCIP_OKAY;
8451 
8452  /* get the solver's infinity value */
8453  lpiinf = SCIPlpiInfinity(lp->lpi);
8454 
8455  /* get temporary memory for changes */
8456  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8457  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8458  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8459 
8460  /* collect all cached left and right hand side changes */
8461  nchg = 0;
8462  for( i = 0; i < lp->nchgrows; ++i )
8463  {
8464  row = lp->chgrows[i];
8465  assert(row != NULL);
8466 
8467  if( row->lpipos >= 0 )
8468  {
8469 #ifndef NDEBUG
8470  /* do not check consistency of data with LPI in case of LPI=none */
8471  if( !lpinone )
8472  {
8473  SCIP_Real lpilhs;
8474  SCIP_Real lpirhs;
8475 
8476  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8477  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8478  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8479  }
8480 #endif
8481  if( row->lhschanged || row->rhschanged )
8482  {
8483  SCIP_Real newlhs;
8484  SCIP_Real newrhs;
8485 
8486  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8487  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8488  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8489  {
8490  assert(nchg < lp->nrows);
8491  ind[nchg] = row->lpipos;
8492  lhs[nchg] = newlhs;
8493  rhs[nchg] = newrhs;
8494  nchg++;
8495  row->flushedlhs = newlhs;
8496  row->flushedrhs = newrhs;
8497  }
8498  row->lhschanged = FALSE;
8499  row->rhschanged = FALSE;
8500  }
8501  }
8502  }
8503 
8504  /* change left and right hand sides in LP */
8505  if( nchg > 0 )
8506  {
8507  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8508  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8509 
8510  /* mark the LP unsolved */
8511  lp->solved = FALSE;
8512  lp->primalfeasible = FALSE;
8513  lp->primalchecked = FALSE;
8514  lp->lpobjval = SCIP_INVALID;
8516  }
8517 
8518  lp->nchgrows = 0;
8519 
8520  /* free temporary memory */
8521  SCIPsetFreeBufferArray(set, &rhs);
8522  SCIPsetFreeBufferArray(set, &lhs);
8523  SCIPsetFreeBufferArray(set, &ind);
8524 
8525  return SCIP_OKAY;
8526 }
8527 
8528 /** copy integrality information to the LP */
8529 static
8531  SCIP_LP* lp, /**< current LP data */
8532  SCIP_SET* set /**< global SCIP settings */
8533  )
8534 {
8535  int i;
8536  int nintegers;
8537  int* integerInfo;
8538  SCIP_VAR* var;
8539 
8540  assert(lp != NULL);
8541 
8542  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8543 
8544  /* count total number of integralities */
8545  nintegers = 0;
8546 
8547  for( i = 0; i < lp->ncols; ++i )
8548  {
8549  var = SCIPcolGetVar(lp->cols[i]);
8550  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8551  {
8552  integerInfo[i] = 1;
8553  ++nintegers;
8554  }
8555  else
8556  integerInfo[i] = 0;
8557  }
8558 
8559  /* only pass integrality information if integer variables are present */
8560  if( nintegers > 0 )
8561  {
8562  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8563  }
8564  else
8565  {
8567  }
8568 
8569  SCIPsetFreeBufferArray(set, &integerInfo);
8570 
8571  /* mark integralities to be updated */
8572  lp->updateintegrality = FALSE;
8573 
8574  return SCIP_OKAY;
8575 }
8576 
8577 /** applies all cached changes to the LP solver */
8579  SCIP_LP* lp, /**< current LP data */
8580  BMS_BLKMEM* blkmem, /**< block memory */
8581  SCIP_SET* set, /**< global SCIP settings */
8582  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8583  )
8584 {
8585  assert(lp != NULL);
8586  assert(blkmem != NULL);
8587 
8588  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",
8589  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8590 
8591  if( !lp->flushed )
8592  {
8593  lp->flushdeletedcols = FALSE;
8594  lp->flushaddedcols = FALSE;
8595  lp->flushdeletedrows = FALSE;
8596  lp->flushaddedrows = FALSE;
8597 
8598  SCIP_CALL( lpFlushDelCols(lp) );
8599  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8600  SCIP_CALL( lpFlushChgCols(lp, set) );
8601  SCIP_CALL( lpFlushChgRows(lp, set) );
8602  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8603  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8604 
8605  lp->flushed = TRUE;
8606 
8607  checkLinks(lp);
8608  }
8609 
8610  /* if the cutoff bound was changed in between, we want to re-optimize the LP even if nothing else has changed */
8611  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 ) /*lint !e777*/
8612  {
8613  lp->solved = FALSE;
8615  }
8616 
8617  assert(lp->nlpicols == lp->ncols);
8618  assert(lp->lpifirstchgcol == lp->nlpicols);
8619  assert(lp->nlpirows == lp->nrows);
8620  assert(lp->lpifirstchgrow == lp->nlpirows);
8621  assert(lp->nchgcols == 0);
8622  assert(lp->nchgrows == 0);
8623 #ifndef NDEBUG
8624  {
8625  int ncols;
8626  int nrows;
8627 
8628  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8629  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8630  assert(ncols == lp->ncols);
8631  assert(nrows == lp->nrows);
8632  }
8633 #endif
8634 
8635  return SCIP_OKAY;
8636 }
8637 
8638 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8640  SCIP_LP* lp, /**< current LP data */
8641  SCIP_SET* set /**< global SCIP settings */
8642  )
8643 {
8644 #ifndef NDEBUG
8645  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8646 #endif
8647  int i;
8648 
8649  assert(lp != NULL);
8650 
8651 #ifndef NDEBUG
8652  /* check, if there are really no column or row deletions or coefficient changes left */
8653  while( lp->lpifirstchgcol < lp->nlpicols
8654  && lp->lpifirstchgcol < lp->ncols
8655  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8656  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8657  {
8658  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8659  lp->lpifirstchgcol++;
8660  }
8661  assert(lp->nlpicols == lp->lpifirstchgcol);
8662 
8663  while( lp->lpifirstchgrow < lp->nlpirows
8664  && lp->lpifirstchgrow < lp->nrows
8665  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8666  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8667  {
8668  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8669  lp->lpifirstchgrow++;
8670  }
8671  assert(lp->nlpirows == lp->lpifirstchgrow);
8672 #endif
8673 
8674  lp->lpifirstchgcol = lp->nlpicols;
8675  lp->lpifirstchgrow = lp->nlpirows;
8676 
8677  /* check, if there are really no column or row additions left */
8678  assert(lp->ncols == lp->nlpicols);
8679  assert(lp->nrows == lp->nlpirows);
8680 
8681  /* mark the changed columns to be unchanged, and check, if this is really correct */
8682  for( i = 0; i < lp->nchgcols; ++i )
8683  {
8684  SCIP_COL* col;
8685 
8686  col = lp->chgcols[i];
8687  assert(col != NULL);
8688  assert(col->var != NULL);
8689  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8690  assert(SCIPvarGetCol(col->var) == col);
8691 
8692  if( col->lpipos >= 0 )
8693  {
8694 #ifndef NDEBUG
8695  /* do not check consistency of data with LPI in case of LPI=none */
8696  if( !lpinone )
8697  {
8698  SCIP_Real lpiobj;
8699  SCIP_Real lpilb;
8700  SCIP_Real lpiub;
8701 
8702  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8703  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8704  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8705  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8706  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8707  assert(col->flushedobj == col->obj); /*lint !e777*/
8708  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8709  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8710  }
8711 #endif
8712  col->objchanged = FALSE;
8713  col->lbchanged = FALSE;
8714  col->ubchanged = FALSE;
8715  }
8716  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8717  }
8718  lp->nchgcols = 0;
8719 
8720  /* mark the changed rows to be unchanged, and check, if this is really correct */
8721  for( i = 0; i < lp->nchgrows; ++i )
8722  {
8723  SCIP_ROW* row;
8724 
8725  row = lp->chgrows[i];
8726  assert(row != NULL);
8727 
8728  if( row->lpipos >= 0 )
8729  {
8730 #ifndef NDEBUG
8731  /* do not check consistency of data with LPI in case of LPI=none */
8732  if( !lpinone )
8733  {
8734  SCIP_Real lpilhs;
8735  SCIP_Real lpirhs;
8736 
8737  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8738  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8739  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8740  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8741  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8742  }
8743 #endif
8744  row->lhschanged = FALSE;
8745  row->rhschanged = FALSE;
8746  }
8747  }
8748  lp->nchgrows = 0;
8749 
8750  /* mark the LP to be flushed */
8751  lp->flushed = TRUE;
8752 
8753  checkLinks(lp);
8754 
8755  return SCIP_OKAY;
8756 }
8757 
8758 
8759 
8760 
8761 /*
8762  * LP methods
8763  */
8764 
8765 /** updates link data after addition of column */
8766 static
8768  SCIP_COL* col, /**< LP column */
8769  SCIP_SET* set /**< global SCIP settings */
8770  )
8771 {
8772  SCIP_ROW* row;
8773  int i;
8774  int pos;
8775 
8776  assert(col != NULL);
8777  assert(col->lppos >= 0);
8778 
8779  /* update column arrays of all linked rows */
8780  for( i = 0; i < col->len; ++i )
8781  {
8782  pos = col->linkpos[i];
8783  if( pos >= 0 )
8784  {
8785  row = col->rows[i];
8786  assert(row != NULL);
8787  assert(row->linkpos[pos] == i);
8788  assert(row->cols[pos] == col);
8789  assert(row->nlpcols <= pos && pos < row->len);
8790 
8791  row->nlpcols++;
8792  rowSwapCoefs(row, pos, row->nlpcols-1);
8793  assert(row->cols[row->nlpcols-1] == col);
8794 
8795  /* if no swap was necessary, mark lpcols to be unsorted */
8796  if( pos == row->nlpcols-1 )
8797  row->lpcolssorted = FALSE;
8798 
8799  /* update norms */
8800  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8801  }
8802  }
8803 }
8804 
8805 /** updates link data after addition of row */
8806 static
8808  SCIP_ROW* row /**< LP row */
8809  )
8810 {
8811  SCIP_COL* col;
8812  int i;
8813  int pos;
8814 
8815  assert(row != NULL);
8816  assert(row->lppos >= 0);
8817 
8818  /* update row arrays of all linked columns */
8819  for( i = 0; i < row->len; ++i )
8820  {
8821  pos = row->linkpos[i];
8822  if( pos >= 0 )
8823  {
8824  col = row->cols[i];
8825  assert(col != NULL);
8826  assert(col->linkpos[pos] == i);
8827  assert(col->rows[pos] == row);
8828  assert(col->nlprows <= pos && pos < col->len);
8829 
8830  col->nlprows++;
8831  colSwapCoefs(col, pos, col->nlprows-1);
8832 
8833  /* if no swap was necessary, mark lprows to be unsorted */
8834  if( pos == col->nlprows-1 )
8835  col->lprowssorted = FALSE;
8836  }
8837  }
8838 }
8839 
8840 /** updates link data after removal of column */
8841 static
8843  SCIP_COL* col, /**< LP column */
8844  SCIP_SET* set /**< global SCIP settings */
8845  )
8846 {
8847  SCIP_ROW* row;
8848  int i;
8849  int pos;
8850 
8851  assert(col != NULL);
8852  assert(col->lppos == -1);
8853 
8854  /* update column arrays of all linked rows */
8855  for( i = 0; i < col->len; ++i )
8856  {
8857  pos = col->linkpos[i];
8858  if( pos >= 0 )
8859  {
8860  row = col->rows[i];
8861  assert(row != NULL);
8862  assert(row->linkpos[pos] == i);
8863  assert(row->cols[pos] == col);
8864  assert(0 <= pos && pos < row->nlpcols);
8865 
8866  /* update norms */
8867  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8868 
8869  row->nlpcols--;
8870  rowSwapCoefs(row, pos, row->nlpcols);
8871 
8872  /* if no swap was necessary, mark nonlpcols to be unsorted */
8873  if( pos == row->nlpcols )
8874  row->nonlpcolssorted = FALSE;
8875  }
8876  }
8877 }
8878 
8879 /** updates link data after removal of row */
8880 static
8882  SCIP_ROW* row /**< LP row */
8883  )
8884 {
8885  SCIP_COL* col;
8886  int i;
8887  int pos;
8888 
8889  assert(row != NULL);
8890  assert(row->lppos == -1);
8891 
8892  /* update row arrays of all linked columns */
8893  for( i = 0; i < row->len; ++i )
8894  {
8895  pos = row->linkpos[i];
8896  if( pos >= 0 )
8897  {
8898  col = row->cols[i];
8899  assert(col != NULL);
8900  assert(0 <= pos && pos < col->nlprows);
8901  assert(col->linkpos[pos] == i);
8902  assert(col->rows[pos] == row);
8903 
8904  col->nlprows--;
8905  colSwapCoefs(col, pos, col->nlprows);
8906 
8907  /* if no swap was necessary, mark lprows to be unsorted */
8908  if( pos == col->nlprows )
8909  col->nonlprowssorted = FALSE;
8910  }
8911  }
8912 }
8913 
8914 static
8916  SCIP_LP* lp, /**< LP data object */
8917  int initsize /**< initial size of the arrays */
8918  )
8919 {
8920  assert(lp != NULL);
8921  assert(lp->divechgsides == NULL);
8922  assert(lp->divechgsidetypes == NULL);
8923  assert(lp->divechgrows == NULL);
8924  assert(lp->ndivechgsides == 0);
8925  assert(lp->divechgsidessize == 0);
8926  assert(initsize > 0);
8927 
8928  lp->divechgsidessize = initsize;
8932 
8933  return SCIP_OKAY;
8934 }
8935 
8936 static
8938  SCIP_LP* lp, /**< LP data object */
8939  int minsize, /**< minimal number of elements */
8940  SCIP_Real growfact /**< growing factor */
8941  )
8942 {
8943  assert(lp != NULL);
8944  assert(lp->divechgsides != NULL);
8945  assert(lp->divechgsidetypes != NULL);
8946  assert(lp->divechgrows != NULL);
8947  assert(lp->ndivechgsides > 0);
8948  assert(lp->divechgsidessize > 0);
8949  assert(minsize > 0);
8950 
8951  if( minsize <= lp->divechgsidessize )
8952  return SCIP_OKAY;
8953 
8954  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
8958 
8959  return SCIP_OKAY;
8960 }
8961 
8962 static
8964  SCIP_LP* lp /**< LP data object */
8965  )
8966 {
8967  assert(lp != NULL);
8968  assert(lp->divechgsides != NULL);
8969  assert(lp->divechgsidetypes != NULL);
8970  assert(lp->divechgrows != NULL);
8971  assert(lp->ndivechgsides == 0);
8972  assert(lp->divechgsidessize > 0);
8973 
8977  lp->divechgsidessize = 0;
8978 }
8979 
8980 #define DIVESTACKINITSIZE 100
8981 
8982 /** creates empty LP data object */
8984  SCIP_LP** lp, /**< pointer to LP data object */
8985  SCIP_SET* set, /**< global SCIP settings */
8986  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
8987  SCIP_STAT* stat, /**< problem statistics */
8988  const char* name /**< problem name */
8989  )
8990 {
8991  SCIP_Bool success;
8992 
8993  assert(lp != NULL);
8994  assert(set != NULL);
8995  assert(stat != NULL);
8996  assert(name != NULL);
8997 
8998  SCIP_ALLOC( BMSallocMemory(lp) );
8999 
9000  /* open LP Solver interface */
9001  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9002 
9003  (*lp)->lpicols = NULL;
9004  (*lp)->lpirows = NULL;
9005  (*lp)->chgcols = NULL;
9006  (*lp)->chgrows = NULL;
9007  (*lp)->cols = NULL;
9008  (*lp)->soldirection = NULL;
9009  (*lp)->lazycols = NULL;
9010  (*lp)->rows = NULL;
9011  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9012  (*lp)->lpobjval = 0.0;
9013  (*lp)->glbpseudoobjval = 0.0;
9014  (*lp)->relglbpseudoobjval = 0.0;
9015  (*lp)->glbpseudoobjvalid = TRUE;
9016  (*lp)->glbpseudoobjvalinf = 0;
9017  (*lp)->pseudoobjval = 0.0;
9018  (*lp)->relpseudoobjval = 0.0;
9019  (*lp)->pseudoobjvalid = TRUE;
9020  (*lp)->pseudoobjvalinf = 0;
9021  (*lp)->looseobjval = 0.0;
9022  (*lp)->rellooseobjval = 0.0;
9023  (*lp)->looseobjvalid = TRUE;
9024  (*lp)->looseobjvalinf = 0;
9025  (*lp)->nloosevars = 0;
9026  (*lp)->rootlpobjval = SCIP_INVALID;
9027  (*lp)->rootlooseobjval = SCIP_INVALID;
9028  (*lp)->cutoffbound = SCIPsetInfinity(set);
9029  (*lp)->objsqrnorm = 0.0;
9030  (*lp)->objsumnorm = 0.0;
9031  (*lp)->lpicolssize = 0;
9032  (*lp)->nlpicols = 0;
9033  (*lp)->lpirowssize = 0;
9034  (*lp)->nlpirows = 0;
9035  (*lp)->lpifirstchgcol = 0;
9036  (*lp)->lpifirstchgrow = 0;
9037  (*lp)->colssize = 0;
9038  (*lp)->soldirectionsize = 0;
9039  (*lp)->ncols = 0;
9040  (*lp)->lazycolssize = 0;
9041  (*lp)->nlazycols = 0;
9042  (*lp)->rowssize = 0;
9043  (*lp)->nrows = 0;
9044  (*lp)->chgcolssize = 0;
9045  (*lp)->nchgcols = 0;
9046  (*lp)->chgrowssize = 0;
9047  (*lp)->nchgrows = 0;
9048  (*lp)->firstnewcol = 0;
9049  (*lp)->firstnewrow = 0;
9050  (*lp)->nremovablecols = 0;
9051  (*lp)->nremovablerows = 0;
9052  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9053  (*lp)->validfarkaslp = -1;
9054  (*lp)->validsoldirlp = -1;
9055  (*lp)->validsoldirsol = NULL;
9056  (*lp)->objsqrnormunreliable = FALSE;
9057  (*lp)->flushdeletedcols = FALSE;
9058  (*lp)->flushaddedcols = FALSE;
9059  (*lp)->flushdeletedrows = FALSE;
9060  (*lp)->flushaddedrows = FALSE;
9061  (*lp)->updateintegrality = TRUE;
9062  (*lp)->flushed = TRUE;
9063  (*lp)->solved = TRUE;
9064  (*lp)->primalfeasible = TRUE;
9065  (*lp)->primalchecked = TRUE;
9066  (*lp)->dualfeasible = TRUE;
9067  (*lp)->dualchecked = TRUE;
9068  (*lp)->solisbasic = FALSE;
9069  (*lp)->rootlpisrelax = TRUE;
9070  (*lp)->isrelax = TRUE;
9071  (*lp)->installing = FALSE;
9072  (*lp)->strongbranching = FALSE;
9073  (*lp)->strongbranchprobing = FALSE;
9074  (*lp)->probing = FALSE;
9075  (*lp)->diving = FALSE;
9076  (*lp)->divingobjchg = FALSE;
9077  (*lp)->divinglazyapplied = FALSE;
9078  (*lp)->divelpistate = NULL;
9079  (*lp)->divelpwasprimfeas = TRUE;
9080  (*lp)->divelpwasprimchecked = TRUE;
9081  (*lp)->divelpwasdualfeas = TRUE;
9082  (*lp)->divelpwasdualchecked = TRUE;
9083  (*lp)->divechgsides = NULL;
9084  (*lp)->divechgsidetypes = NULL;
9085  (*lp)->divechgrows = NULL;
9086  (*lp)->ndivechgsides = 0;
9087  (*lp)->divechgsidessize = 0;
9088  (*lp)->ndivingrows = 0;
9089  (*lp)->divinglpiitlim = INT_MAX;
9090  (*lp)->resolvelperror = FALSE;
9091  (*lp)->divenolddomchgs = 0;
9092  (*lp)->adjustlpval = FALSE;
9093  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9094  (*lp)->lpifeastol = SCIPsetLpfeastol(set);
9095  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9096  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9097  (*lp)->lpifromscratch = FALSE;
9098  (*lp)->lpifastmip = set->lp_fastmip;
9099  (*lp)->lpiscaling = set->lp_scaling;
9100  (*lp)->lpipresolving = set->lp_presolving;
9101  (*lp)->lpilpinfo = set->disp_lpinfo;
9102  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9103  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9104  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9105  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9106  (*lp)->lpiitlim = INT_MAX;
9107  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9108  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9109  (*lp)->lpithreads = set->lp_threads;
9110  (*lp)->lpitiming = (int) set->time_clocktype;
9111  (*lp)->lpirandomseed = set->random_randomseed;
9112  (*lp)->storedsolvals = NULL;
9113 
9114  /* allocate arrays for diving */
9116 
9117  /* set default parameters in LP solver */
9118  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9119  if( !success )
9120  {
9121  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9122  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9124  }
9125  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9126  (*lp)->lpihasfeastol = success;
9127  if( !success )
9128  {
9129  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9130  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9132  }
9133  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9134  (*lp)->lpihasdualfeastol = success;
9135  if( !success )
9136  {
9137  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9138  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9140  }
9141  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9142  (*lp)->lpihasbarrierconvtol = success;
9143  if( !success )
9144  {
9145  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9146  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9148  }
9149  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9150  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9151  (*lp)->lpihasfastmip = success;
9152  if( !success )
9153  {
9154  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9155  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9157  }
9158  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9159  (*lp)->lpihasscaling = success;
9160  if( !success )
9161  {
9162  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9163  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9165  }
9166  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9167  (*lp)->lpihaspresolving = success;
9168  if( !success )
9169  {
9170  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9171  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9173  }
9174  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9175  if( !success )
9176  {
9177  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9178  "LP Solver <%s>: clock type cannot be set\n",
9180  }
9181  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9182  if( !success )
9183  {
9184  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9185  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9187  }
9188  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9189  if( !success )
9190  {
9191  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9192  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9194  }
9195  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9196  if( !success )
9197  {
9198  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9199  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9201  }
9202  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9203  (*lp)->lpihasrowrep = success;
9204  if( !success )
9205  {
9206  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9207  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9209  }
9210  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9211  (*lp)->lpihaspolishing = success;
9212  if( !success )
9213  {
9214  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9215  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9217  }
9218  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9219  (*lp)->lpihasrefactor = success;
9220  if( !success )
9221  {
9222  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9223  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9225  }
9226  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9227  if( !success )
9228  {
9229  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9230  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9232  }
9233  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9234  if( !success )
9235  {
9236  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9237  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9239  }
9240  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9241  if( (*lp)->lpirandomseed != 0 )
9242  {
9243  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9244  if( !success )
9245  {
9246  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9247  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9249  }
9250  }
9251 
9252  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9253  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9254  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9255  {
9256  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9257  return SCIP_PARAMETERWRONGVAL;
9258  }
9259 
9260  return SCIP_OKAY;
9261 }
9262 
9263 /** frees LP data object */
9265  SCIP_LP** lp, /**< pointer to LP data object */
9266  BMS_BLKMEM* blkmem, /**< block memory */
9267  SCIP_SET* set, /**< global SCIP settings */
9268  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9269  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9270  )
9271 {
9272  int i;
9273 
9274  assert(lp != NULL);
9275  assert(*lp != NULL);
9276 
9277  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9278 
9279  freeDiveChgSideArrays(*lp);
9280 
9281  /* release LPI rows */
9282  for( i = 0; i < (*lp)->nlpirows; ++i )
9283  {
9284  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9285  }
9286 
9287  if( (*lp)->lpi != NULL )
9288  {
9289  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9290  }
9291 
9292  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9293  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9294  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9295  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9296  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9297  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9298  BMSfreeMemoryArrayNull(&(*lp)->cols);
9299  BMSfreeMemoryArrayNull(&(*lp)->rows);
9300  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9301  BMSfreeMemory(lp);
9302 
9303  return SCIP_OKAY;
9304 }
9305 
9306 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9307  * changes to the LP solver
9308  */
9310  SCIP_LP* lp, /**< LP data */
9311  BMS_BLKMEM* blkmem, /**< block memory */
9312  SCIP_SET* set, /**< global SCIP settings */
9313  SCIP_STAT* stat, /**< problem statistics */
9314  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9315  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9316  )
9317 {
9318  assert(stat != NULL);
9319 
9320  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9321  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9322 
9323  /* mark the empty LP to be solved */
9325  lp->lpobjval = 0.0;
9326  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9327  lp->validfarkaslp = -1;
9328  lp->validsoldirlp = -1;
9329  lp->validsoldirsol = NULL;
9330  lp->solved = TRUE;
9331  lp->primalfeasible = TRUE;
9332  lp->primalchecked = TRUE;
9333  lp->dualfeasible = TRUE;
9334  lp->dualchecked = TRUE;
9335  lp->solisbasic = FALSE;
9337 
9338  return SCIP_OKAY;
9339 }
9340 
9341 /** adds a column to the LP */
9343  SCIP_LP* lp, /**< LP data */
9344  SCIP_SET* set, /**< global SCIP settings */
9345  SCIP_COL* col, /**< LP column */
9346  int depth /**< depth in the tree where the column addition is performed */
9347  )
9348 {
9349  assert(lp != NULL);
9350  assert(!lp->diving);
9351  assert(col != NULL);
9352  assert(col->len == 0 || col->rows != NULL);
9353  assert(col->lppos == -1);
9354  assert(col->var != NULL);
9355  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9356  assert(SCIPvarGetCol(col->var) == col);
9357  assert(SCIPvarIsIntegral(col->var) == col->integral);
9358 
9359  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9360 #ifdef SCIP_DEBUG
9361  {
9362  int i;
9363  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9364  for( i = 0; i < col->len; ++i )
9365  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9366  SCIPsetDebugMsgPrint(set, "\n");
9367  }
9368 #endif
9369 
9370  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9371  lp->cols[lp->ncols] = col;
9372  col->lppos = lp->ncols;
9373  col->lpdepth = depth;
9374  col->age = 0;
9375  lp->ncols++;
9376  if( col->removable )
9377  lp->nremovablecols++;
9378 
9379  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9380  {
9381  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9382  lp->lazycols[lp->nlazycols] = col;
9383  lp->nlazycols++;
9384  }
9385 
9386  /* mark the current LP unflushed */
9387  lp->flushed = FALSE;
9388 
9389  /* update column arrays of all linked rows */
9390  colUpdateAddLP(col, set);
9391 
9392  /* update the objective function vector norms */
9393  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9394 
9395  checkLinks(lp);
9396 
9397  return SCIP_OKAY;
9398 }
9399 
9400 /** adds a row to the LP and captures it */
9402  SCIP_LP* lp, /**< LP data */
9403  BMS_BLKMEM* blkmem, /**< block memory buffers */
9404  SCIP_SET* set, /**< global SCIP settings */
9405  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9406  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9407  SCIP_ROW* row, /**< LP row */
9408  int depth /**< depth in the tree where the row addition is performed */
9409  )
9410 {
9411  assert(lp != NULL);
9412  assert(row != NULL);
9413  assert(row->len == 0 || row->cols != NULL);
9414  assert(row->lppos == -1);
9415 
9416  SCIProwCapture(row);
9417  SCIProwLock(row);
9418 
9419  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9420 #ifdef SCIP_DEBUG
9421  {
9422  int i;
9423  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9424  for( i = 0; i < row->len; ++i )
9425  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9426  if( !SCIPsetIsZero(set, row->constant) )
9427  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9428  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9429  }
9430 #endif
9431 
9432  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9433  lp->rows[lp->nrows] = row;
9434  row->lppos = lp->nrows;
9435  row->lpdepth = depth;
9436  row->age = 0;
9437  lp->nrows++;
9438  if( row->removable )
9439  lp->nremovablerows++;
9440 
9441  /* mark the current LP unflushed */
9442  lp->flushed = FALSE;
9443 
9444  /* update row arrays of all linked columns */
9445  rowUpdateAddLP(row);
9446 
9447  checkLinks(lp);
9448 
9449  rowCalcNorms(row, set);
9450 
9451  /* check, if row addition to LP events are tracked
9452  * if so, issue ROWADDEDLP event
9453  */
9454  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9455  {
9456  SCIP_EVENT* event;
9457 
9458  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9459  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9460  }
9461 
9462  return SCIP_OKAY;
9463 }
9464 
9465 
9466 #ifndef NDEBUG
9467 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9468  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9469  * the lazycols array
9470  */
9471 static
9473  SCIP_LP* lp, /**< LP data */
9474  SCIP_SET* set /**< global SCIP settings */
9475  )
9476 {
9477  SCIP_Bool contained;
9478  int c;
9479  int i;
9480 
9481  assert(lp != NULL);
9482 
9483  /* check if each column in the lazy column array has a counter part in the column array */
9484  for( i = 0; i < lp->nlazycols; ++i )
9485  {
9486  /* check if each lazy column has at least on lazy bound */
9487  assert(lp->lazycols[i] != NULL);
9488  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9489 
9490  contained = FALSE;
9491  for( c = 0; c < lp->ncols; ++c )
9492  {
9493  if( lp->lazycols[i] == lp->cols[c] )
9494  {
9495  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9496  contained = TRUE;
9497  }
9498  }
9499  assert(contained);
9500  }
9501 
9502  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9503  * array */
9504  for( c = 0; c < lp->ncols; ++c )
9505  {
9506  contained = FALSE;
9507  assert(lp->cols[c] != NULL);
9508 
9509  for( i = 0; i < lp->nlazycols; ++i )
9510  {
9511  if( lp->lazycols[i] == lp->cols[c] )
9512  {
9513  contained = TRUE;
9514  }
9515  }
9516 
9517  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9518  }
9519 }
9520 #else
9521 #define checkLazyColArray(lp, set) /**/
9522 #endif
9523 
9524 /** removes all columns after the given number of cols from the LP */
9526  SCIP_LP* lp, /**< LP data */
9527  SCIP_SET* set, /**< global SCIP settings */
9528  int newncols /**< new number of columns in the LP */
9529  )
9530 {
9531  SCIP_COL* col;
9532  int c;
9533 
9534  assert(lp != NULL);
9535 
9536  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9537  assert(0 <= newncols);
9538  assert(newncols <= lp->ncols);
9539 
9540  if( newncols < lp->ncols )
9541  {
9542  assert(!lp->diving);
9543 
9544  for( c = lp->ncols-1; c >= newncols; --c )
9545  {
9546  col = lp->cols[c];
9547  assert(col != NULL);
9548  assert(col->len == 0 || col->rows != NULL);
9549  assert(col->var != NULL);
9550  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9551  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9552  assert(col->lppos == c);
9553 
9554  /* mark column to be removed from the LP */
9555  col->lppos = -1;
9556  col->lpdepth = -1;
9557  lp->ncols--;
9558 
9559  /* count removable columns */
9560  if( col->removable )
9561  lp->nremovablecols--;
9562 
9563  /* update column arrays of all linked rows */
9564  colUpdateDelLP(col, set);
9565 
9566  /* update the objective function vector norms */
9567  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9568  }
9569  assert(lp->ncols == newncols);
9570  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9571 
9572  /* remove columns which are deleted from the lazy column array */
9573  c = 0;
9574  while( c < lp->nlazycols )
9575  {
9576  if( lp->lazycols[c]->lppos < 0 )
9577  {
9578  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9579  lp->nlazycols--;
9580  }
9581  else
9582  c++;
9583  }
9584 
9585  /* mark the current LP unflushed */
9586  lp->flushed = FALSE;
9587 
9588  checkLazyColArray(lp, set);
9589  checkLinks(lp);
9590  }
9591  assert(lp->nremovablecols <= lp->ncols);
9592 
9593  return SCIP_OKAY;
9594 }
9595 
9596 /** removes and releases all rows after the given number of rows from the LP */
9598  SCIP_LP* lp, /**< LP data */
9599  BMS_BLKMEM* blkmem, /**< block memory */
9600  SCIP_SET* set, /**< global SCIP settings */
9601  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9602  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9603  int newnrows /**< new number of rows in the LP */
9604  )
9605 {
9606  SCIP_ROW* row;
9607  int r;
9608 
9609  assert(lp != NULL);
9610  assert(0 <= newnrows && newnrows <= lp->nrows);
9611 
9612  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9613  if( newnrows < lp->nrows )
9614  {
9615  for( r = lp->nrows-1; r >= newnrows; --r )
9616  {
9617  row = lp->rows[r];
9618  assert(row != NULL);
9619  assert(row->len == 0 || row->cols != NULL);
9620  assert(row->lppos == r);
9621 
9622  /* mark row to be removed from the LP */
9623  row->lppos = -1;
9624  row->lpdepth = -1;
9625  lp->nrows--;
9626 
9627  /* count removable rows */
9628  if( row->removable )
9629  lp->nremovablerows--;
9630 
9631  /* update row arrays of all linked columns */
9632  rowUpdateDelLP(row);
9633 
9634  SCIProwUnlock(lp->rows[r]);
9635 
9636  /* check, if row deletion events are tracked
9637  * if so, issue ROWDELETEDLP event
9638  */
9639  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9640  {
9641  SCIP_EVENT* event;
9642 
9643  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9644  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9645  }
9646 
9647  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9648  }
9649  assert(lp->nrows == newnrows);
9650  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9651 
9652  /* mark the current LP unflushed */
9653  lp->flushed = FALSE;
9654 
9655  checkLinks(lp);
9656  }
9657  assert(lp->nremovablerows <= lp->nrows);
9658 
9659  return SCIP_OKAY;
9660 }
9661 
9662 /** removes all columns and rows from LP, releases all rows */
9664  SCIP_LP* lp, /**< LP data */
9665  BMS_BLKMEM* blkmem, /**< block memory */
9666  SCIP_SET* set, /**< global SCIP settings */
9667  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9668  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9669  )
9670 {
9671  assert(lp != NULL);
9672  assert(!lp->diving);
9673 
9674  SCIPsetDebugMsg(set, "clearing LP\n");
9675  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9676  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9677 
9678  return SCIP_OKAY;
9679 }
9680 
9681 /** remembers number of columns and rows to track the newly added ones */
9683  SCIP_LP* lp /**< current LP data */
9684  )
9685 {
9686  assert(lp != NULL);
9687  assert(!lp->diving);
9688 
9689  lp->firstnewrow = lp->nrows;
9690  lp->firstnewcol = lp->ncols;
9691 }
9692 
9693 /** sets the remembered number of columns and rows to the given values */
9695  SCIP_LP* lp, /**< current LP data */
9696  int nrows, /**< number of rows to set the size marker to */
9697  int ncols /**< number of columns to set the size marker to */
9698  )
9699 {
9700  assert(lp != NULL);
9701  assert(!lp->diving);
9702 
9703  lp->firstnewrow = nrows;
9704  lp->firstnewcol = ncols;
9705 }
9706 
9707 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9709  SCIP_LP* lp, /**< LP data */
9710  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9711  )
9712 {
9713  assert(lp != NULL);
9714  assert(lp->flushed);
9715  assert(lp->solved);
9716  assert(lp->solisbasic);
9717  assert(basisind != NULL);
9718 
9719  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9720 
9721  return SCIP_OKAY;
9722 }
9723 
9724 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9726  SCIP_LP* lp, /**< LP data */
9727  int* cstat, /**< array to store column basis status, or NULL */
9728  int* rstat /**< array to store row basis status, or NULL */
9729  )
9730 {
9731  assert(lp != NULL);
9732  assert(lp->flushed);
9733  assert(lp->solved);
9734  assert(lp->solisbasic);
9735 
9736  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9737 
9738  return SCIP_OKAY;
9739 }
9740 
9741 /** gets a row from the inverse basis matrix B^-1 */
9743  SCIP_LP* lp, /**< LP data */
9744  int r, /**< row number */
9745  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9746  int* inds, /**< array to store the non-zero indices, or NULL */
9747  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9748  * (-1: if we do not store sparsity informations) */
9749  )
9750 {
9751  assert(lp != NULL);
9752  assert(lp->flushed);
9753  assert(lp->solved);
9754  assert(lp->solisbasic);
9755  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9756  assert(coef != NULL);
9757 
9758  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9759 
9760  return SCIP_OKAY;
9761 }
9762 
9763 /** gets a column from the inverse basis matrix B^-1 */
9765  SCIP_LP* lp, /**< LP data */
9766  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9767  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9768  * to get the array which links the B^-1 column numbers to the row and
9769  * column numbers of the LP! c must be between 0 and nrows-1, since the
9770  * basis has the size nrows * nrows */
9771  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9772  int* inds, /**< array to store the non-zero indices, or NULL */
9773  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9774  * (-1: if we do not store sparsity informations) */
9775  )
9776 {
9777  assert(lp != NULL);
9778  assert(lp->flushed);
9779  assert(lp->solved);
9780  assert(lp->solisbasic);
9781  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9782  assert(coef != NULL);
9783 
9784  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9785 
9786  return SCIP_OKAY;
9787 }
9788 
9789 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9791  SCIP_LP* lp, /**< LP data */
9792  int r, /**< row number */
9793  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9794  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9795  int* inds, /**< array to store the non-zero indices, or NULL */
9796  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9797  * (-1: if we do not store sparsity informations) */
9798  )
9799 {
9800  assert(lp != NULL);
9801  assert(lp->flushed);
9802  assert(lp->solved);
9803  assert(lp->solisbasic);
9804  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9805  assert(coef != NULL);
9806 
9807  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9808 
9809  return SCIP_OKAY;
9810 }
9811 
9812 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9813  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9814  */
9816  SCIP_LP* lp, /**< LP data */
9817  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9818  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9819  int* inds, /**< array to store the non-zero indices, or NULL */
9820  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9821  * (-1: if we do not store sparsity informations) */
9822  )
9823 {
9824  assert(lp != NULL);
9825  assert(lp->flushed);
9826  assert(lp->solved);
9827  assert(lp->solisbasic);
9828  assert(0 <= c && c < lp->ncols);
9829  assert(coef != NULL);
9830 
9831  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9832 
9833  return SCIP_OKAY;
9834 }
9835 
9836 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9837  * LP row are swapped in the summation
9838  */
9840  SCIP_LP* lp, /**< LP data */
9841  SCIP_SET* set, /**< global SCIP settings */
9842  SCIP_PROB* prob, /**< problem data */
9843  SCIP_Real* weights, /**< row weights in row summation */
9844  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9845  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9846  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9847  )
9848 {
9849  SCIP_ROW* row;
9850  int r;
9851  int i;
9852  int idx;
9853  SCIP_Bool lhsinfinite;
9854  SCIP_Bool rhsinfinite;
9855 
9856  assert(lp != NULL);
9857  assert(prob != NULL);
9858  assert(weights != NULL);
9859  assert(sumcoef != NULL);
9860  assert(sumlhs != NULL);
9861  assert(sumrhs != NULL);
9862 
9863  /**@todo test, if a column based summation is faster */
9864 
9865  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9866  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9867  *sumlhs = 0.0;
9868  *sumrhs = 0.0;
9869  lhsinfinite = FALSE;
9870  rhsinfinite = FALSE;
9871  for( r = 0; r < lp->nrows; ++r )
9872  {
9873  if( !SCIPsetIsZero(set, weights[r]) )
9874  {
9875  row = lp->rows[r];
9876  assert(row != NULL);
9877  assert(row->len == 0 || row->cols != NULL);
9878  assert(row->len == 0 || row->cols_index != NULL);
9879  assert(row->len == 0 || row->vals != NULL);
9880 
9881  /* add the row coefficients to the sum */
9882  for( i = 0; i < row->len; ++i )
9883  {
9884  assert(row->cols[i] != NULL);
9885  assert(row->cols[i]->var != NULL);
9886  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9887  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9888  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9889  idx = row->cols[i]->var_probindex;
9890  assert(0 <= idx && idx < prob->nvars);
9891  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9892  }
9893 
9894  /* add the row sides to the sum, depending on the sign of the weight */
9895  if( weights[r] > 0.0 )
9896  {
9897  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9898  if( !lhsinfinite )
9899  (*sumlhs) += weights[r] * (row->lhs - row->constant);
9900  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9901  if( !rhsinfinite )
9902  (*sumrhs) += weights[r] * (row->rhs - row->constant);
9903  }
9904  else
9905  {
9906  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
9907  if( !lhsinfinite )
9908  (*sumlhs) += weights[r] * (row->rhs - row->constant);
9909  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
9910  if( !rhsinfinite )
9911  (*sumrhs) += weights[r] * (row->lhs - row->constant);
9912  }
9913  }
9914  }
9915 
9916  if( lhsinfinite )
9917  *sumlhs = -SCIPsetInfinity(set);
9918  if( rhsinfinite )
9919  *sumrhs = SCIPsetInfinity(set);
9920 
9921  return SCIP_OKAY;
9922 }
9923 
9924 /** stores LP state (like basis information) into LP state object */
9926  SCIP_LP* lp, /**< LP data */
9927  BMS_BLKMEM* blkmem, /**< block memory */
9928  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9929  )
9930 {
9931  assert(lp != NULL);
9932  assert(lp->flushed);
9933  assert(lp->solved);
9934  assert(blkmem != NULL);
9935  assert(lpistate != NULL);
9936 
9937  /* check whether there is no lp */
9938  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
9939  *lpistate = NULL;
9940  else
9941  {
9942  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
9943  }
9944 
9945  return SCIP_OKAY;
9946 }
9947 
9948 /** loads LP state (like basis information) into solver */
9950  SCIP_LP* lp, /**< LP data */
9951  BMS_BLKMEM* blkmem, /**< block memory */
9952  SCIP_SET* set, /**< global SCIP settings */
9953  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9954  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
9955  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
9956  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
9957  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
9958  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
9959  )
9960 {
9961  assert(lp != NULL);
9962  assert(blkmem != NULL);
9963 
9964  /* flush changes to the LP solver */
9965  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
9966  assert(lp->flushed);
9967 
9968  if( lp->solved && lp->solisbasic )
9969  return SCIP_OKAY;
9970 
9971  /* set LPI state in the LP solver */
9972  if( lpistate == NULL )
9973  lp->solisbasic = FALSE;
9974  else
9975  {
9976  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
9977  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
9978  }
9979  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
9980  * flushed and solved, also, e.g., when we hit the iteration limit
9981  */
9982  lp->primalfeasible = wasprimfeas;
9983  lp->primalchecked = wasprimchecked;
9984  lp->dualfeasible = wasdualfeas;
9985  lp->dualchecked = wasdualchecked;
9986 
9987  return SCIP_OKAY;
9988 }
9989 
9990 /** frees LP state information */
9992  SCIP_LP* lp, /**< LP data */
9993  BMS_BLKMEM* blkmem, /**< block memory */
9994  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
9995  )
9996 {
9997  assert(lp != NULL);
9998 
9999  if( *lpistate != NULL )
10000  {
10001  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10002  }
10003 
10004  return SCIP_OKAY;
10005 }
10006 
10007 /** stores pricing norms into LP norms object */
10009  SCIP_LP* lp, /**< LP data */
10010  BMS_BLKMEM* blkmem, /**< block memory */
10011  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10012  )
10013 {
10014  assert(lp != NULL);
10015  assert(lp->flushed);
10016  assert(lp->solved);
10017  assert(blkmem != NULL);
10018  assert(lpinorms != NULL);
10019 
10020  /* check whether there is no lp */
10021  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10022  *lpinorms = NULL;
10023  else
10024  {
10025  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10026  }
10027 
10028  return SCIP_OKAY;
10029 }
10030 
10031 /** loads pricing norms from LP norms object into solver */
10033  SCIP_LP* lp, /**< LP data */
10034  BMS_BLKMEM* blkmem, /**< block memory */
10035  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10036  )
10037 {
10038  assert(lp != NULL);
10039  assert(blkmem != NULL);
10040  assert(lp->flushed);
10041 
10042  /* set LPI norms in the LP solver */
10043  if( lpinorms != NULL )
10044  {
10045  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10046  }
10047 
10048  return SCIP_OKAY;
10049 }
10050 
10051 /** frees pricing norms information */
10053  SCIP_LP* lp, /**< LP data */
10054  BMS_BLKMEM* blkmem, /**< block memory */
10055  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10056  )
10057 {
10058  assert(lp != NULL);
10059 
10060  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10061 
10062  return SCIP_OKAY;
10063 }
10064 
10065 /** return the current cutoff bound of the lp */
10067  SCIP_LP* lp /**< current LP data */
10068  )
10069 {
10070  assert(lp != NULL);
10071 
10072  return lp->cutoffbound;
10073 }
10074 
10075 /** sets the upper objective limit of the LP solver */
10077  SCIP_LP* lp, /**< current LP data */
10078  SCIP_SET* set, /**< global SCIP settings */
10079  SCIP_PROB* prob, /**< problem data */
10080  SCIP_Real cutoffbound /**< new upper objective limit */
10081  )
10082 {
10083  assert(lp != NULL);
10084 
10085  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10086 
10087  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10088  * in SCIPendDive())
10089  */
10090  if( SCIPlpDivingObjChanged(lp) )
10091  {
10092  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10093  return SCIP_OKAY;
10094  }
10095 
10096  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10097  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10098  {
10099  /* mark the current solution invalid */
10100  lp->solved = FALSE;
10101  lp->lpobjval = SCIP_INVALID;
10103  }
10104  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10105  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10106  */
10108  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10109  {
10110  assert(lp->flushed);
10111  assert(lp->solved);
10113  }
10114 
10115  lp->cutoffbound = cutoffbound;
10116 
10117  return SCIP_OKAY;
10118 }
10119 
10120 /** returns the name of the given LP algorithm */
10121 static
10122 const char* lpalgoName(
10123  SCIP_LPALGO lpalgo /**< LP algorithm */
10124  )
10125 {
10126  switch( lpalgo )
10127  {
10129  return "primal simplex";
10131  return "dual simplex";
10132  case SCIP_LPALGO_BARRIER:
10133  return "barrier";
10135  return "barrier/crossover";
10136  default:
10137  SCIPerrorMessage("invalid LP algorithm\n");
10138  SCIPABORT();
10139  return "invalid"; /*lint !e527*/
10140  }
10141 }
10142 
10143 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10144 static
10146  SCIP_LP* lp, /**< current LP data */
10147  SCIP_SET* set, /**< global SCIP settings */
10148  SCIP_STAT* stat, /**< problem statistics */
10149  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10150  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10151  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10152  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10153  )
10154 {
10155  SCIP_Real timedelta;
10156  SCIP_RETCODE retcode;
10157  int iterations;
10158 
10159  assert(lp != NULL);
10160  assert(lp->flushed);
10161  assert(set != NULL);
10162  assert(stat != NULL);
10163  assert(lperror != NULL);
10164 
10165  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",
10166  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10167 
10168  *lperror = FALSE;
10169 
10170 #if 0 /* for debugging: write all root node LP's */
10171  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10172  {
10173  char fname[SCIP_MAXSTRLEN];
10174  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10175  SCIP_CALL( SCIPlpWrite(lp, fname) );
10176  SCIPsetDebugMsg("wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10177  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10178  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10179  }
10180 #endif
10181 
10182  /* start timing */
10183  if( lp->diving || lp->probing )
10184  {
10185  if( lp->strongbranchprobing )
10186  SCIPclockStart(stat->strongbranchtime, set);
10187  else
10188  SCIPclockStart(stat->divinglptime, set);
10189 
10190  timedelta = 0.0; /* unused for diving or probing */
10191  }
10192  else
10193  {
10194  SCIPclockStart(stat->primallptime, set);
10195  timedelta = -SCIPclockGetTime(stat->primallptime);
10196  }
10197 
10198  /* if this is a call to resolve an instable LP, collect time */
10199  if( instable )
10200  {
10202  }
10203 
10204  /* call primal simplex */
10205  retcode = SCIPlpiSolvePrimal(lp->lpi);
10206  if( retcode == SCIP_LPERROR )
10207  {
10208  *lperror = TRUE;
10209  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10210  }
10211  else
10212  {
10213  SCIP_CALL( retcode );
10214  }
10216  lp->solisbasic = TRUE;
10217 
10218  /* stop timing */
10219  if( lp->diving || lp->probing )
10220  {
10221  if( lp->strongbranchprobing )
10222  SCIPclockStop(stat->strongbranchtime, set);
10223  else
10224  SCIPclockStop(stat->divinglptime, set);
10225  }
10226  else
10227  {
10228  timedelta += SCIPclockGetTime(stat->primallptime);
10229  SCIPclockStop(stat->primallptime, set);
10230  }
10231 
10232  if ( instable )
10233  {
10235  }
10236 
10237  /* count number of iterations */
10238  SCIPstatIncrement(stat, set, lpcount);
10239  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10240  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10241  {
10242  if( !lp->strongbranchprobing )
10243  {
10244  SCIPstatIncrement(stat, set, nlps);
10245  SCIPstatAdd( stat, set, nlpiterations, iterations );
10246  }
10247  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10248  {
10249  SCIPstatIncrement(stat, set, nprimalresolvelps );
10250  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10251  }
10252  if ( instable )
10253  {
10254  SCIPstatIncrement(stat, set, nresolveinstablelps);
10255  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10256  }
10257  if( lp->diving || lp->probing )
10258  {
10259  if( lp->strongbranchprobing )
10260  {
10261  SCIPstatIncrement(stat, set, nsbdivinglps);
10262  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10263  }
10264  else
10265  {
10266  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10267  SCIPstatIncrement(stat, set, ndivinglps);
10268  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10269  }
10270  }
10271  else
10272  {
10273  SCIPstatIncrement(stat, set, nprimallps);
10274  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10275  }
10276  }
10277  else
10278  {
10279  if ( ! lp->diving && ! lp->probing )
10280  {
10281  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10282  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10283  }
10284 
10285  if ( keepsol && !(*lperror) )
10286  {
10287  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10288  if( lp->validsollp == stat->lpcount-1 )
10289  lp->validsollp = stat->lpcount;
10290  if( lp->validfarkaslp == stat->lpcount-1 )
10291  lp->validfarkaslp = stat->lpcount;
10292  }
10293  }
10294 
10295  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10296  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10297 
10298  return SCIP_OKAY;
10299 }
10300 
10301 /** calls LPI to perform dual simplex, measures time and counts iterations */
10302 static
10304  SCIP_LP* lp, /**< current LP data */
10305  SCIP_SET* set, /**< global SCIP settings */
10306  SCIP_STAT* stat, /**< problem statistics */
10307  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10308  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10309  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10310  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10311  )
10312 {
10313  SCIP_Real timedelta;
10314  SCIP_RETCODE retcode;
10315  int iterations;
10316 
10317  assert(lp != NULL);
10318  assert(lp->flushed);
10319  assert(set != NULL);
10320  assert(stat != NULL);
10321  assert(lperror != NULL);
10322 
10323  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",
10324  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10325 
10326  *lperror = FALSE;
10327 
10328 #if 0 /* for debugging: write all root node LP's */
10329  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10330  {
10331  char fname[SCIP_MAXSTRLEN];
10332  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10333  SCIP_CALL( SCIPlpWrite(lp, fname) );
10334  SCIPsetDebugMsg("wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10335  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10336  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10337  }
10338 #endif
10339 
10340  /* start timing */
10341  if( lp->diving || lp->probing )
10342  {
10343  if( lp->strongbranchprobing )
10344  SCIPclockStart(stat->strongbranchtime, set);
10345  else
10346  SCIPclockStart(stat->divinglptime, set);
10347 
10348  timedelta = 0.0; /* unused for diving or probing */
10349  }
10350  else
10351  {
10352  SCIPclockStart(stat->duallptime, set);
10353  timedelta = -SCIPclockGetTime(stat->duallptime);
10354  }
10355 
10356  /* if this is a call to resolve an instable LP, collect time */
10357  if ( instable )
10358  {
10360  }
10361 
10362  /* call dual simplex */
10363  retcode = SCIPlpiSolveDual(lp->lpi);
10364  if( retcode == SCIP_LPERROR )
10365  {
10366  *lperror = TRUE;
10367  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10368  }
10369  else
10370  {
10371  SCIP_CALL( retcode );
10372  }
10374  lp->solisbasic = TRUE;
10375 
10376  /* stop timing */
10377  if( lp->diving || lp->probing )
10378  {
10379  if( lp->strongbranchprobing )
10380  SCIPclockStop(stat->strongbranchtime, set);
10381  else
10382  SCIPclockStop(stat->divinglptime, set);
10383  }
10384  else
10385  {
10386  timedelta += SCIPclockGetTime(stat->duallptime);
10387  SCIPclockStop(stat->duallptime, set);
10388  }
10389 
10390  if ( instable )
10391  {
10393  }
10394 
10395  /* count number of iterations */
10396  SCIPstatIncrement(stat, set, lpcount);
10397  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10398  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10399  {
10400  if( !lp->strongbranchprobing )
10401  {
10402  SCIPstatIncrement(stat, set, nlps);
10403  SCIPstatAdd(stat, set, nlpiterations, iterations);
10404  }
10405  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10406  {
10407  SCIPstatIncrement(stat, set, ndualresolvelps);
10408  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10409  }
10410  if ( instable )
10411  {
10412  SCIPstatIncrement(stat, set, nresolveinstablelps);
10413  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10414  }
10415  if( lp->diving || lp->probing )
10416  {
10417  if( lp->strongbranchprobing )
10418  {
10419  SCIPstatIncrement(stat, set, nsbdivinglps);
10420  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10421  }
10422  else
10423  {
10424  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10425  SCIPstatIncrement(stat, set, ndivinglps);
10426  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10427  }
10428  }
10429  else
10430  {
10431  SCIPstatIncrement(stat, set, nduallps);
10432  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10433  }
10434  }
10435  else
10436  {
10437  if ( ! lp->diving && ! lp->probing )
10438  {
10439  SCIPstatIncrement(stat, set, ndualzeroitlps);
10440  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10441  }
10442 
10443  if( keepsol && !(*lperror) )
10444  {
10445  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10446  if( lp->validsollp == stat->lpcount-1 )
10447  lp->validsollp = stat->lpcount;
10448  if( lp->validfarkaslp == stat->lpcount-1 )
10449  lp->validfarkaslp = stat->lpcount;
10450  }
10451  }
10452 
10453  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10454  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10455 
10456  return SCIP_OKAY;
10457 }
10458 
10459 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10460  *
10461  * We follow the approach of the following paper to find a lexicographically minimal optimal
10462  * solution:
10463  *
10464  * Zanette, Fischetti, Balas@n
10465  * Can pure cutting plane algorithms work?@n
10466  * IPCO 2008, Bertinoro, Italy.
10467  *
10468  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10469  * heuristic, i.e., we limit the number of components which are minimized.
10470  *
10471  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10472  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10473  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10474  * pivots that will not change the objective are allowed afterwards.
10475  *
10476  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10477  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10478  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10479  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10480  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10481  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10482  * reduced cost. We then choose the next variable and iterate.
10483  *
10484  * We stop the process once we do not find candidates or have performed a maximum number of
10485  * iterations.
10486  *
10487  * @todo Does this really produce a lexicographically minimal solution?
10488  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10489  * guarantee that these variables will not be changed in later stages? We can fix these variables
10490  * to their lower bound, but this destroys the basis.
10491  * @todo Should we use lexicographical minimization in diving/probing or not?
10492  */
10493 static
10495  SCIP_LP* lp, /**< current LP data */
10496  SCIP_SET* set, /**< global SCIP settings */
10497  SCIP_STAT* stat, /**< problem statistics */
10498  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10499  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10500  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10501  )
10502 {
10503  SCIP_Real timedelta;
10504  SCIP_RETCODE retcode;
10505  int totalIterations;
10506  int lexIterations;
10507  int iterations;
10508  int rounds;
10509 
10510  assert(lp != NULL);
10511  assert(lp->flushed);
10512  assert(set != NULL);
10513  assert(stat != NULL);
10514  assert(lperror != NULL);
10515 
10516  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",
10517  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10518 
10519  *lperror = FALSE;
10520 
10521  /* start timing */
10522  if( lp->diving || lp->probing )
10523  {
10524  if( lp->strongbranchprobing )
10525  SCIPclockStart(stat->strongbranchtime, set);
10526  else
10527  SCIPclockStart(stat->divinglptime, set);
10528 
10529  timedelta = 0.0; /* unused for diving or probing */
10530  }
10531  else
10532  {
10533  SCIPclockStart(stat->duallptime, set);
10534  timedelta = -SCIPclockGetTime(stat->duallptime);
10535  }
10536 
10537  /* call dual simplex for first lp */
10538  retcode = SCIPlpiSolveDual(lp->lpi);
10539  if( retcode == SCIP_LPERROR )
10540  {
10541  *lperror = TRUE;
10542  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10543  }
10544  else
10545  {
10546  SCIP_CALL( retcode );
10547  }
10548  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10549  totalIterations = iterations;
10550 
10551  /* stop timing */
10552  if( lp->diving || lp->probing )
10553  {
10554  if( lp->strongbranchprobing )
10555  SCIPclockStop(stat->strongbranchtime, set);
10556  else
10557  SCIPclockStop(stat->divinglptime, set);
10558  }
10559  else
10560  {
10561  timedelta += SCIPclockGetTime(stat->duallptime);
10562  SCIPclockStop(stat->duallptime, set);
10563  }
10564 
10565  /* count number of iterations */
10566  SCIPstatIncrement(stat, set, lpcount);
10567  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10568  {
10569  if( lp->strongbranchprobing )
10570  {
10571  SCIPstatAdd(stat, set, nlpiterations, iterations);
10572  }
10573  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10574  {
10575  SCIPstatIncrement(stat, set, ndualresolvelps);
10576  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10577  }
10578  if( lp->diving || lp->probing )
10579  {
10580  if( lp->strongbranchprobing )
10581  {
10582  SCIPstatIncrement(stat, set, nsbdivinglps);
10583  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10584  }
10585  else
10586  {
10587  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10588  SCIPstatIncrement(stat, set, ndivinglps);
10589  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10590  }
10591  }
10592  else
10593  {
10594  SCIPstatIncrement(stat, set, nduallps);
10595  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10596  }
10597  }
10598  else
10599  {
10600  if ( ! lp->diving && ! lp->probing )
10601  {
10602  SCIPstatIncrement(stat, set, ndualzeroitlps);
10603  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10604  }
10605  }
10606  lexIterations = 0;
10607 
10608  /* search for lexicographically minimal optimal solution */
10609  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10610  {
10611  SCIP_Bool chooseBasic;
10612  SCIP_Real* primsol;
10613  SCIP_Real* dualsol;
10614  SCIP_Real* redcost;
10615  int* cstat;
10616  int* rstat;
10617  SCIP_Real* newobj;
10618  SCIP_Real* newlb;
10619  SCIP_Real* newub;
10620  SCIP_Real* newlhs;
10621  SCIP_Real* newrhs;
10622  SCIP_Real* oldlb;
10623  SCIP_Real* oldub;
10624  SCIP_Real* oldlhs;
10625  SCIP_Real* oldrhs;
10626  SCIP_Real* oldobj;
10627  SCIP_Bool* fixedc;
10628  SCIP_Bool* fixedr;
10629  int* indcol;
10630  int* indrow;
10631  int* indallcol;
10632  int* indallrow;
10633  int nDualDeg;
10634  int r, c;
10635  int cntcol;
10636  int cntrow;
10637  int nruns;
10638  int pos;
10639 
10640  chooseBasic = set->lp_lexdualbasic;
10641 
10642  /* start timing */
10643  SCIPclockStart(stat->lexduallptime, set);
10644 
10645  /* get all solution information */
10646  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10647  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10648  if( chooseBasic )
10649  {
10650  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10651  }
10652  else
10653  primsol = NULL;
10654 
10655  /* get basic and nonbasic information */
10656  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10657  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10658 
10659  /* save bounds, lhs/rhs, and objective */
10660  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10661  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10662  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10663  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10664  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10665  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10666  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10667  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10668 
10669  /* get storage for several arrays */
10670  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10671  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10672  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10673 
10674  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10675  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10676  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10677 
10678  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10679  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10680 
10681  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10682  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10683 
10684  /* initialize: set objective to 0, get fixed variables */
10685  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10686  for( c = 0; c < lp->nlpicols; ++c )
10687  {
10688  newobj[c] = 0.0;
10689  indallcol[c] = c;
10690  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10691  fixedc[c] = TRUE;
10692  else
10693  fixedc[c] = FALSE;
10694  }
10695 
10696  /* initialize: get fixed slack variables */
10697  for( r = 0; r < lp->nlpirows; ++r )
10698  {
10699  indallrow[r] = r;
10700  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10701  fixedr[r] = TRUE;
10702  else
10703  fixedr[r] = FALSE;
10704  }
10705 
10706 #ifdef DEBUG_LEXDUAL
10707  {
10708  int j;
10709 
10710  if( !chooseBasic )
10711  {
10712  assert(primsol == NULL);
10713  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10714  }
10715  assert(primsol != NULL);
10716  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10717  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10718 
10719  for( j = 0; j < lp->nlpicols; ++j )
10720  {
10721  if( fixedc[j] )
10722  {
10723  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10724  }
10725  else
10726  {
10727  char type;
10728  switch( (SCIP_BASESTAT) cstat[j] )
10729  {
10730  case SCIP_BASESTAT_LOWER:
10731  type = 'l';
10732  break;
10733  case SCIP_BASESTAT_UPPER:
10734  type = 'u';
10735  break;
10736  case SCIP_BASESTAT_ZERO:
10737  type = 'z';
10738  break;
10739  case SCIP_BASESTAT_BASIC:
10740  type = 'b';
10741  break;
10742  default:
10743  type = '?';
10744  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10745  SCIPABORT();
10746  }
10747  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10748  }
10749  }
10750  SCIPsetDebugMsg(set, "\n\n");
10751 
10752  if( !chooseBasic )
10753  {
10754  SCIPsetFreeBufferArray(set, &primsol);
10755  assert(primsol == NULL);
10756  }
10757  }
10758 #endif
10759 
10760  /* perform lexicographic rounds */
10761  pos = -1;
10762  nruns = 0;
10763  rounds = 0;
10764  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10765  do
10766  {
10767  int oldpos;
10768 
10769  /* get current solution */
10770  if( chooseBasic )
10771  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10772  else
10773  {
10774  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10775  assert(primsol == NULL);
10776  }
10777 
10778  /* get current basis */
10779  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10780 
10781  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10782  nDualDeg = 0;
10783  cntcol = 0;
10784  oldpos = pos;
10785  pos = -1;
10786  for( c = 0; c < lp->nlpicols; ++c )
10787  {
10788  if( !fixedc[c] )
10789  {
10790  /* check whether variable is in basis */
10791  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10792  {
10793  /* store first candidate */
10794  if( pos == -1 && c > oldpos )
10795  {
10796  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10797  pos = c;
10798  }
10799  }
10800  else
10801  {
10802  /* reduced cost == 0 -> possible candidate */
10803  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10804  {
10805  ++nDualDeg;
10806  /* only if we have not yet found a candidate */
10807  if( pos == -1 && c > oldpos )
10808  {
10809  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10810  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10811  {
10812  newlb[cntcol] = oldlb[c];
10813  newub[cntcol] = oldlb[c];
10814  indcol[cntcol++] = c;
10815  fixedc[c] = TRUE;
10816  }
10817  else /* found a non-fixed candidate */
10818  {
10819  if( !chooseBasic )
10820  pos = c;
10821  }
10822  }
10823  }
10824  else
10825  {
10826  /* nonzero reduced cost -> variable can be fixed */
10827  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10828  {
10829  newlb[cntcol] = oldlb[c];
10830  newub[cntcol] = oldlb[c];
10831  }
10832  else
10833  {
10834  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
10835  {
10836  newlb[cntcol] = oldub[c];
10837  newub[cntcol] = oldub[c];
10838  }
10839  else
10840  {
10841  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
10842  newlb[cntcol] = 0.0;
10843  newub[cntcol] = 0.0;
10844  }
10845  }
10846  indcol[cntcol++] = c;
10847  fixedc[c] = TRUE;
10848  }
10849  }
10850  }
10851  }
10852 
10853  /* check rows */
10854  cntrow = 0;
10855  for( r = 0; r < lp->nlpirows; ++r )
10856  {
10857  if( !fixedr[r] )
10858  {
10859  /* consider only nonbasic rows */
10860  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
10861  {
10862  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
10863  if( SCIPsetIsFeasZero(set, dualsol[r]) )
10864  ++nDualDeg;
10865  else
10866  {
10867  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
10868  {
10869  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
10870  newlhs[cntrow] = oldlhs[r];
10871  newrhs[cntrow] = oldlhs[r];
10872  }
10873  else
10874  {
10875  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
10876  newlhs[cntrow] = oldrhs[r];
10877  newrhs[cntrow] = oldrhs[r];
10878  }
10879  indrow[cntrow++] = r;
10880  fixedr[r] = TRUE;
10881  }
10882  }
10883  }
10884  }
10885 
10886  if( nDualDeg > 0 && pos >= 0 )
10887  {
10888  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
10889 
10890  /* change objective */
10891  if( nruns == 0 )
10892  {
10893  /* set objective to appropriate unit vector for first run */
10894  newobj[pos] = 1.0;
10895  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
10896  }
10897  else
10898  {
10899  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
10900  SCIP_Real obj = 1.0;
10901  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
10902  }
10903 
10904  /* fix variables */
10905  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
10906  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
10907 
10908  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
10909  retcode = SCIPlpiSolvePrimal(lp->lpi);
10910  if( retcode == SCIP_LPERROR )
10911  {
10912  *lperror = TRUE;
10913  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10914  }
10915  else
10916  {
10917  SCIP_CALL( retcode );
10918  }
10919  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10920  lexIterations += iterations;
10921 
10922 #ifdef DEBUG_LEXDUAL
10923  if( iterations > 0 )
10924  {
10925  int j;
10926 
10927  if( !chooseBasic )
10928  {
10929  assert(primsol == NULL);
10930  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10931  }
10932  assert(primsol != NULL);
10933  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10934 
10935  for( j = 0; j < lp->nlpicols; ++j )
10936  {
10937  if( fixedc[j] )
10938  {
10939  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10940  }
10941  else
10942  {
10943  char cstart = '[';
10944  char cend = ']';
10945  char type;
10946 
10947  if(j == pos)
10948  {
10949  cstart = '*';
10950  cend = '*';
10951  }
10952 
10953  switch( (SCIP_BASESTAT) cstat[j] )
10954  {
10955  case SCIP_BASESTAT_LOWER:
10956  type = 'l';
10957  break;
10958  case SCIP_BASESTAT_UPPER:
10959  type = 'u';
10960  break;
10961  case SCIP_BASESTAT_ZERO:
10962  type = 'z';
10963  break;
10964  case SCIP_BASESTAT_BASIC:
10965  type = 'b';
10966  break;
10967  default:
10968  type = '?';
10969  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
10970  SCIPABORT();
10971  }
10972  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
10973  }
10974  }
10975  SCIPsetDebugMsg(set, "\n\n");
10976 
10977  if( !chooseBasic )
10978  {
10979  SCIPsetFreeBufferArray(set, &primsol);
10980  assert(primsol == NULL);
10981  }
10982  }
10983 #endif
10984 
10985  /* count only as round if iterations have been performed */
10986  if( iterations > 0 )
10987  ++rounds;
10988  ++nruns;
10989  }
10990  }
10991  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
10992 
10993  /* reset bounds, lhs/rhs, and obj */
10994  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
10995  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
10996  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
10997 
10998  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
10999  retcode = SCIPlpiSolveDual(lp->lpi);
11000  if( retcode == SCIP_LPERROR )
11001  {
11002  *lperror = TRUE;
11003  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11004  }
11005  else
11006  {
11007  SCIP_CALL( retcode );
11008  }
11009  assert(SCIPlpiIsOptimal(lp->lpi));
11010  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11011  lexIterations += iterations;
11012 
11013  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11014 
11015  /* count number of iterations */
11016  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11017  SCIPstatIncrement(stat, set, nlps);
11018 
11019  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11020  {
11021  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11022  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11023  {
11024  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11025  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11026  }
11027  SCIPstatIncrement(stat, set, nlexduallps);
11028  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11029 
11030  totalIterations += lexIterations;
11031  }
11032 
11033  /* free space */
11034  SCIPsetFreeBufferArray(set, &newobj);
11035 
11036  SCIPsetFreeBufferArray(set, &fixedr);
11037  SCIPsetFreeBufferArray(set, &fixedc);
11038 
11039  SCIPsetFreeBufferArray(set, &indallrow);
11040  SCIPsetFreeBufferArray(set, &indallcol);
11041 
11042  SCIPsetFreeBufferArray(set, &indrow);
11043  SCIPsetFreeBufferArray(set, &newrhs);
11044  SCIPsetFreeBufferArray(set, &newlhs);
11045 
11046  SCIPsetFreeBufferArray(set, &indcol);
11047  SCIPsetFreeBufferArray(set, &newub);
11048  SCIPsetFreeBufferArray(set, &newlb);
11049 
11050  SCIPsetFreeBufferArray(set, &oldobj);
11051  SCIPsetFreeBufferArray(set, &oldrhs);
11052  SCIPsetFreeBufferArray(set, &oldlhs);
11053  SCIPsetFreeBufferArray(set, &oldub);
11054  SCIPsetFreeBufferArray(set, &oldlb);
11055 
11056  SCIPsetFreeBufferArray(set, &rstat);
11057  SCIPsetFreeBufferArray(set, &cstat);
11058 
11059  SCIPsetFreeBufferArray(set, &redcost);
11060  SCIPsetFreeBufferArray(set, &dualsol);
11061  if( chooseBasic )
11062  SCIPsetFreeBufferArray(set, &primsol);
11063 
11064  /* stop timing */
11065  SCIPclockStop(stat->lexduallptime, set);
11066 
11067  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11068  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11069  }
11071  lp->solisbasic = TRUE;
11072 
11073  if( totalIterations > 0 && !lp->strongbranchprobing )
11074  SCIPstatIncrement(stat, set, nlps);
11075  else
11076  {
11077  if( keepsol && !(*lperror) )
11078  {
11079  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11080  if( lp->validsollp == stat->lpcount-1 )
11081  lp->validsollp = stat->lpcount;
11082  if( lp->validfarkaslp == stat->lpcount-1 )
11083  lp->validfarkaslp = stat->lpcount;
11084  }
11085  }
11086 
11087  return SCIP_OKAY;
11088 }
11089 
11090 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11091 static
11093  SCIP_LP* lp, /**< current LP data */
11094  SCIP_SET* set, /**< global SCIP settings */
11095  SCIP_STAT* stat, /**< problem statistics */
11096  SCIP_Bool crossover, /**< should crossover be performed? */
11097  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11098  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11099  )
11100 {
11101  SCIP_Real timedelta;
11102  SCIP_RETCODE retcode;
11103  int iterations;
11104 
11105  assert(lp != NULL);
11106  assert(lp->flushed);
11107  assert(set != NULL);
11108  assert(stat != NULL);
11109  assert(lperror != NULL);
11110 
11111  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",
11112  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11113  stat->nbarrierlps, stat->ndivinglps);
11114 
11115  *lperror = FALSE;
11116 
11117 #if 0 /* for debugging: write all root node LP's */
11118  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11119  {
11120  char fname[SCIP_MAXSTRLEN];
11121  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11122  SCIP_CALL( SCIPlpWrite(lp, fname) );
11123  SCIPsetDebugMsg("wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11124  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11125  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11126  }
11127 #endif
11128 
11129  /* start timing */
11130  if( lp->diving || lp->probing )
11131  {
11132  if( lp->strongbranchprobing )
11133  SCIPclockStart(stat->strongbranchtime, set);
11134  else
11135  SCIPclockStart(stat->divinglptime, set);
11136 
11137  timedelta = 0.0; /* unused for diving or probing */
11138  }
11139  else
11140  {
11141  SCIPclockStart(stat->barrierlptime, set);
11142  timedelta = -SCIPclockGetTime(stat->duallptime);
11143  }
11144 
11145  /* call barrier algorithm */
11146  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11147  if( retcode == SCIP_LPERROR )
11148  {
11149  *lperror = TRUE;
11150  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11151  }
11152  else
11153  {
11154  SCIP_CALL( retcode );
11155  }
11157  lp->solisbasic = crossover;
11158 
11159  /* stop timing */
11160  if( lp->diving || lp->probing )
11161  {
11162  if( lp->strongbranchprobing )
11163  SCIPclockStop(stat->strongbranchtime, set);
11164  else
11165  SCIPclockStop(stat->divinglptime, set);
11166  }
11167  else
11168  {
11169  SCIPclockStop(stat->barrierlptime, set);
11170  timedelta = -SCIPclockGetTime(stat->duallptime);
11171  }
11172 
11173  /* count number of iterations */
11174  SCIPstatIncrement(stat, set, lpcount);
11175  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11176  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11177  {
11178  if( !lp->strongbranchprobing )
11179  {
11180  SCIPstatIncrement(stat, set, nlps);
11181  SCIPstatAdd(stat, set, nlpiterations, iterations);
11182  }
11183  if( lp->diving || lp->probing )
11184  {
11185  if( lp->strongbranchprobing )
11186  {
11187  SCIPstatIncrement(stat, set, nsbdivinglps);
11188  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11189  }
11190  else
11191  {
11192  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11193  SCIPstatIncrement(stat, set, ndivinglps);
11194  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11195  }
11196  }
11197  else
11198  {
11199  SCIPstatIncrement(stat, set, nbarrierlps);
11200  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11201  }
11202  }
11203  else
11204  {
11205  if ( ! lp->diving && ! lp->probing )
11206  {
11207  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11208  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11209  }
11210 
11211  if( keepsol && !(*lperror) )
11212  {
11213  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11214  if( lp->validsollp == stat->lpcount-1 )
11215  lp->validsollp = stat->lpcount;
11216  if( lp->validfarkaslp == stat->lpcount-1 )
11217  lp->validfarkaslp = stat->lpcount;
11218  }
11219  }
11220 
11221  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11222  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11223 
11224  return SCIP_OKAY;
11225 }
11226 
11227 /** solves the LP with the given algorithm */
11228 static
11230  SCIP_LP* lp, /**< current LP data */
11231  SCIP_SET* set, /**< global SCIP settings */
11232  SCIP_STAT* stat, /**< problem statistics */
11233  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11234  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11235  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11236  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11237  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11238  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11239  )
11240 {
11241  SCIP_Real lptimelimit;
11242  SCIP_Bool success;
11243 
11244  assert(lp != NULL);
11245  assert(lp->flushed);
11246  assert(lperror != NULL);
11247 
11248  /* check if a time limit is set, and set time limit for LP solver accordingly */
11249  lptimelimit = SCIPlpiInfinity(lp->lpi);
11250  if( set->istimelimitfinite )
11251  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11252 
11253  success = FALSE;
11254  if( lptimelimit > 0.0 )
11255  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11256 
11257  if( lptimelimit <= 0.0 || !success )
11258  {
11259  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11260  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11261  *timelimit = TRUE;
11262  return SCIP_OKAY;
11263  }
11264  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11265 
11266  /* call appropriate LP algorithm */
11267  switch( lpalgo )
11268  {
11270  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11271  break;
11272 
11274  /* run dual lexicographic simplex if required */
11275  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11276  {
11277  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11278  }
11279  else
11280  {
11281  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11282  }
11283  break;
11284 
11285  case SCIP_LPALGO_BARRIER:
11286  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11287  break;
11288 
11290  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11291  break;
11292 
11293  default:
11294  SCIPerrorMessage("invalid LP algorithm\n");
11295  return SCIP_INVALIDDATA;
11296  }
11297 
11298  if( !(*lperror) )
11299  {
11300  /* check for primal and dual feasibility */
11302 
11303  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11304  }
11305 
11306  return SCIP_OKAY;
11307 }
11308 
11309 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11310  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11311  */
11312 #define MAXNUMTROUBLELPMSGS 10
11313 
11314 /** prints message about numerical trouble
11315  *
11316  * If message has verblevel at most high and display/verblevel is not full,
11317  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11318  * were printed before in the current run.
11319  */
11320 static
11322  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11323  SCIP_SET* set, /**< global SCIP settings */
11324  SCIP_STAT* stat, /**< problem statistics */
11325  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11326  const char* formatstr, /**< message format string */
11327  ... /**< arguments to format string */
11328  )
11329 {
11330  va_list ap;
11331 
11332  assert(verblevel > SCIP_VERBLEVEL_NONE);
11333  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11334  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11335 
11336  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11337  {
11338  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11339  {
11340  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11342  return;
11343 
11344  /* increase count on messages with verblevel high */
11345  ++stat->nnumtroublelpmsgs ;
11346  }
11347 
11348  /* if messages wouldn't be printed, then return already */
11349  if( verblevel > set->disp_verblevel )
11350  return;
11351  }
11352 
11353  /* print common begin of message */
11354  SCIPmessagePrintInfo(messagehdlr,
11355  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11356  stat->nnodes, stat->nlps);
11357 
11358  /* print individual part of message */
11359  va_start(ap, formatstr); /*lint !e838*/
11360  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11361  va_end(ap);
11362 
11363  /* warn that further messages will be suppressed */
11364  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11365  {
11366  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11367  }
11368 
11369  /* print closing new-line */
11370  SCIPmessagePrintInfo(messagehdlr, "\n");
11371 }
11372 
11373 #define FEASTOLTIGHTFAC 0.001
11374 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11375 static
11377  SCIP_LP* lp, /**< current LP data */
11378  SCIP_SET* set, /**< global SCIP settings */
11379  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11380  SCIP_STAT* stat, /**< problem statistics */
11381  SCIP_PROB* prob, /**< problem data */
11382  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11383  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11384  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11385  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11386  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11387  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11388  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11389  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11390  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11391  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11392  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11393  )
11394 {
11395  SCIP_Bool success;
11396  SCIP_Bool success2;
11397  SCIP_Bool success3;
11398  SCIP_Bool simplex;
11399  SCIP_Bool itlimishard;
11400  SCIP_Bool usepolishing;
11401 
11402  assert(lp != NULL);
11403  assert(lp->flushed);
11404  assert(set != NULL);
11405  assert(stat != NULL);
11406  assert(lperror != NULL);
11407  assert(timelimit != NULL);
11408 
11409  *lperror = FALSE;
11410 
11411  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11412  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11413  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11414  * SCIP_LP such that we can return a primal ray
11415  */
11416  if( lp->looseobjvalinf > 0 )
11417  {
11418  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11419  return SCIP_ERROR;
11420  }
11421 
11422  /* check, whether we solve with a simplex algorithm */
11423  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11424 
11425  /* check whether the iteration limit is a hard one */
11426  itlimishard = (itlim == harditlim);
11427 
11428  /* check whether solution polishing should be used */
11429  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11430  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11431  {
11432  usepolishing = TRUE;
11433  if( lp->updateintegrality )
11434  {
11435  SCIP_CALL( lpCopyIntegrality(lp, set) );
11436  }
11437  }
11438  else
11439  usepolishing = FALSE;
11440 
11441  /* solve with given settings (usually fast but imprecise) */
11442  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11443  {
11444  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound) );
11445  }
11446  else
11447  {
11448  SCIP_CALL( lpSetObjlim(lp, set, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) );
11449  }
11450  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11451  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * SCIPsetLpfeastol(set) : SCIPsetLpfeastol(set), &success) );
11452  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11453  &success) );
11454  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11455  : SCIPsetBarrierconvtol(set), &success) );
11456  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11457  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11458  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11459  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11460  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11461  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11462  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11463  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11464  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11465  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11466  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11467  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11468  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11469 
11470  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11471  resolve = FALSE; /* only the first solve should be counted as resolving call */
11472 
11473  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11474  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11475  return SCIP_OKAY;
11476 
11477  if( !set->lp_checkstability )
11478  {
11479  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11480  if( success )
11481  {
11482  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11483  return SCIP_OKAY;
11484  }
11485  }
11486 
11487  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11488  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11489  */
11490 
11491  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11492  * do this only if the iteration limit was not exceeded in the last LP solving call
11493  */
11494  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11495  {
11496  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11497  if( success )
11498  {
11499  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11500  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11501 
11502  /* check for stability */
11503  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11504  return SCIP_OKAY;
11505 
11506  if( !set->lp_checkstability )
11507  {
11508  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11509  if( success )
11510  {
11511  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11512  return SCIP_OKAY;
11513  }
11514  }
11515  }
11516  }
11517 
11518  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11519  * and go directly to solving the LP from scratch
11520  */
11521  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11522  {
11523  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11524  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11525  if( success )
11526  {
11527  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11528  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11529  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11530 
11531  /* check for stability */
11532  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11533  return SCIP_OKAY;
11534 
11535  if( !set->lp_checkstability )
11536  {
11537  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11538  if( success )
11539  {
11540  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11541  return SCIP_OKAY;
11542  }
11543  }
11544 
11545  /* reset scaling */
11546  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11547  assert(success);
11548  }
11549  }
11550 
11551  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11552  * and go directly to solving the LP from scratch */
11553  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11554  {
11555  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11556  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11557  if( success )
11558  {
11559  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11560  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11561  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11562 
11563  /* check for stability */
11564  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11565  return SCIP_OKAY;
11566 
11567  if( !set->lp_checkstability )
11568  {
11569  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11570  if( success )
11571  {
11572  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11573  return SCIP_OKAY;
11574  }
11575  }
11576 
11577  /* reset presolving */
11578  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11579  assert(success);
11580  }
11581  }
11582 
11583  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11584  * do this only if the iteration limit was not exceeded in the last LP solving call
11585  */
11586  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11587  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11588  {
11589  success = FALSE;
11590  if( !tightprimfeastol )
11591  {
11592  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11593  }
11594 
11595  success2 = FALSE;
11596  if( !tightdualfeastol )
11597  {
11599  }
11600 
11601  success3 = FALSE;
11602  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11603  {
11605  }
11606 
11607  if( success || success2 || success3 )
11608  {
11609  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11610  lpalgoName(lpalgo));
11611  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11612 
11613  /* check for stability */
11614  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11615  return SCIP_OKAY;
11616 
11617  if( !set->lp_checkstability )
11618  {
11619  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11620  if( success )
11621  {
11622  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11623  return SCIP_OKAY;
11624  }
11625  }
11626 
11627  /* reset feasibility tolerance */
11628  if( !tightprimfeastol )
11629  {
11630  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11631  }
11632  if( !tightdualfeastol )
11633  {
11634  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11635  }
11636  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11637  {
11638  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11639  }
11640  }
11641  }
11642 
11643  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11644  * the given iteration limit might be a soft one to restrict resolving calls only */
11645  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11646 
11647  /* if not already done, solve again from scratch */
11648  if( !fromscratch && simplex )
11649  {
11650  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11651  if( success )
11652  {
11653  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11654  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11655 
11656  /* check for stability */
11657  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11658  return SCIP_OKAY;
11659 
11660  if( !set->lp_checkstability )
11661  {
11662  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11663  if( success )
11664  {
11665  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11666  return SCIP_OKAY;
11667  }
11668  }
11669  }
11670  }
11671 
11672  /* solve again, use other simplex this time */
11673  if( simplex )
11674  {
11676  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11677  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11678 
11679  /* check for stability */
11680  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11681  return SCIP_OKAY;
11682 
11683  if( !set->lp_checkstability )
11684  {
11685  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11686  if( success )
11687  {
11688  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11689  return SCIP_OKAY;
11690  }
11691  }
11692 
11693  /* solve again with opposite scaling and other simplex */
11694  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11695  if( success )
11696  {
11697  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11698  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11699  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11700 
11701  /* check for stability */
11702  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11703  return SCIP_OKAY;
11704 
11705  if( !set->lp_checkstability )
11706  {
11707  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11708  if( success )
11709  {
11710  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11711  return SCIP_OKAY;
11712  }
11713  }
11714 
11715  /* reset scaling */
11716  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11717  assert(success);
11718  }
11719 
11720  /* solve again with opposite presolving and other simplex */
11721  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11722  if( success )
11723  {
11724  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11725  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11726  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11727 
11728  /* check for stability */
11729  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11730  return SCIP_OKAY;
11731 
11732  if( !set->lp_checkstability )
11733  {
11734  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11735  if( success )
11736  {
11737  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11738  return SCIP_OKAY;
11739  }
11740  }
11741 
11742  /* reset presolving */
11743  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11744  assert(success);
11745  }
11746 
11747  /* solve again with tighter feasibility tolerance, use other simplex this time */
11748  if( !tightprimfeastol || !tightdualfeastol )
11749  {
11750  success = FALSE;
11751  if( !tightprimfeastol )
11752  {
11753  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11754  }
11755 
11756  success2 = FALSE;
11757  if( !tightdualfeastol )
11758  {
11760  }
11761 
11762  if( success || success2 )
11763  {
11764  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11765  lpalgoName(lpalgo));
11766  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11767 
11768  /* check for stability */
11769  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11770  return SCIP_OKAY;
11771 
11772  if( !set->lp_checkstability )
11773  {
11774  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11775  if( success )
11776  {
11777  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11778  return SCIP_OKAY;
11779  }
11780  }
11781 
11782  /* reset feasibility tolerance */
11783  if( !tightprimfeastol )
11784  {
11785  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11786  }
11787  if( !tightdualfeastol )
11788  {
11789  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11790  }
11791  }
11792  }
11793  }
11794 
11795  /* nothing worked -- exit with an LPERROR */
11796  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11797  *lperror = TRUE;
11798 
11799  return SCIP_OKAY;
11800 }
11801 
11802 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11803 static
11805  SCIP_LP* lp, /**< current LP data */
11806  SCIP_SET* set, /**< global SCIP settings */
11807  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11808  )
11809 {
11810  assert(lp != NULL);
11811  assert(set != NULL);
11812 
11813  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11814  {
11815  if( !lp->adjustlpval && messagehdlr != NULL )
11816  {
11817  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11818  lp->adjustlpval = TRUE;
11819  }
11820  lp->lpobjval = SCIPsetInfinity(set);
11821  }
11822  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11823  {
11824  if( !lp->adjustlpval && messagehdlr != NULL )
11825  {
11826  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11827  lp->adjustlpval = TRUE;
11828  }
11829  lp->lpobjval = -SCIPsetInfinity(set);
11830  }
11831 }
11832 
11833 /** solves the LP with the given algorithm and evaluates return status */
11834 static
11836  SCIP_LP* lp, /**< current LP data */
11837  SCIP_SET* set, /**< global SCIP settings */
11838  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11839  SCIP_STAT* stat, /**< problem statistics */
11840  SCIP_PROB* prob, /**< problem data */
11841  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11842  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11843  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11844  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11845  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11846  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11847  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11848  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11849  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11850  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11851  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11852  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11853  )
11854 {
11855  SCIP_Bool solvedprimal;
11856  SCIP_Bool solveddual;
11857  SCIP_Bool timelimit;
11858  int itlim;
11859 
11860  assert(lp != NULL);
11861  assert(lp->flushed);
11862  assert(set != NULL);
11863  assert(stat != NULL);
11864  assert(lperror != NULL);
11865 
11866  checkLinks(lp);
11867 
11868  solvedprimal = FALSE;
11869  solveddual = FALSE;
11870  timelimit = FALSE;
11871 
11872  /* select the basic iteration limit depending on whether this is a resolving call or not */
11873  itlim = ( resolve ? resolveitlim : harditlim );
11874 
11875  SOLVEAGAIN:
11876  /* call simplex */
11877  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11878  keepsol, &timelimit, lperror) );
11879  resolve = FALSE; /* only the first solve should be counted as resolving call */
11880  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11881  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11882 
11883  /* check, if an error occurred */
11884  if( *lperror )
11885  {
11886  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11887  lp->solved = FALSE;
11889  return SCIP_OKAY;
11890  }
11891 
11892  /* check, if a time limit was exceeded */
11893  if( timelimit )
11894  {
11895  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11896  lp->solved = TRUE;
11898  lp->lpobjval = -SCIPsetInfinity(set);
11899  return SCIP_OKAY;
11900  }
11901 
11902  /* only one should return true */
11903  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11905 
11906  /* evaluate solution status */
11907  if( SCIPlpiIsOptimal(lp->lpi) )
11908  {
11909  assert(lp->primalfeasible);
11910  assert(lp->dualfeasible);
11912  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11913  adjustLPobjval(lp, set, messagehdlr);
11914 
11915  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
11916  {
11917  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11918  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
11920  lp->lpobjval = SCIPsetInfinity(set);
11921  }
11922  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11923  * reached if the LP objective value is greater than the cutoff bound
11924  */
11926  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11927  }
11928  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11929  {
11930  assert(!lpCutoffDisabled(set));
11932  lp->lpobjval = SCIPsetInfinity(set);
11933  }
11934  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11935  {
11936  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11937  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11938  {
11939  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11940  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11941  goto SOLVEAGAIN;
11942  }
11944  lp->lpobjval = SCIPsetInfinity(set);
11945  }
11946  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11947  {
11948  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11949  if( needprimalray && !SCIPlpiHasPrimalRay(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11950  {
11951  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11952  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11953  goto SOLVEAGAIN;
11954  }
11956  lp->lpobjval = -SCIPsetInfinity(set);
11957  }
11958  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11959  {
11960  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11961 
11962  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
11963  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
11964  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
11965  adjustLPobjval(lp, set, NULL);
11966  else
11967  adjustLPobjval(lp, set, messagehdlr);
11968 
11970  }
11971  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11972  {
11973  lp->lpobjval = -SCIPsetInfinity(set);
11975  }
11976  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11977  {
11978  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11979  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11980  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11981  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11982  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11983  goto SOLVEAGAIN;
11984  }
11985  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11986  {
11987  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11988  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11989  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11990  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11991  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11992  goto SOLVEAGAIN;
11993  }
11994  else
11995  {
11996  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
11997  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
11999  return SCIP_LPERROR;
12000  }
12001 
12002  lp->solved = TRUE;
12003 
12004  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12007 
12008  return SCIP_OKAY;
12009 }
12010 
12011 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12012 static
12014  SCIP_LP* lp, /**< current LP data */
12015  BMS_BLKMEM* blkmem, /**< block memory */
12016  SCIP_SET* set, /**< global SCIP settings */
12017  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12018  SCIP_STAT* stat, /**< problem statistics */
12019  SCIP_PROB* prob, /**< problem data */
12020  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12021  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12022  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12023  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12024  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12025  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12026  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12027  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12028  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12029  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12030  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12031  )
12032 {
12033  SCIP_Bool resolve;
12034  char algo;
12035 
12036  assert(lp != NULL);
12037  assert(set != NULL);
12038  assert(lperror != NULL);
12039 
12040  /* flush changes to the LP solver */
12041  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12042  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12043 
12044  /* select LP algorithm to apply */
12045  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12046  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12047 
12048  switch( algo )
12049  {
12050  case 's':
12051  /* select simplex method */
12052  if( lp->dualfeasible || !lp->primalfeasible )
12053  {
12054  SCIPsetDebugMsg(set, "solving dual LP\n");
12055  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12056  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12057  }
12058  else
12059  {
12060  SCIPsetDebugMsg(set, "solving primal LP\n");
12061  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12062  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12063  }
12064  break;
12065 
12066  case 'p':
12067  SCIPsetDebugMsg(set, "solving primal LP\n");
12068  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12069  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12070  break;
12071 
12072  case 'd':
12073  SCIPsetDebugMsg(set, "solving dual LP\n");
12074  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12075  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12076  break;
12077 
12078  case 'b':
12079  SCIPsetDebugMsg(set, "solving barrier LP\n");
12080  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12081  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12082  break;
12083 
12084  case 'c':
12085  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12086  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12087  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12088  break;
12089 
12090  default:
12091  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12092  return SCIP_PARAMETERWRONGVAL;
12093  }
12094  assert(!(*lperror) || !lp->solved);
12095 
12096  return SCIP_OKAY;
12097 }
12098 
12099 #ifndef NDEBUG
12100 /** checks if the lazy bounds are valid */
12101 static
12103  SCIP_LP* lp, /**< LP data */
12104  SCIP_SET* set /**< global SCIP settings */
12105  )
12106 {
12107  SCIP_COL* col;
12108  int c;
12109 
12110  assert(lp->flushed);
12111 
12112  for( c = 0; c < lp->nlazycols; ++c )
12113  {
12114  col = lp->lazycols[c];
12115 
12116  /* in case lazy bounds are given, check that the primal solution satisfies them */
12117  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12118  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12119  }
12120 }
12121 #else
12122 #define checkLazyBounds(lp, set) /**/
12123 #endif
12124 
12125 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12126  * diving
12127  */
12128 static
12130  SCIP_LP* lp, /**< LP data */
12131  SCIP_SET* set /**< global SCIP settings */
12132  )
12133 {
12134  SCIP_COL* col;
12135  int c;
12136 
12137  assert(lp->nlazycols > 0);
12138 
12139  /* return, if we are in diving, and bounds were already applied
12140  * or if we are not in diving and bounds were not applied
12141  */
12142  if( lp->diving == lp->divinglazyapplied )
12143  return SCIP_OKAY;
12144 
12145  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12146  lp->diving, lp->divinglazyapplied);
12147 
12148  for( c = 0; c < lp->nlazycols; ++c )
12149  {
12150  col = lp->lazycols[c];
12151 
12152  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12153  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12154  {
12155  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
12156  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12157  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12158 
12159  /* insert column in the chgcols list (if not already there) */
12160  SCIP_CALL( insertColChgcols(col, set, lp) );
12161 
12162  /* mark bound change in the column */
12163  col->lbchanged = TRUE;
12164  }
12165 
12166  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12167  if( !SCIPsetIsInfinity(set, col->lazyub) )
12168  {
12169  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
12170  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12171  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12172 
12173  /* insert column in the chgcols list (if not already there) */
12174  SCIP_CALL( insertColChgcols(col, set, lp) );
12175 
12176  /* mark bound change in the column */
12177  col->ubchanged = TRUE;
12178  }
12179  }
12180 
12181  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12182  * if not, we just removed them
12183  */
12184  lp->divinglazyapplied = lp->diving;
12185 
12186  return SCIP_OKAY;
12187 }
12188 
12189 /** returns the iteration limit for an LP resolving call */
12190 static
12192  SCIP_SET* set, /**< global SCIP settings */
12193  SCIP_STAT* stat, /**< dynamic problem statistics */
12194  int itlim /**< hard iteration limit */
12195  )
12196 {
12197  /* no limit set or average not yet reliable */
12198  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12199  return itlim;
12200  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12201  if( itlim == -1 )
12202  itlim = INT_MAX;
12203  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12204  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12205  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12206 }
12207 
12208 
12209 
12210 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12212  SCIP_LP* lp, /**< LP data */
12213  SCIP_SET* set, /**< global SCIP settings */
12214  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12215  BMS_BLKMEM* blkmem, /**< block memory buffers */
12216  SCIP_STAT* stat, /**< problem statistics */
12217  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12218  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12219  SCIP_PROB* prob, /**< problem data */
12220  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12221  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12222  * (limit is computed within the method w.r.t. the average LP iterations) */
12223  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12224  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12225  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12226  )
12227 {
12228  SCIP_RETCODE retcode;
12229  SCIP_Bool needprimalray;
12230  SCIP_Bool needdualray;
12231  int harditlim;
12232  int resolveitlim;
12233 
12234  assert(lp != NULL);
12235  assert(prob != NULL);
12236  assert(prob->nvars >= lp->ncols);
12237  assert(lperror != NULL);
12238 
12239  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12240  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12241 
12242  retcode = SCIP_OKAY;
12243  *lperror = FALSE;
12244 
12245  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12246  needprimalray = TRUE;
12247  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12248  || (set->conf_enable && set->conf_useinflp != 'o'));
12249 
12250  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12251  harditlim = (int) MIN(itlim, INT_MAX);
12252  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12253  assert(harditlim == -1 || (resolveitlim <= harditlim));
12254 
12255  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12256  * or removed from the LP (diving was ended)
12257  */
12258  if( lp->nlazycols > 0 )
12259  {
12260  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12261  * first resolve LP?
12262  */
12263  SCIP_CALL( updateLazyBounds(lp, set) );
12264  assert(lp->diving == lp->divinglazyapplied);
12265  }
12266 
12267  /* flush changes to the LP solver */
12268  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12269  assert(lp->flushed);
12270 
12271  /* 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
12272  * to run again anyway, since there seems to be some time left / the time limit was increased
12273  */
12274  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12275  {
12276  SCIP_Bool* primalfeaspointer;
12277  SCIP_Bool* dualfeaspointer;
12278  SCIP_Bool primalfeasible;
12279  SCIP_Bool dualfeasible;
12280  SCIP_Bool farkasvalid;
12281  SCIP_Bool rayfeasible;
12282  SCIP_Bool tightprimfeastol;
12283  SCIP_Bool tightdualfeastol;
12284  SCIP_Bool fromscratch;
12285  SCIP_Bool wasfromscratch;
12286  SCIP_Longint oldnlps;
12287  int fastmip;
12288 
12289  /* set initial LP solver settings */
12290  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12291  tightprimfeastol = FALSE;
12292  tightdualfeastol = FALSE;
12293  fromscratch = FALSE;
12294  primalfeasible = FALSE;
12295  dualfeasible = FALSE;
12296  wasfromscratch = (stat->nlps == 0);
12297 
12298  SOLVEAGAIN:
12299  /* solve the LP */
12300  oldnlps = stat->nlps;
12301  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12302  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12303  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12304  assert(!(*lperror) || !lp->solved);
12305 
12306  /* check for error */
12307  if( *lperror )
12308  {
12309  retcode = SCIP_OKAY;
12310  goto TERMINATE;
12311  }
12312 
12313  /* evaluate solution status */
12314  switch( SCIPlpGetSolstat(lp) )
12315  {
12317  /* get LP solution and possibly check the solution's feasibility again */
12318  if( set->lp_checkprimfeas )
12319  {
12320  primalfeaspointer = &primalfeasible;
12321  lp->primalchecked = TRUE;
12322  }
12323  else
12324  {
12325  /* believe in the primal feasibility of the LP solution */
12326  primalfeasible = TRUE;
12327  primalfeaspointer = NULL;
12328  lp->primalchecked = FALSE;
12329  }
12330  if( set->lp_checkdualfeas )
12331  {
12332  dualfeaspointer = &dualfeasible;
12333  lp->dualchecked = TRUE;
12334  }
12335  else
12336  {
12337  /* believe in the dual feasibility of the LP solution */
12338  dualfeasible = TRUE;
12339  dualfeaspointer = NULL;
12340  lp->dualchecked = FALSE;
12341  }
12342 
12343  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12344 
12345  /* in debug mode, check that lazy bounds (if present) are not violated */
12346  checkLazyBounds(lp, set);
12347 
12348  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12349  {
12350  /* update ages and remove obsolete columns and rows from LP */
12351  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12352  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12353  {
12354  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12355  }
12356 
12357  if( !lp->solved )
12358  {
12359  /* resolve LP after removing obsolete columns and rows */
12360  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12361  aging = FALSE; /* to prevent infinite loops */
12362  goto SOLVEAGAIN;
12363  }
12364  }
12365  if( !primalfeasible || !dualfeasible )
12366  {
12368 
12369  if( (fastmip > 0) && simplex )
12370  {
12371  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12372  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12373  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12374  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12375  fastmip = 0;
12376  goto SOLVEAGAIN;
12377  }
12378  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12379  {
12380  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12381  * tolerance
12382  */
12383  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12384  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12385  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12386  tightprimfeastol = tightprimfeastol || !primalfeasible;
12387  tightdualfeastol = tightdualfeastol || !dualfeasible;
12388  goto SOLVEAGAIN;
12389  }
12390  else if( !fromscratch && !wasfromscratch && simplex )
12391  {
12392  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12393  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12394  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12395  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12396  fromscratch = TRUE;
12397  goto SOLVEAGAIN;
12398  }
12399  else
12400  {
12401  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12402  lp->solved = FALSE;
12404  *lperror = TRUE;
12405  }
12406  }
12407  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12408  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12409  lp->lpsolstat, lp->cutoffbound);
12410  break;
12411 
12413  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12414  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12415  {
12416  if( SCIPlpiHasDualRay(lp->lpi) )
12417  {
12418  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12419  }
12420  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12421  * with the primal simplex due to numerical problems) - treat this case like an LP error
12422  */
12423  else
12424  {
12425  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12426  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12427  lp->solved = FALSE;
12429  farkasvalid = FALSE;
12430  *lperror = TRUE;
12431  }
12432  }
12433  else
12434  farkasvalid = TRUE;
12435 
12436  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12437  if( !farkasvalid && !(*lperror) )
12438  {
12440 
12441  if( (fastmip > 0) && simplex )
12442  {
12443  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12444  * without FASTMIP
12445  */
12446  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12447  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12448  stat->nnodes, stat->nlps);
12449  fastmip = 0;
12450  goto SOLVEAGAIN;
12451  }
12452  else if( !tightdualfeastol )
12453  {
12454  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12455  * solve again with tighter feasibility tolerance
12456  */
12457  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12458  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12459  stat->nnodes, stat->nlps);
12460  tightdualfeastol = TRUE;
12461  goto SOLVEAGAIN;
12462  }
12463  else if( !fromscratch && simplex )
12464  {
12465  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12466  * from scratch
12467  */
12468  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12469  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12470  stat->nnodes, stat->nlps);
12471  fromscratch = TRUE;
12472  goto SOLVEAGAIN;
12473  }
12474  else
12475  {
12476  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12477  * helped forget about the LP at this node and mark it to be unsolved
12478  */
12479  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12480  lp->solved = FALSE;
12482  *lperror = TRUE;
12483  }
12484  }
12485 
12486  break;
12487 
12489  if( set->lp_checkprimfeas )
12490  {
12491  /* get unbounded LP solution and check the solution's feasibility again */
12492  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12493 
12494  lp->primalchecked = TRUE;
12495  }
12496  else
12497  {
12498  /* get unbounded LP solution believing in the feasibility of the LP solution */
12499  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12500 
12501  primalfeasible = TRUE;
12502  rayfeasible = TRUE;
12503  lp->primalchecked = FALSE;
12504  }
12505 
12506  /* in debug mode, check that lazy bounds (if present) are not violated */
12507  checkLazyBounds(lp, set);
12508 
12509  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12510  primalfeasible, rayfeasible);
12511 
12512  if( !primalfeasible || !rayfeasible )
12513  {
12515 
12516  if( (fastmip > 0) && simplex )
12517  {
12518  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12519  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12520  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12521  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12522  fastmip = 0;
12523  goto SOLVEAGAIN;
12524  }
12525  else if( !tightprimfeastol )
12526  {
12527  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12528  * tolerance
12529  */
12530  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12531  "(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",
12532  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12533  tightprimfeastol = TRUE;
12534  goto SOLVEAGAIN;
12535  }
12536  else if( !fromscratch && simplex )
12537  {
12538  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12539  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12540  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12541  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12542  fromscratch = TRUE;
12543  goto SOLVEAGAIN;
12544  }
12545  else
12546  {
12547  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12548  * forget about the LP at this node and mark it to be unsolved
12549  */
12550  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12551  lp->solved = FALSE;
12553  *lperror = TRUE;
12554  }
12555  }
12556 
12557  break;
12558 
12560  assert(!lpCutoffDisabled(set));
12561  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12562  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12563  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12564  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12565  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12566  * FASTMIP and solve again.
12567  */
12568  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12569  {
12570  SCIP_LPI* lpi;
12571  SCIP_Real objval;
12572 
12573  lpi = SCIPlpGetLPI(lp);
12574 
12575  assert(lpi != NULL);
12576  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12577  * the assert by using !SCIPsetIsFeasNegative()
12578  */
12579  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12580 
12581  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12582 
12583  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12584  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12585  {
12586  SCIP_Real tmpcutoff;
12587  char tmppricingchar;
12588  SCIP_LPSOLSTAT solstat;
12589 
12590  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12591 
12592  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12593  fromscratch = FALSE;
12594 
12595  /* temporarily disable cutoffbound, which also disables the objective limit */
12596  tmpcutoff = lp->cutoffbound;
12597  lp->cutoffbound = SCIPlpiInfinity(lpi);
12598 
12599  /* set lp pricing strategy to steepest edge */
12600  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12601  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12602 
12603  /* resolve LP with an iteration limit of 1 */
12604  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12605  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12606 
12607  /* reinstall old cutoff bound and lp pricing strategy */
12608  lp->cutoffbound = tmpcutoff;
12609  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12610 
12611  /* get objective value */
12612  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12613 
12614  /* get solution status for the lp */
12615  solstat = SCIPlpGetSolstat(lp);
12616  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12617 
12618  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12619  {
12620  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12621  }
12622 
12623  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12624  fastmip = 0;
12625 
12626  /* the solution is still not exceeding the objective limit and the solving process
12627  * was stopped due to time or iteration limit, solve again with fastmip turned off
12628  */
12629  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12630  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12631  {
12632  assert(!(*lperror));
12633 
12634  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12635  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12636 
12637  /* get objective value */
12638  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12639 
12640  /* get solution status for the lp */
12641  solstat = SCIPlpGetSolstat(lp);
12642 
12643  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12644  }
12645 
12646  /* check for lp errors */
12647  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12648  {
12649  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12650  lp->solved = FALSE;
12652 
12653  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12654  goto TERMINATE;
12655  }
12656 
12657  lp->solved = TRUE;
12658 
12659  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12660  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12661  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12662  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12663  {
12664  /* get LP solution and possibly check the solution's feasibility again */
12665  if( set->lp_checkprimfeas )
12666  {
12667  primalfeaspointer = &primalfeasible;
12668  lp->primalchecked = TRUE;
12669  }
12670  else
12671  {
12672  /* believe in the primal feasibility of the LP solution */
12673  primalfeasible = TRUE;
12674  primalfeaspointer = NULL;
12675  lp->primalchecked = FALSE;
12676  }
12677  if( set->lp_checkdualfeas )
12678  {
12679  dualfeaspointer = &dualfeasible;
12680  lp->dualchecked = TRUE;
12681  }
12682  else
12683  {
12684  /* believe in the dual feasibility of the LP solution */
12685  dualfeasible = TRUE;
12686  dualfeaspointer = NULL;
12687  lp->dualchecked = FALSE;
12688  }
12689 
12690  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12691 
12692  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12693  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12694  {
12695  checkLazyBounds(lp, set);
12696  }
12697 
12698  /* if objective value is larger than the cutoff bound, set solution status to objective
12699  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12700  * this was already done in the lpSolve() method
12701  */
12702  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12703  {
12705  lp->lpobjval = SCIPsetInfinity(set);
12706  }
12707 
12708  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12709  * the cutoffbound; mark the LP to be unsolved
12710  */
12711  if( !primalfeasible || !dualfeasible
12712  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12713  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12714  {
12715  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12716  lp->solved = FALSE;
12718  *lperror = TRUE;
12719  }
12720 
12721  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12722  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12723  lp->lpsolstat, lp->cutoffbound);
12724  }
12725  /* infeasible solution */
12726  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12727  {
12728  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12729 
12730  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12731  {
12732  if( SCIPlpiHasDualRay(lp->lpi) )
12733  {
12734  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12735  }
12736  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12737  * with the primal simplex due to numerical problems) - treat this case like an LP error
12738  */
12739  else
12740  {
12741  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12742  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12743  lp->solved = FALSE;
12745  farkasvalid = FALSE;
12746  *lperror = TRUE;
12747  }
12748  }
12749  else
12750  farkasvalid = TRUE;
12751 
12752  if( !farkasvalid )
12753  {
12755 
12756  if( !tightprimfeastol )
12757  {
12758  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12759  * solve again with tighter feasibility tolerance
12760  */
12761  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12762  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12763  stat->nnodes, stat->nlps);
12764  tightprimfeastol = TRUE;
12765  goto SOLVEAGAIN;
12766  }
12767  else if( simplex )
12768  {
12769  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12770  * from scratch
12771  */
12772  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12773  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12774  stat->nnodes, stat->nlps);
12775  fromscratch = TRUE;
12776  goto SOLVEAGAIN;
12777  }
12778  else
12779  {
12780  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12781  * helped forget about the LP at this node and mark it to be unsolved
12782  */
12783  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12784  lp->solved = FALSE;
12786  *lperror = TRUE;
12787  }
12788  }
12789  }
12790  /* unbounded solution */
12791  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12792  {
12793  if( set->lp_checkprimfeas )
12794  {
12795  /* get unbounded LP solution and check the solution's feasibility again */
12796  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12797 
12798  lp->primalchecked = TRUE;
12799  }
12800  else
12801  {
12802  /* get unbounded LP solution believing in its feasibility */
12803  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12804 
12805  primalfeasible = TRUE;
12806  rayfeasible = TRUE;
12807  lp->primalchecked = FALSE;
12808  }
12809 
12810  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12811 
12812  /* in debug mode, check that lazy bounds (if present) are not violated */
12813  checkLazyBounds(lp, set);
12814 
12815  if( !primalfeasible || !rayfeasible )
12816  {
12817  /* unbounded solution is infeasible (this can happen due to numerical problems):
12818  * forget about the LP at this node and mark it to be unsolved
12819  *
12820  * @todo: like in the default LP solving evaluation, solve without fastmip,
12821  * with tighter feasibility tolerance and from scratch
12822  */
12823  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12824  lp->solved = FALSE;
12826  *lperror = TRUE;
12827  }
12828  }
12829 
12830  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12831  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12833  }
12834  else
12835  {
12836  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12837  }
12838  }
12839  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12840  {
12841  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12842  }
12843  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12844  break;
12845 
12847  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12848  break;
12849 
12851  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12852 
12853  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12854  stat->nclockskipsleft = 0;
12855  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12856  {
12857  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12858  "you might consider switching the clock type of SCIP\n");
12859  stat->status = SCIP_STATUS_TIMELIMIT;
12860  }
12861  break;
12862 
12863  case SCIP_LPSOLSTAT_ERROR:
12865  SCIPerrorMessage("error in LP solver\n");
12866  retcode = SCIP_LPERROR;
12867  goto TERMINATE;
12868 
12869  default:
12870  SCIPerrorMessage("unknown LP solution status\n");
12871  retcode = SCIP_ERROR;
12872  goto TERMINATE;
12873  }
12874  }
12875  assert(!(*lperror) || !lp->solved);
12876 
12877  TERMINATE:
12878  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12879  * may happen that we continue to solve from scratch during strong branching */
12880  if( lp->lpifromscratch )
12881  {
12882  SCIP_Bool success;
12883  (void) lpSetFromscratch(lp, FALSE, &success);
12884  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12885  }
12886 
12887  return retcode;
12888 }
12889 
12890 /** gets solution status of current LP */
12892  SCIP_LP* lp /**< current LP data */
12893  )
12894 {
12895  assert(lp != NULL);
12896  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12897 
12898  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12899 }
12900 
12901 /** gets objective value of current LP
12902  *
12903  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12904  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12905  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12906  */
12908  SCIP_LP* lp, /**< current LP data */
12909  SCIP_SET* set, /**< global SCIP settings */
12910  SCIP_PROB* prob /**< problem data */
12911  )
12912 {
12913  assert(lp != NULL);
12914  assert(lp->solved);
12915  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12916  assert(set != NULL);
12917 
12918  if( !lp->flushed )
12919  return SCIP_INVALID;
12920  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12921  return lp->lpobjval;
12922  else if( lp->looseobjvalinf > 0 )
12923  return -SCIPsetInfinity(set);
12924  else
12925  {
12926  /* recalculate the loose objective value, if needed */
12927  if( !lp->looseobjvalid )
12928  recomputeLooseObjectiveValue(lp, set, prob);
12929 
12930  return lp->lpobjval + lp->looseobjval;
12931  }
12932 }
12933 
12934 /** gets part of objective value of current LP that results from COLUMN variables only */
12936  SCIP_LP* lp /**< current LP data */
12937  )
12938 {
12939  assert(lp != NULL);
12940  assert(lp->solved);
12941 
12942  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12943 }
12944 
12945 /** gets part of objective value of current LP that results from LOOSE variables only */
12947  SCIP_LP* lp, /**< current LP data */
12948  SCIP_SET* set, /**< global SCIP settings */
12949  SCIP_PROB* prob /**< problem data */
12950  )
12951 {
12952  assert(lp != NULL);
12953  assert(lp->solved);
12954  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12955  assert(set != NULL);
12956 
12957  if( !lp->flushed )
12958  return SCIP_INVALID;
12959  else if( lp->looseobjvalinf > 0 )
12960  return -SCIPsetInfinity(set);
12961  else
12962  return getFiniteLooseObjval(lp, set, prob);
12963 }
12964 
12965 /** remembers the current LP objective value as root solution value */
12967  SCIP_LP* lp, /**< current LP data */
12968  SCIP_SET* set, /**< global SCIP settings */
12969  SCIP_PROB* prob /**< problem data */
12970  )
12971 {
12972  assert(lp != NULL);
12973 
12975  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12976 }
12977 
12978 /** invalidates the root LP solution value */
12980  SCIP_LP* lp /**< current LP data */
12981  )
12982 {
12983  assert(lp != NULL);
12984 
12985  lp->rootlpobjval = SCIP_INVALID;
12987 }
12988 
12989 /** recomputes local and global pseudo objective values */
12991  SCIP_LP* lp, /**< current LP data */
12992  SCIP_SET* set, /**< global SCIP settings */
12993  SCIP_PROB* prob /**< problem data */
12994  )
12995 {
12996  SCIP_VAR** vars;
12997  int nvars;
12998  int v;
12999 
13000  assert(lp != NULL);
13001  assert(set != NULL);
13002  assert(prob != NULL);
13003 
13004  vars = prob->vars;
13005  nvars = prob->nvars;
13006 
13007  lp->glbpseudoobjvalinf = 0;
13008  lp->glbpseudoobjval = 0.0;
13009 
13010  lp->pseudoobjvalinf = 0;
13011  lp->pseudoobjval = 0.0;
13012 
13013  for( v = 0; v < nvars; ++v )
13014  {
13015  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13016 
13017  if( SCIPsetIsPositive(set, obj) )
13018  {
13019  /* update the global pseudo objective value */
13020  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13021  ++(lp->glbpseudoobjvalinf);
13022  else
13023  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13024 
13025  /* update the local pseudo objective value */
13026  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13027  ++(lp->pseudoobjvalinf);
13028  else
13029  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13030  }
13031 
13032  if( SCIPsetIsNegative(set, obj) )
13033  {
13034  /* update the global pseudo objective value */
13035  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13036  ++(lp->glbpseudoobjvalinf);
13037  else
13038  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13039 
13040  /* update the local pseudo objective value */
13041  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13042  ++(lp->pseudoobjvalinf);
13043  else
13044  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13045  }
13046  }
13047 
13048  /* the recomputed values are reliable */
13050  lp->glbpseudoobjvalid = TRUE;
13051  lp->relpseudoobjval = lp->pseudoobjval;
13052  lp->pseudoobjvalid = TRUE;
13053 }
13054 
13055 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13056  * global bound
13057  */
13059  SCIP_LP* lp, /**< current LP data */
13060  SCIP_SET* set, /**< global SCIP settings */
13061  SCIP_PROB* prob /**< problem data */
13062  )
13063 {
13064  assert(lp != NULL);
13065  assert(lp->glbpseudoobjvalinf >= 0);
13066  assert(set != NULL);
13067 
13068  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13069  return -SCIPsetInfinity(set);
13070  else
13071  {
13072  /* recalculate the global pseudo solution value, if needed */
13073  if( !lp->glbpseudoobjvalid )
13074  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13075 
13076  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13077  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13078  return -SCIPsetInfinity(set);
13079 
13080  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13081  return SCIPsetInfinity(set);
13082 
13083  return lp->glbpseudoobjval;
13084  }
13085 }
13086 
13087 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13088  * objective function) local bound
13089  */
13091  SCIP_LP* lp, /**< current LP data */
13092  SCIP_SET* set, /**< global SCIP settings */
13093  SCIP_PROB* prob /**< problem data */
13094  )
13095 {
13096  assert(lp != NULL);
13097  assert(lp->pseudoobjvalinf >= 0);
13098  assert(set != NULL);
13099 
13100  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13101  return -SCIPsetInfinity(set);
13102  else
13103  {
13104  /* recalculate the pseudo solution value, if needed */
13105  if( !lp->pseudoobjvalid )
13106  recomputePseudoObjectiveValue(lp, set, prob);
13107 
13108  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13109  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13110  return -SCIPsetInfinity(set);
13111 
13112  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13113  return SCIPsetInfinity(set);
13114 
13115  return lp->pseudoobjval;
13116  }
13117 }
13118 
13119 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13121  SCIP_LP* lp, /**< current LP data */
13122  SCIP_SET* set, /**< global SCIP settings */
13123  SCIP_PROB* prob, /**< problem data */
13124  SCIP_VAR* var, /**< problem variable */
13125  SCIP_Real oldbound, /**< old value for bound */
13126  SCIP_Real newbound, /**< new value for bound */
13127  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13128  )
13129 {
13130  SCIP_Real pseudoobjval;
13131  int pseudoobjvalinf;
13132  SCIP_Real obj;
13133 
13134  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13135  pseudoobjvalinf = lp->pseudoobjvalinf;
13136  obj = SCIPvarGetObj(var);
13137  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13138  {
13139  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13140  pseudoobjvalinf--;
13141  else
13142  pseudoobjval -= oldbound * obj;
13143  assert(pseudoobjvalinf >= 0);
13144  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13145  pseudoobjvalinf++;
13146  else
13147  pseudoobjval += newbound * obj;
13148  }
13149  assert(pseudoobjvalinf >= 0);
13150 
13151  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13152  return -SCIPsetInfinity(set);
13153  else
13154  return pseudoobjval;
13155 }
13156 
13157 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13158  * perform calculations with interval arithmetic to get an exact lower bound
13159  */
13161  SCIP_LP* lp, /**< current LP data */
13162  SCIP_SET* set, /**< global SCIP settings */
13163  SCIP_VAR* var, /**< problem variable */
13164  SCIP_Real oldbound, /**< old value for bound */
13165  SCIP_Real newbound, /**< new value for bound */
13166  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13167  )
13168 {
13169  SCIP_Real pseudoobjval;
13170  int pseudoobjvalinf;
13171  SCIP_Real obj;
13172 
13173  assert(lp->pseudoobjvalid);
13174 
13175  pseudoobjval = lp->pseudoobjval;
13176  pseudoobjvalinf = lp->pseudoobjvalinf;
13177  obj = SCIPvarGetObj(var);
13178  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13179  {
13180  SCIP_INTERVAL objint;
13181  SCIP_INTERVAL bd;
13182  SCIP_INTERVAL prod;
13183  SCIP_INTERVAL psval;
13184 
13185  SCIPintervalSet(&psval, pseudoobjval);
13186  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13187 
13188  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13189  pseudoobjvalinf--;
13190  else
13191  {
13192  SCIPintervalSet(&bd, oldbound);
13193  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13194  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13195  }
13196  assert(pseudoobjvalinf >= 0);
13197  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13198  pseudoobjvalinf++;
13199  else
13200  {
13201  SCIPintervalSet(&bd, newbound);
13202  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13203  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13204  }
13205 
13206  pseudoobjval = SCIPintervalGetInf(psval);
13207  }
13208  assert(pseudoobjvalinf >= 0);
13209 
13210  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13211  return -SCIPsetInfinity(set);
13212  else
13213  return pseudoobjval;
13214 }
13215 
13216 /** compute the objective delta due the new objective coefficient */
13217 static
13219  SCIP_SET* set, /**< global SCIP settings */
13220  SCIP_Real oldobj, /**< old objective value of variable */
13221  SCIP_Real newobj, /**< new objective value of variable */
13222  SCIP_Real lb, /**< lower bound of variable */
13223  SCIP_Real ub, /**< upper bound of variable */
13224  SCIP_Real* deltaval, /**< pointer to store the delta value */
13225  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13226  )
13227 {
13228  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13229  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13230  assert(!SCIPsetIsInfinity(set, lb));
13231  assert(!SCIPsetIsInfinity(set, -ub));
13232  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13233 
13234  (*deltaval) = 0.0;
13235  (*deltainf) = 0;
13236 
13237  if( SCIPsetIsPositive(set, oldobj) )
13238  {
13239  /* sign of objective did not change */
13240  if( SCIPsetIsPositive(set, newobj) )
13241  {
13242  /* if the bound is finite, calculate the deltaval */
13243  if( !SCIPsetIsInfinity(set, -lb) )
13244  (*deltaval) = lb * (newobj - oldobj);
13245  }
13246  /* sign of objective did change, so the best bound does change */
13247  else if( SCIPsetIsNegative(set, newobj) )
13248  {
13249  if( SCIPsetIsInfinity(set, -lb) )
13250  {
13251  /* old best bound was infinite while new one is not */
13252  if( !SCIPsetIsInfinity(set, ub) )
13253  {
13254  (*deltainf) = -1;
13255  (*deltaval) = ub * newobj;
13256  }
13257  }
13258  else
13259  {
13260  /* new best bound is infinite while old one was not */
13261  if( SCIPsetIsInfinity(set, ub) )
13262  {
13263  (*deltainf) = 1;
13264  (*deltaval) = -lb * oldobj;
13265  }
13266  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13267  else
13268  {
13269  (*deltaval) = (ub * newobj) - (lb * oldobj);
13270  }
13271  }
13272  }
13273  /* new objective is 0.0 */
13274  else
13275  {
13276  if( SCIPsetIsInfinity(set, -lb) )
13277  (*deltainf) = -1;
13278  else
13279  (*deltaval) = -lb * oldobj;
13280  }
13281  }
13282  else if( SCIPsetIsNegative(set, oldobj) )
13283  {
13284  /* sign of objective did not change */
13285  if( SCIPsetIsNegative(set, newobj) )
13286  {
13287  /* if the bound is finite, calculate the deltaval */
13288  if( !SCIPsetIsInfinity(set, ub) )
13289  (*deltaval) = ub * (newobj - oldobj);
13290  }
13291  /* sign of objective did change, so the best bound does change */
13292  else if( SCIPsetIsPositive(set, newobj) )
13293  {
13294  if( SCIPsetIsInfinity(set, ub) )
13295  {
13296  /* old best bound was infinite while new one is not */
13297  if( !SCIPsetIsInfinity(set, -lb) )
13298  {
13299  (*deltainf) = -1;
13300  (*deltaval) = lb * newobj;
13301  }
13302  }
13303  else
13304  {
13305  /* new best bound is infinite while old one was not */
13306  if( SCIPsetIsInfinity(set, -lb) )
13307  {
13308  (*deltainf) = 1;
13309  (*deltaval) = -ub * oldobj;
13310  }
13311  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13312  else
13313  {
13314  (*deltaval) = (lb * newobj) - (ub * oldobj);
13315  }
13316  }
13317  }
13318  /* new objective is 0.0 */
13319  else
13320  {
13321  if( SCIPsetIsInfinity(set, ub) )
13322  (*deltainf) = -1;
13323  else
13324  (*deltaval) = -ub * oldobj;
13325  }
13326  }
13327  /* old objective was 0.0 */
13328  else
13329  {
13330  if( SCIPsetIsNegative(set, newobj) )
13331  {
13332  if( SCIPsetIsInfinity(set, ub) )
13333  (*deltainf) = 1;
13334  else
13335  (*deltaval) = ub * newobj;
13336  }
13337  else if( SCIPsetIsPositive(set, newobj) )
13338  {
13339  if( SCIPsetIsInfinity(set, -lb) )
13340  (*deltainf) = 1;
13341  else
13342  (*deltaval) = lb * newobj;
13343  }
13344  }
13345 }
13346 
13347 /** compute the objective delta due the new lower bound */
13348 static
13350  SCIP_SET* set, /**< global SCIP settings */
13351  SCIP_Real obj, /**< objective value of variable */
13352  SCIP_Real oldlb, /**< old lower bound of variable */
13353  SCIP_Real newlb, /**< new lower bound of variable */
13354  SCIP_Real* deltaval, /**< pointer to store the delta value */
13355  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13356  )
13357 {
13358  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13359  assert(!SCIPsetIsInfinity(set, oldlb));
13360  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13361  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13362 
13363  if( SCIPsetIsInfinity(set, -oldlb) )
13364  {
13365  if( !SCIPsetIsInfinity(set, newlb) )
13366  {
13367  (*deltainf) = -1;
13368  (*deltaval) = newlb * obj;
13369  }
13370  else
13371  {
13372  (*deltainf) = 0;
13373  (*deltaval) = 0.0;
13374  }
13375  }
13376  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13377  {
13378  (*deltainf) = 1;
13379  (*deltaval) = -oldlb * obj;
13380  }
13381  else
13382  {
13383  (*deltainf) = 0;
13384  (*deltaval) = obj * (newlb - oldlb);
13385  }
13386 }
13387 
13388 /** compute the objective delta due the new upper bound */
13389 static
13391  SCIP_SET* set, /**< global SCIP settings */
13392  SCIP_Real obj, /**< objective value of variable */
13393  SCIP_Real oldub, /**< old upper bound of variable */
13394  SCIP_Real newub, /**< new upper bound of variable */
13395  SCIP_Real* deltaval, /**< pointer to store the delta value */
13396  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13397  )
13398 {
13399  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13400  assert(!SCIPsetIsInfinity(set, -oldub));
13401  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13402  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13403 
13404  if( SCIPsetIsInfinity(set, oldub) )
13405  {
13406  if( !SCIPsetIsInfinity(set, -newub) )
13407  {
13408  (*deltainf) = -1;
13409  (*deltaval) = newub * obj;
13410  }
13411  else
13412  {
13413  (*deltainf) = 0;
13414  (*deltaval) = 0.0;
13415  }
13416  }
13417  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13418  {
13419  (*deltainf) = 1;
13420  (*deltaval) = -oldub * obj;
13421  }
13422  else
13423  {
13424  (*deltainf) = 0;
13425  (*deltaval) = obj * (newub - oldub);
13426  }
13427 }
13428 
13429 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13430 static
13432  SCIP_LP* lp, /**< current LP data */
13433  SCIP_SET* set, /**< global SCIP settings */
13434  SCIP_VAR* var, /**< problem variable that changed */
13435  SCIP_Real deltaval, /**< delta value in the objective function */
13436  int deltainf, /**< delta value for the number of variables with infinite best bound */
13437  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13438  SCIP_Bool loose, /**< should the loose objective value be updated? */
13439  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13440  )
13441 {
13442  assert(lp != NULL);
13443  assert(lp->looseobjvalinf >= 0);
13444  assert(lp->pseudoobjvalinf >= 0);
13445  assert(lp->glbpseudoobjvalinf >= 0);
13446 
13447  /* update the pseudo objective value */
13448  if( local )
13449  {
13450  lp->pseudoobjvalinf += deltainf;
13451  if( lp->pseudoobjvalid )
13452  {
13453  lp->pseudoobjval += deltaval;
13454 
13455  /* if the absolute value was increased, this is regarded as reliable,
13456  * otherwise, we check whether we can still trust the updated value
13457  */
13458  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13459  lp->relpseudoobjval = lp->pseudoobjval;
13460  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13461  lp->pseudoobjvalid = FALSE;
13462  }
13463 
13464  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13466  loose = TRUE;
13467  }
13468  /* update the loose objective value */
13469  if( loose )
13470  {
13471  lp->looseobjvalinf += deltainf;
13472 
13473  if( deltaval != 0.0 && lp->looseobjvalid )
13474  {
13475  lp->looseobjval += deltaval;
13476 
13477  /* if the absolute value was increased, this is regarded as reliable,
13478  * otherwise, we check whether we can still trust the updated value
13479  */
13480  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13481  lp->rellooseobjval = lp->looseobjval;
13482  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13483  lp->looseobjvalid = FALSE;
13484  }
13485  }
13486  /* update the root pseudo objective values */
13487  if( global )
13488  {
13489  lp->glbpseudoobjvalinf += deltainf;
13490  if( lp->glbpseudoobjvalid )
13491  {
13492  lp->glbpseudoobjval += deltaval;
13493 
13494  /* if the absolute value was increased, this is regarded as reliable,
13495  * otherwise, we check whether we can still trust the updated value
13496  */
13500  lp->glbpseudoobjvalid = FALSE;
13501  }
13502  }
13503 
13504  assert(lp->looseobjvalinf >= 0);
13505  assert(lp->pseudoobjvalinf >= 0);
13506  assert(lp->glbpseudoobjvalinf >= 0);
13507 }
13508 
13509 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13510  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13511  */
13512 static
13514  SCIP_LP* lp, /**< current LP data */
13515  SCIP_SET* set, /**< global SCIP settings */
13516  SCIP_VAR* var, /**< problem variable that changed */
13517  SCIP_Real oldobj, /**< old objective value of variable */
13518  SCIP_Real oldlb, /**< old objective value of variable */
13519  SCIP_Real oldub, /**< old objective value of variable */
13520  SCIP_Real newobj, /**< new objective value of variable */
13521  SCIP_Real newlb, /**< new objective value of variable */
13522  SCIP_Real newub /**< new objective value of variable */
13523  )
13524 {
13525  SCIP_INTERVAL deltaval;
13526  SCIP_INTERVAL bd;
13527  SCIP_INTERVAL obj;
13528  SCIP_INTERVAL prod;
13529  SCIP_INTERVAL psval;
13530  int deltainf;
13531 
13532  assert(lp != NULL);
13533  assert(lp->pseudoobjvalinf >= 0);
13534  assert(lp->looseobjvalinf >= 0);
13535  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13536  assert(!SCIPsetIsInfinity(set, oldlb));
13537  assert(!SCIPsetIsInfinity(set, -oldub));
13538  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13539  assert(!SCIPsetIsInfinity(set, newlb));
13540  assert(!SCIPsetIsInfinity(set, -newub));
13541  assert(var != NULL);
13542 
13544  {
13545  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13546  return SCIP_INVALIDDATA;
13547  }
13548 
13549  assert(SCIPvarGetProbindex(var) >= 0);
13550 
13551  SCIPintervalSet(&deltaval, 0.0);
13552  deltainf = 0;
13553 
13554  /* subtract old pseudo objective value */
13555  if( oldobj > 0.0 )
13556  {
13557  if( SCIPsetIsInfinity(set, -oldlb) )
13558  deltainf--;
13559  else
13560  {
13561  SCIPintervalSet(&bd, oldlb);
13562  SCIPintervalSet(&obj, oldobj);
13563  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13564  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13565  }
13566  }
13567  else if( oldobj < 0.0 )
13568  {
13569  if( SCIPsetIsInfinity(set, oldub) )
13570  deltainf--;
13571  else
13572  {
13573  SCIPintervalSet(&bd, oldub);
13574  SCIPintervalSet(&obj, oldobj);
13575  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13576  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13577  }
13578  }
13579 
13580  /* add new pseudo objective value */
13581  if( newobj > 0.0 )
13582  {
13583  if( SCIPsetIsInfinity(set, -newlb) )
13584  deltainf++;
13585  else
13586  {
13587  SCIPintervalSet(&bd, newlb);
13588  SCIPintervalSet(&obj, newobj);
13589  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13590  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13591  }
13592  }
13593  else if( newobj < 0.0 )
13594  {
13595  if( SCIPsetIsInfinity(set, newub) )
13596  deltainf++;
13597  else
13598  {
13599  SCIPintervalSet(&bd, newub);
13600  SCIPintervalSet(&obj, newobj);
13601  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13602  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13603  }
13604  }
13605 
13606  /* update the pseudo and loose objective values */
13607  SCIPintervalSet(&psval, lp->pseudoobjval);
13608  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13609  lp->pseudoobjval = SCIPintervalGetInf(psval);
13610  lp->pseudoobjvalinf += deltainf;
13612  {
13613  SCIPintervalSet(&psval, lp->looseobjval);
13614  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13615  lp->looseobjval = SCIPintervalGetInf(psval);
13616  lp->looseobjvalinf += deltainf;
13617  }
13618 
13619  assert(lp->pseudoobjvalinf >= 0);
13620  assert(lp->looseobjvalinf >= 0);
13621 
13622  return SCIP_OKAY;
13623 }
13624 
13625 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13627  SCIP_LP* lp, /**< current LP data */
13628  SCIP_SET* set, /**< global SCIP settings */
13629  SCIP_VAR* var, /**< problem variable that changed */
13630  SCIP_Real oldobj, /**< old objective value of variable */
13631  SCIP_Real newobj /**< new objective value of variable */
13632  )
13633 {
13634  assert(set != NULL);
13635  assert(var != NULL);
13636 
13637  if( set->misc_exactsolve )
13638  {
13639  if( oldobj != newobj ) /*lint !e777*/
13640  {
13641  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13642  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13643  }
13644  }
13645  else
13646  {
13647  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13648  {
13649  SCIP_Real deltaval;
13650  int deltainf;
13651 
13653  assert(SCIPvarGetProbindex(var) >= 0);
13654 
13655  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13656  * domain of the variable are the same
13657  */
13658  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13659  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13660 
13661  /* compute the pseudo objective delta due the new objective coefficient */
13662  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13663 
13664  /* update the local pseudo objective value */
13665  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13666 
13667  /* compute the pseudo objective delta due the new objective coefficient */
13668  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13669 
13670  /* update the global pseudo objective value */
13671  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13672  }
13673  }
13674 
13675  return SCIP_OKAY;
13676 }
13677 
13678 
13679 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13681  SCIP_LP* lp, /**< current LP data */
13682  SCIP_SET* set, /**< global SCIP settings */
13683  SCIP_VAR* var, /**< problem variable that changed */
13684  SCIP_Real oldlb, /**< old lower bound of variable */
13685  SCIP_Real newlb /**< new lower bound of variable */
13686  )
13687 {
13688  assert(set != NULL);
13689  assert(var != NULL);
13690 
13691  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13692  {
13693  SCIP_Real deltaval;
13694  int deltainf;
13695 
13696  /* compute the pseudo objective delta due the new lower bound */
13697  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13698 
13699  /* update the root pseudo objective values */
13700  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13701  }
13702 
13703  return SCIP_OKAY;
13704 }
13705 
13706 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13708  SCIP_LP* lp, /**< current LP data */
13709  SCIP_SET* set, /**< global SCIP settings */
13710  SCIP_VAR* var, /**< problem variable that changed */
13711  SCIP_Real oldlb, /**< old lower bound of variable */
13712  SCIP_Real newlb /**< new lower bound of variable */
13713  )
13714 {
13715  assert(set != NULL);
13716  assert(var != NULL);
13717 
13718  if( set->misc_exactsolve )
13719  {
13720  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13721  {
13722  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13723  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13724  }
13725  }
13726  else
13727  {
13728  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13729  {
13730  SCIP_Real deltaval;
13731  int deltainf;
13732 
13734  assert(SCIPvarGetProbindex(var) >= 0);
13735 
13736  /* compute the pseudo objective delta due the new lower bound */
13737  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13738 
13739  /* update the pseudo and loose objective values */
13740  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13741  }
13742  }
13743 
13744  return SCIP_OKAY;
13745 }
13746 
13747 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13749  SCIP_LP* lp, /**< current LP data */
13750  SCIP_SET* set, /**< global SCIP settings */
13751  SCIP_VAR* var, /**< problem variable that changed */
13752  SCIP_Real oldub, /**< old upper bound of variable */
13753  SCIP_Real newub /**< new upper bound of variable */
13754  )
13755 {
13756  assert(set != NULL);
13757  assert(var != NULL);
13758 
13759  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13760  {
13761  SCIP_Real deltaval;
13762  int deltainf;
13763 
13764  /* compute the pseudo objective delta due the new upper bound */
13765  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13766 
13767  /* update the root pseudo objective values */
13768  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13769  }
13770 
13771  return SCIP_OKAY;
13772 }
13773 
13774 /** updates current pseudo objective value for a change in a variable's upper bound */
13776  SCIP_LP* lp, /**< current LP data */
13777  SCIP_SET* set, /**< global SCIP settings */
13778  SCIP_VAR* var, /**< problem variable that changed */
13779  SCIP_Real oldub, /**< old upper bound of variable */
13780  SCIP_Real newub /**< new upper bound of variable */
13781  )
13782 {
13783  assert(set != NULL);
13784  assert(var != NULL);
13785 
13786  if( set->misc_exactsolve )
13787  {
13788  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13789  {
13790  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13791  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13792  }
13793  }
13794  else
13795  {
13796  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13797  {
13798  SCIP_Real deltaval;
13799  int deltainf;
13800 
13802  assert(SCIPvarGetProbindex(var) >= 0);
13803 
13804  /* compute the pseudo objective delta due the new upper bound */
13805  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13806 
13807  /* update the pseudo and loose objective values */
13808  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13809  }
13810  }
13811 
13812  return SCIP_OKAY;
13813 }
13814 
13815 /** informs LP, that given variable was added to the problem */
13817  SCIP_LP* lp, /**< current LP data */
13818  SCIP_SET* set, /**< global SCIP settings */
13819  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13820  )
13821 {
13822  assert(lp != NULL);
13824  assert(SCIPvarGetProbindex(var) >= 0);
13825 
13826  /* add the variable to the loose objective value sum */
13827  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13828 
13829  /* update the loose variables counter */
13831  lp->nloosevars++;
13832 
13833  return SCIP_OKAY;
13834 }
13835 
13836 /** informs LP, that given variable is to be deleted from the problem */
13838  SCIP_LP* lp, /**< current LP data */
13839  SCIP_SET* set, /**< global SCIP settings */
13840  SCIP_VAR* var /**< variable that will be deleted from the problem */
13841  )
13842 {
13843  assert(lp != NULL);
13845  assert(SCIPvarGetProbindex(var) >= 0);
13846 
13847  /* subtract the variable from the loose objective value sum */
13848  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13849 
13850  /* update the loose variables counter */
13852  {
13853  SCIPlpDecNLoosevars(lp);
13854  }
13855 
13856  return SCIP_OKAY;
13857 }
13858 
13859 /** informs LP, that given formerly loose problem variable is now a column variable */
13860 static
13862  SCIP_LP* lp, /**< current LP data */
13863  SCIP_SET* set, /**< global SCIP settings */
13864  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13865  )
13866 {
13867  SCIP_Real obj;
13868  SCIP_Real lb;
13869  SCIP_Real ub;
13870 
13871  assert(lp != NULL);
13872  assert(lp->nloosevars > 0);
13873  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13874  assert(SCIPvarGetProbindex(var) >= 0);
13875  assert(lp->looseobjvalinf >= 0);
13876 
13877  obj = SCIPvarGetObj(var);
13878 
13879  /* update loose objective value */
13880  if( SCIPsetIsPositive(set, obj) )
13881  {
13882  lb = SCIPvarGetLbLocal(var);
13883  if( SCIPsetIsInfinity(set, -lb) )
13884  lp->looseobjvalinf--;
13885  else
13886  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13887  }
13888  else if( SCIPsetIsNegative(set, obj) )
13889  {
13890  ub = SCIPvarGetUbLocal(var);
13891  if( SCIPsetIsInfinity(set, ub) )
13892  lp->looseobjvalinf--;
13893  else
13894  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13895  }
13896 
13897  SCIPlpDecNLoosevars(lp);
13898 
13899  assert(lp->looseobjvalinf >= 0);
13900 
13901  return SCIP_OKAY;
13902 }
13903 
13904 /** informs LP, that given formerly loose problem variable is now a column variable
13905  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13906  */
13907 static
13909  SCIP_LP* lp, /**< current LP data */
13910  SCIP_SET* set, /**< global SCIP settings */
13911  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13912  )
13913 {
13914  SCIP_INTERVAL bd;
13915  SCIP_INTERVAL ob;
13916  SCIP_INTERVAL prod;
13917  SCIP_INTERVAL loose;
13918  SCIP_Real obj;
13919  SCIP_Real lb;
13920  SCIP_Real ub;
13921 
13922  assert(lp != NULL);
13923  assert(lp->nloosevars > 0);
13924  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13925  assert(SCIPvarGetProbindex(var) >= 0);
13926 
13927  obj = SCIPvarGetObj(var);
13928 
13929  SCIPintervalSet(&loose, lp->looseobjval);
13930 
13931  /* update loose objective value corresponding to the deletion of variable */
13932  if( obj > 0.0 )
13933  {
13934  lb = SCIPvarGetLbLocal(var);
13935  if( SCIPsetIsInfinity(set, -lb) )
13936  lp->looseobjvalinf--;
13937  else
13938  {
13939  SCIPintervalSet(&bd, lb);
13940  SCIPintervalSet(&ob, obj);
13941  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13942  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13943  }
13944  }
13945  else if( SCIPsetIsNegative(set, obj) )
13946  {
13947  ub = SCIPvarGetUbLocal(var);
13948  if( SCIPsetIsInfinity(set, ub) )
13949  lp->looseobjvalinf--;
13950  else
13951  {
13952  SCIPintervalSet(&bd, ub);
13953  SCIPintervalSet(&ob, obj);
13954  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13955  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13956  }
13957  }
13958  lp->nloosevars--;
13959 
13960  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13961  if( lp->nloosevars == 0 )
13962  {
13963  assert(lp->looseobjvalinf == 0);
13964  lp->looseobjval = 0.0;
13965  }
13966  else
13967  lp->looseobjval = SCIPintervalGetInf(loose);
13968 
13969  return SCIP_OKAY;
13970 }
13971 
13972 /** informs LP, that given formerly loose problem variable is now a column variable */
13974  SCIP_LP* lp, /**< current LP data */
13975  SCIP_SET* set, /**< global SCIP settings */
13976  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13977  )
13978 {
13979  assert(set != NULL);
13980 
13981  if( set->misc_exactsolve )
13982  {
13983  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13984  }
13985  else
13986  {
13987  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13988  }
13989 
13990  return SCIP_OKAY;
13991 }
13992 
13993 /** informs LP, that given formerly column problem variable is now again a loose variable */
13994 static
13996  SCIP_LP* lp, /**< current LP data */
13997  SCIP_SET* set, /**< global SCIP settings */
13998  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
13999  )
14000 {
14001  SCIP_Real obj;
14002  SCIP_Real lb;
14003  SCIP_Real ub;
14004 
14005  assert(lp != NULL);
14006  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14007  assert(SCIPvarGetProbindex(var) >= 0);
14008  assert(lp->looseobjvalinf >= 0);
14009 
14010  obj = SCIPvarGetObj(var);
14011 
14012  /* update loose objective value corresponding to the addition of variable */
14013  if( SCIPsetIsPositive(set, obj) )
14014  {
14015  lb = SCIPvarGetLbLocal(var);
14016  if( SCIPsetIsInfinity(set, -lb) )
14017  lp->looseobjvalinf++;
14018  else
14019  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14020  }
14021  else if( SCIPsetIsNegative(set, obj) )
14022  {
14023  ub = SCIPvarGetUbLocal(var);
14024  if( SCIPsetIsInfinity(set, ub) )
14025  lp->looseobjvalinf++;
14026  else
14027  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14028  }
14029  lp->nloosevars++;
14030 
14031  assert(lp->looseobjvalinf >= 0);
14032 
14033  return SCIP_OKAY;
14034 }
14035 
14036 /** informs LP, that given formerly column problem variable is now again a loose variable
14037  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14038  */
14039 static
14041  SCIP_LP* lp, /**< current LP data */
14042  SCIP_SET* set, /**< global SCIP settings */
14043  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14044  )
14045 {
14046  SCIP_INTERVAL bd;
14047  SCIP_INTERVAL ob;
14048  SCIP_INTERVAL prod;
14049  SCIP_INTERVAL loose;
14050  SCIP_Real obj;
14051  SCIP_Real lb;
14052  SCIP_Real ub;
14053 
14054  assert(lp != NULL);
14055  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14056  assert(SCIPvarGetProbindex(var) >= 0);
14057 
14058  obj = SCIPvarGetObj(var);
14059 
14060  SCIPintervalSet(&loose, lp->looseobjval);
14061 
14062  /* update loose objective value corresponding to the deletion of variable */
14063  if( obj > 0.0 )
14064  {
14065  lb = SCIPvarGetLbLocal(var);
14066  if( SCIPsetIsInfinity(set, -lb) )
14067  lp->looseobjvalinf++;
14068  else
14069  {
14070  SCIPintervalSet(&bd, lb);
14071  SCIPintervalSet(&ob, obj);
14072  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14073  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14074  }
14075  }
14076  else if( SCIPsetIsNegative(set, obj) )
14077  {
14078  ub = SCIPvarGetUbLocal(var);
14079  if( SCIPsetIsInfinity(set, ub) )
14080  lp->looseobjvalinf++;
14081  else
14082  {
14083  SCIPintervalSet(&bd, ub);
14084  SCIPintervalSet(&ob, obj);
14085  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14086  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14087  }
14088  }
14089  lp->nloosevars++;
14090 
14091  lp->looseobjval = SCIPintervalGetInf(loose);
14092 
14093  return SCIP_OKAY;
14094 }
14095 
14096 /** informs LP, that given formerly column problem variable is now again a loose variable */
14098  SCIP_LP* lp, /**< current LP data */
14099  SCIP_SET* set, /**< global SCIP settings */
14100  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14101  )
14102 {
14103  assert(set != NULL);
14104 
14105  if( set->misc_exactsolve )
14106  {
14107  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14108  }
14109  else
14110  {
14111  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14112  }
14113 
14114  return SCIP_OKAY;
14115 }
14116 
14117 /** decrease the number of loose variables by one */
14119  SCIP_LP* lp /**< current LP data */
14120  )
14121 {
14122  assert(lp != NULL);
14123  assert(lp->nloosevars > 0);
14124 
14125  lp->nloosevars--;
14126 
14127  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14128  if( lp->nloosevars == 0 )
14129  {
14130  assert(lp->looseobjvalinf == 0);
14131  lp->looseobjval = 0.0;
14132  }
14133 }
14134 
14135 /** stores the LP solution in the columns and rows */
14137  SCIP_LP* lp, /**< current LP data */
14138  SCIP_SET* set, /**< global SCIP settings */
14139  SCIP_STAT* stat, /**< problem statistics */
14140  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14141  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14142  )
14143 {
14144  SCIP_COL** lpicols;
14145  SCIP_ROW** lpirows;
14146  SCIP_Real* primsol;
14147  SCIP_Real* dualsol;
14148  SCIP_Real* activity;
14149  SCIP_Real* redcost;
14150  SCIP_Real primalbound;
14151  SCIP_Real dualbound;
14152  SCIP_Bool stillprimalfeasible;
14153  SCIP_Bool stilldualfeasible;
14154  int* cstat;
14155  int* rstat;
14156  SCIP_Longint lpcount;
14157  int nlpicols;
14158  int nlpirows;
14159  int c;
14160  int r;
14161 
14162  assert(lp != NULL);
14163  assert(lp->flushed);
14164  assert(lp->solved);
14165  assert(set != NULL);
14166  assert(stat != NULL);
14167  assert(lp->validsollp <= stat->lpcount);
14168 
14169  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14170  * corresponding flag immediately to FALSE to skip all checks
14171  */
14172  if( primalfeasible == NULL )
14173  stillprimalfeasible = FALSE;
14174  else
14175  {
14176  *primalfeasible = TRUE;
14177  stillprimalfeasible = TRUE;
14178  }
14179  if( dualfeasible == NULL )
14180  stilldualfeasible = FALSE;
14181  else
14182  {
14183  *dualfeasible = TRUE;
14184  stilldualfeasible = TRUE;
14185  }
14186 
14187  /* check if the values are already calculated */
14188  if( lp->validsollp == stat->lpcount )
14189  return SCIP_OKAY;
14190  lp->validsollp = stat->lpcount;
14191 
14192  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14193  stat->lpcount, SCIPlpGetSolstat(lp));
14194 
14195  lpicols = lp->lpicols;
14196  lpirows = lp->lpirows;
14197  nlpicols = lp->nlpicols;
14198  nlpirows = lp->nlpirows;
14199  lpcount = stat->lpcount;
14200 
14201  /* get temporary memory */
14202  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14203  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14204  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14205  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14206  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14207  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14208 
14209  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14210  if( lp->solisbasic )
14211  {
14212  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14213  }
14214  else
14215  {
14216  BMSclearMemoryArray(cstat, nlpicols);
14217  BMSclearMemoryArray(rstat, nlpirows);
14218  }
14219 
14220  primalbound = 0.0;
14221  dualbound = 0.0;
14222 
14223  /* copy primal solution and reduced costs into columns */
14224  for( c = 0; c < nlpicols; ++c )
14225  {
14226  assert( 0 <= cstat[c] && cstat[c] < 4 );
14227  lpicols[c]->primsol = primsol[c];
14228  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14229  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14230  lpicols[c]->redcost = redcost[c];
14231  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14232  lpicols[c]->validredcostlp = lpcount;
14233  if( stillprimalfeasible )
14234  {
14235  stillprimalfeasible =
14236  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
14237  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
14238  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14239  }
14240  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14241  {
14242  double compslack;
14243 
14244  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14245  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14246  * variables, which would magnify even the tiniest violation in the dual multiplier
14247  */
14248  if( stilldualfeasible )
14249  {
14250  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14251  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14252  }
14253  if( stilldualfeasible )
14254  {
14255  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14256  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14257  }
14258 
14259  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14260  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14261  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14262  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14263  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14264  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14265  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14266  dualfeasible != NULL ? stilldualfeasible : TRUE);
14267  }
14268  else
14269  {
14270  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14271  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14272  {
14273  lpicols[c]->redcost = 0.0;
14274  }
14275 
14276  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14277  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14278  * bounds, its reduced cost must be zero
14279  */
14280  if( stilldualfeasible
14281  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
14282  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14283  if( stilldualfeasible
14284  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
14285  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14286 
14287  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14288  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14289  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14290  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14291  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14292  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14293  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14294  dualfeasible != NULL ? stilldualfeasible : TRUE);
14295  }
14296 
14297  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14298  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14299  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14300  */
14301  if( stilldualfeasible )
14302  {
14303  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14304  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14305  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14306  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14307  }
14308  }
14309 
14310  /* copy dual solution and activities into rows */
14311  for( r = 0; r < nlpirows; ++r )
14312  {
14313  assert( 0 <= rstat[r] && rstat[r] < 4 );
14314  lpirows[r]->dualsol = dualsol[r];
14315  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14316  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14317  lpirows[r]->validactivitylp = lpcount;
14318  if( stillprimalfeasible )
14319  {
14320  stillprimalfeasible =
14321  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14322  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14323  }
14324  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14325  {
14326  double compslack;
14327 
14328  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14329  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14330  * variables, which would magnify even the tiniest violation in the dual multiplier
14331  */
14332  if( stilldualfeasible )
14333  {
14334  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14335  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14336  }
14337  if( stilldualfeasible )
14338  {
14339  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14340  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14341  }
14342 
14343  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14344  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14345  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14346  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14347  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14348  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14349  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14350  dualfeasible != NULL ? stilldualfeasible : TRUE);
14351  }
14352  else
14353  {
14354  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14355  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14356  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14357  */
14358  if( stilldualfeasible &&
14359  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
14360  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14361  if( stilldualfeasible &&
14362  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
14363  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14364 
14365  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14366  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14367  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14368  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14369  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14370  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14371  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14372  dualfeasible != NULL ? stilldualfeasible : TRUE);
14373  }
14374 
14375  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14376  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14377  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14378  */
14379  if( stilldualfeasible )
14380  {
14381  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14382  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14383  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14384  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14385  }
14386  }
14387 
14388  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14389  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14390  * infinity
14391  */
14392  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14393  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14394  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14395  {
14396  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14397  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14398  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14399  }
14400 
14401  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14402  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14403  */
14404  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14405  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14406  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14407  {
14408  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14409  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14410  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14411  }
14412 
14413  if( primalfeasible != NULL )
14414  *primalfeasible = stillprimalfeasible;
14415  if( dualfeasible != NULL )
14416  *dualfeasible = stilldualfeasible;
14417 
14418  /* free temporary memory */
14419  SCIPsetFreeBufferArray(set, &rstat);
14420  SCIPsetFreeBufferArray(set, &cstat);
14421  SCIPsetFreeBufferArray(set, &redcost);
14422  SCIPsetFreeBufferArray(set, &activity);
14423  SCIPsetFreeBufferArray(set, &dualsol);
14424  SCIPsetFreeBufferArray(set, &primsol);
14425 
14426  return SCIP_OKAY;
14427 }
14428 
14429 /** stores LP solution with infinite objective value in the columns and rows */
14431  SCIP_LP* lp, /**< current LP data */
14432  SCIP_SET* set, /**< global SCIP settings */
14433  SCIP_STAT* stat, /**< problem statistics */
14434  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14435  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14436  )
14437 {
14438  SCIP_COL** lpicols;
14439  SCIP_ROW** lpirows;
14440  SCIP_Real* primsol;
14441  SCIP_Real* activity;
14442  SCIP_Real* ray;
14443  SCIP_Real rayobjval;
14444  SCIP_Real rayscale;
14445  SCIP_Longint lpcount;
14446  int nlpicols;
14447  int nlpirows;
14448  int c;
14449  int r;
14450 
14451  assert(lp != NULL);
14452  assert(lp->flushed);
14453  assert(lp->solved);
14454  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14455  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14456  assert(set != NULL);
14457  assert(stat != NULL);
14458  assert(lp->validsollp <= stat->lpcount);
14459 
14460  if( primalfeasible != NULL )
14461  *primalfeasible = TRUE;
14462  if( rayfeasible != NULL )
14463  *rayfeasible = TRUE;
14464 
14465  /* check if the values are already calculated */
14466  if( lp->validsollp == stat->lpcount )
14467  return SCIP_OKAY;
14468 
14469  /* check if the LP solver is able to provide a primal unbounded ray */
14470  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14471  {
14472  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14473  return SCIP_LPERROR;
14474  }
14475 
14476  lp->validsollp = stat->lpcount;
14477 
14478  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14479 
14480  /* get temporary memory */
14481  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14482  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14483  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14484 
14485  /* get primal feasible point */
14486  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14487 
14488  /* get primal unbounded ray */
14489  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14490 
14491  lpicols = lp->lpicols;
14492  lpirows = lp->lpirows;
14493  nlpicols = lp->nlpicols;
14494  nlpirows = lp->nlpirows;
14495  lpcount = stat->lpcount;
14496 
14497  /* calculate the objective value decrease of the ray */
14498  rayobjval = 0.0;
14499  for( c = 0; c < nlpicols; ++c )
14500  {
14501  assert(lpicols[c] != NULL);
14502  assert(lpicols[c]->var != NULL);
14503 
14504  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14505  if( rayfeasible != NULL )
14506  *rayfeasible = *rayfeasible
14507  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -lpicols[c]->lb))
14508  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, lpicols[c]->ub));
14509 
14510  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14511  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14512  */
14513  if( primalfeasible != NULL )
14514  *primalfeasible = *primalfeasible
14515  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14516  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14517 
14518  if( !SCIPsetIsZero(set, ray[c]) )
14519  rayobjval += ray[c] * lpicols[c]->obj;
14520  }
14521 
14522  /* if the finite point is already infeasible, we do not have to add the ray */
14523  if( primalfeasible != NULL && !(*primalfeasible) )
14524  {
14525  rayscale = 0.0;
14526  }
14527  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14528  else if( rayfeasible != NULL && !(*rayfeasible) )
14529  {
14530  rayscale = 0.0;
14531  }
14532  /* due to numerical problems, the objective of the ray might be nonnegative,
14533  *
14534  * @todo How to check for negative objective value here?
14535  */
14536  else if( !SCIPsetIsNegative(set, rayobjval) )
14537  {
14538  if( rayfeasible != NULL )
14539  {
14540  *rayfeasible = FALSE;
14541  }
14542 
14543  rayscale = 0.0;
14544  }
14545  else
14546  {
14547  assert(rayobjval != 0.0);
14548 
14549  /* scale the ray, such that the resulting point has infinite objective value */
14550  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14551  assert(SCIPsetIsFeasPositive(set, rayscale));
14552 
14553  /* ensure that unbounded point does not violate the bounds of the variables */
14554  for( c = 0; c < nlpicols; ++c )
14555  {
14556  if( SCIPsetIsPositive(set, ray[c]) )
14557  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14558  else if( SCIPsetIsNegative(set, ray[c]) )
14559  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14560 
14561  assert(SCIPsetIsFeasPositive(set, rayscale));
14562  }
14563  }
14564 
14565  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14566 
14567  /* calculate the unbounded point: x' = x + rayscale * ray */
14568  for( c = 0; c < nlpicols; ++c )
14569  {
14570  if( SCIPsetIsZero(set, ray[c]) )
14571  lpicols[c]->primsol = primsol[c];
14572  else
14573  {
14574  SCIP_Real primsolval = primsol[c] + rayscale * ray[c];
14575  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14576  }
14577  lpicols[c]->redcost = SCIP_INVALID;
14578  lpicols[c]->validredcostlp = -1;
14579  }
14580 
14581  for( r = 0; r < nlpirows; ++r )
14582  {
14583  lpirows[r]->dualsol = SCIP_INVALID;
14584  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14585  lpirows[r]->validactivitylp = lpcount;
14586 
14587  /* check for feasibility of the rows */
14588  if( primalfeasible != NULL )
14589  *primalfeasible = *primalfeasible
14590  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14591  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14592  }
14593 
14594  /* free temporary memory */
14595  SCIPsetFreeBufferArray(set, &ray);
14596  SCIPsetFreeBufferArray(set, &activity);
14597  SCIPsetFreeBufferArray(set, &primsol);
14598 
14599  return SCIP_OKAY;
14600 }
14601 
14602 /** returns primal ray proving the unboundedness of the current LP */
14604  SCIP_LP* lp, /**< current LP data */
14605  SCIP_SET* set, /**< global SCIP settings */
14606  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14607  * so the size of this array should be at least number of active variables
14608  * (all entries have to be initialized to 0 before) */
14609  )
14610 {
14611  SCIP_COL** lpicols;
14612  SCIP_Real* lpiray;
14613  SCIP_VAR* var;
14614  int nlpicols;
14615  int c;
14616 
14617  assert(lp != NULL);
14618  assert(set != NULL);
14619  assert(ray != NULL);
14620  assert(lp->flushed);
14621  assert(lp->solved);
14622  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14623  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14624 
14625  /* check if the LP solver is able to provide a primal unbounded ray */
14626  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14627  {
14628  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14629  return SCIP_LPERROR;
14630  }
14631 
14632  /* get temporary memory */
14633  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14634 
14635  SCIPsetDebugMsg(set, "getting primal ray values\n");
14636 
14637  /* get primal unbounded ray */
14638  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14639 
14640  lpicols = lp->lpicols;
14641  nlpicols = lp->nlpicols;
14642 
14643  /* store the ray values of active problem variables */
14644  for( c = 0; c < nlpicols; c++ )
14645  {
14646  assert(lpicols[c] != NULL);
14647 
14648  var = lpicols[c]->var;
14649  assert(var != NULL);
14650  assert(SCIPvarGetProbindex(var) != -1);
14651  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14652  }
14653 
14654  SCIPsetFreeBufferArray(set, &lpiray);
14655 
14656  return SCIP_OKAY;
14657 }
14658 
14659 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
14660  * lp/checkfarkas = TRUE.
14661  *
14662  * @note the check will not be performed if @p valid is NULL.
14663  */
14665  SCIP_LP* lp, /**< current LP data */
14666  SCIP_SET* set, /**< global SCIP settings */
14667  SCIP_STAT* stat, /**< problem statistics */
14668  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
14669  )
14670 {
14671  SCIP_COL** lpicols;
14672  SCIP_ROW** lpirows;
14673  SCIP_Real* dualfarkas;
14674  SCIP_Real* farkascoefs;
14675  SCIP_Real farkaslhs;
14676  SCIP_Real maxactivity;
14677  SCIP_Bool checkfarkas;
14678  int nlpicols;
14679  int nlpirows;
14680  int c;
14681  int r;
14682 
14683  assert(lp != NULL);
14684  assert(lp->flushed);
14685  assert(lp->solved);
14686  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14687  assert(set != NULL);
14688  assert(stat != NULL);
14689  assert(lp->validfarkaslp <= stat->lpcount);
14690 
14691  if( valid != NULL )
14692  *valid = TRUE;
14693 
14694  /* check if the values are already calculated */
14695  if( lp->validfarkaslp == stat->lpcount )
14696  return SCIP_OKAY;
14697  lp->validfarkaslp = stat->lpcount;
14698 
14699  farkascoefs = NULL;
14700  maxactivity = 0.0;
14701  farkaslhs = 0.0;
14702 
14703  checkfarkas = (set->lp_checkfarkas && valid != NULL);
14704 
14705  /* get temporary memory */
14706  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14707 
14708  if( checkfarkas )
14709  {
14710  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
14711  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
14712  }
14713 
14714  /* get dual Farkas infeasibility proof */
14715  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14716 
14717  lpicols = lp->lpicols;
14718  lpirows = lp->lpirows;
14719  nlpicols = lp->nlpicols;
14720  nlpirows = lp->nlpirows;
14721 
14722  /* store infeasibility proof in rows */
14723  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14724  for( r = 0; r < nlpirows; ++r )
14725  {
14726  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14727  lpirows[r]->dualfarkas = dualfarkas[r];
14728  lpirows[r]->dualsol = SCIP_INVALID;
14729  lpirows[r]->activity = 0.0;
14730  lpirows[r]->validactivitylp = -1L;
14731  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14732 
14733  if( checkfarkas )
14734  {
14735  assert(farkascoefs != NULL);
14736 
14737  /* the infeasibility proof would be invalid if
14738  * (i) dualfarkas[r] > 0 and lhs = -inf
14739  * (ii) dualfarkas[r] < 0 and rhs = inf
14740  * however, due to numerics we accept slightly negative / positive values
14741  */
14742  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
14743  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
14744  {
14745  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
14746  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
14747 
14748  *valid = FALSE; /*lint !e613*/
14749 
14750  goto TERMINATE;
14751  }
14752 
14753  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
14754  * within tolerances (see above) but slighty positive / negative
14755  */
14756  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
14757  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
14758  continue;
14759 
14760  /* iterate over all columns and scale with dual solution */
14761  for( c = 0; c < lpirows[r]->len; c++ )
14762  {
14763  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
14764 
14765  if( pos == -1 )
14766  continue;
14767 
14768  assert(pos >= 0 && pos < nlpicols);
14769 
14770  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
14771  }
14772 
14773  /* the row contributes with its left-hand side to the proof */
14774  if( dualfarkas[r] > 0.0 )
14775  {
14776  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
14777 
14778  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
14779  }
14780  /* the row contributes with its right-hand side to the proof */
14781  else if( dualfarkas[r] < 0.0 )
14782  {
14783  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
14784 
14785  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
14786  }
14787  }
14788  }
14789 
14790  /* set columns as invalid */
14791  for( c = 0; c < nlpicols; ++c )
14792  {
14793  lpicols[c]->primsol = SCIP_INVALID;
14794  lpicols[c]->redcost = SCIP_INVALID;
14795  lpicols[c]->validredcostlp = -1L;
14796  lpicols[c]->validfarkaslp = -1L;
14797 
14798  if( checkfarkas )
14799  {
14800  assert(farkascoefs != NULL);
14801  assert(SCIPcolGetLPPos(lpicols[c]) == c);
14802 
14803  /* skip coefficients that are too close to zero */
14804  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
14805  continue;
14806 
14807  /* calculate the maximal activity */
14808  if( farkascoefs[c] > 0.0 )
14809  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
14810  else
14811  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
14812  }
14813  }
14814 
14815  /* check whether the farkasproof is valid
14816  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
14817  * in that case, we declare the Farkas proof to be invalid.
14818  */
14819  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
14820  {
14821  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
14822 
14823  *valid = FALSE; /*lint !e613*/
14824  }
14825 
14826  TERMINATE:
14827  /* free temporary memory */
14828  if( checkfarkas )
14829  SCIPsetFreeBufferArray(set, &farkascoefs);
14830 
14831  SCIPsetFreeBufferArray(set, &dualfarkas);
14832 
14833  return SCIP_OKAY;
14834 }
14835 
14836 /** get number of iterations used in last LP solve */
14838  SCIP_LP* lp, /**< current LP data */
14839  int* iterations /**< pointer to store the iteration count */
14840  )
14841 {
14842  assert(lp != NULL);
14843 
14844  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14845 
14846  return SCIP_OKAY;
14847 }
14848 
14849 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14850  * resets age of non-zero columns and sharp rows
14851  */
14853  SCIP_LP* lp, /**< current LP data */
14854  SCIP_STAT* stat /**< problem statistics */
14855  )
14856 {
14857  SCIP_COL** lpicols;
14858  SCIP_ROW** lpirows;
14859  int nlpicols;
14860  int nlpirows;
14861  int c;
14862  int r;
14863 
14864  assert(lp != NULL);
14865  assert(lp->flushed);
14866  assert(lp->solved);
14867  assert(lp->nlpicols == lp->ncols);
14868  assert(lp->nlpirows == lp->nrows);
14869  assert(stat != NULL);
14870  assert(lp->validsollp == stat->lpcount);
14871 
14872  SCIPdebugMessage("updating LP ages\n");
14873 
14874  lpicols = lp->lpicols;
14875  lpirows = lp->lpirows;
14876  nlpicols = lp->nlpicols;
14877  nlpirows = lp->nlpirows;
14878 
14879  for( c = 0; c < nlpicols; ++c )
14880  {
14881  assert(lpicols[c] == lp->cols[c]);
14882  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14883  lpicols[c]->age++;
14884  else
14885  lpicols[c]->age = 0;
14886  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14887  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14888  }
14889 
14890  for( r = 0; r < nlpirows; ++r )
14891  {
14892  lpirows[r]->nlpsaftercreation++;
14893  assert(lpirows[r] == lp->rows[r]);
14894 
14895  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14896  {
14897  lpirows[r]->age++;
14898  }
14899  else
14900  {
14901  lpirows[r]->activeinlpcounter++;
14902  lpirows[r]->age = 0;
14903  }
14904  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14905  }
14906 
14907  return SCIP_OKAY;
14908 }
14909 
14910 /* deletes the marked columns from the LP and the LP interface */
14911 static
14913  SCIP_LP* lp, /**< current LP data */
14914  SCIP_SET* set, /**< global SCIP settings */
14915  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
14916  )
14917 {
14918  SCIP_COL* col;
14919  int ncols;
14920  int c;
14921 
14922  assert(lp != NULL);
14923  assert(lp->flushed);
14924  assert(lp->ncols == lp->nlpicols);
14925  assert(!lp->diving);
14926  assert(coldstat != NULL);
14927  assert(lp->nlazycols <= lp->ncols);
14928 
14929  ncols = lp->ncols;
14930 
14931  /* delete columns in LP solver */
14932  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
14933 
14934  /* update LP data respectively */
14935  for( c = 0; c < ncols; ++c )
14936  {
14937  col = lp->cols[c];
14938  assert(col != NULL);
14939  assert(col == lp->lpicols[c]);
14940  assert(coldstat[c] <= c);
14941  col->lppos = coldstat[c];
14942  if( coldstat[c] == -1 )
14943  {
14944  assert(col->removable);
14945 
14946  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
14947  * function vector norms
14948  */
14949  markColDeleted(col);
14950  colUpdateDelLP(col, set);
14951  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
14952  col->lpdepth = -1;
14953 
14954  lp->cols[c] = NULL;
14955  lp->lpicols[c] = NULL;
14956  lp->ncols--;
14957  lp->nremovablecols--;
14958  lp->nlpicols--;
14959  }
14960  else if( coldstat[c] < c )
14961  {
14962  assert(lp->cols[coldstat[c]] == NULL);
14963  assert(lp->lpicols[coldstat[c]] == NULL);
14964  lp->cols[coldstat[c]] = col;
14965  lp->lpicols[coldstat[c]] = col;
14966  lp->cols[coldstat[c]]->lppos = coldstat[c];
14967  lp->cols[coldstat[c]]->lpipos = coldstat[c];
14968  lp->cols[c] = NULL;
14969  lp->lpicols[c] = NULL;
14970  }
14971  }
14972 
14973  /* remove columns which are deleted from the lazy column array */
14974  c = 0;
14975  while( c < lp->nlazycols )
14976  {
14977  if( lp->lazycols[c]->lpipos < 0 )
14978  {
14979  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
14980  lp->nlazycols--;
14981  }
14982  else
14983  c++;
14984  }
14985 
14986  /* mark LP to be unsolved */
14987  if( lp->ncols < ncols )
14988  {
14989  assert(lp->ncols == lp->nlpicols);
14990  assert(lp->nchgcols == 0);
14991  assert(lp->flushed);
14992 
14993  lp->lpifirstchgcol = lp->nlpicols;
14994 
14995  /* mark the current solution invalid */
14996  lp->solved = FALSE;
14997  lp->primalfeasible = FALSE;
14998  lp->primalchecked = FALSE;
14999  lp->lpobjval = SCIP_INVALID;
15001  }
15002 
15003  checkLazyColArray(lp, set);
15004  checkLinks(lp);
15005 
15006  return SCIP_OKAY;
15007 }
15008 
15009 /* deletes the marked rows from the LP and the LP interface */
15010 static
15012  SCIP_LP* lp, /**< current LP data */
15013  BMS_BLKMEM* blkmem, /**< block memory buffers */
15014  SCIP_SET* set, /**< global SCIP settings */
15015  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15016  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15017  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15018  )
15019 {
15020  SCIP_ROW* row;
15021  int nrows;
15022  int r;
15023 
15024  assert(lp != NULL);
15025  assert(lp->flushed);
15026  assert(lp->nrows == lp->nlpirows);
15027  assert(!lp->diving);
15028  assert(rowdstat != NULL);
15029 
15030  nrows = lp->nrows;
15031 
15032  /* delete rows in LP solver */
15033  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15034 
15035  /* update LP data respectively */
15036  for( r = 0; r < nrows; ++r )
15037  {
15038  row = lp->rows[r];
15039  assert(row == lp->lpirows[r]);
15040  assert(rowdstat[r] <= r);
15041  assert(row != NULL);
15042  row->lppos = rowdstat[r];
15043  if( rowdstat[r] == -1 )
15044  {
15045  if( row->removable )
15046  lp->nremovablerows--;
15047 
15048  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15049  markRowDeleted(row);
15050  rowUpdateDelLP(row);
15051  row->lpdepth = -1;
15052 
15053  /* check, if row deletion events are tracked
15054  * if so, issue ROWDELETEDLP event
15055  */
15056  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15057  {
15058  SCIP_EVENT* event;
15059 
15060  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15061  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15062  }
15063 
15064  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15065  SCIProwUnlock(lp->rows[r]);
15066  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15067  assert(lp->lpirows[r] == NULL);
15068  assert(lp->rows[r] == NULL);
15069  lp->nrows--;
15070  lp->nlpirows--;
15071  }
15072  else if( rowdstat[r] < r )
15073  {
15074  assert(lp->rows[rowdstat[r]] == NULL);
15075  assert(lp->lpirows[rowdstat[r]] == NULL);
15076  lp->rows[rowdstat[r]] = row;
15077  lp->lpirows[rowdstat[r]] = row;
15078  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15079  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15080  lp->rows[r] = NULL;
15081  lp->lpirows[r] = NULL;
15082  }
15083  }
15084 
15085  /* mark LP to be unsolved */
15086  if( lp->nrows < nrows )
15087  {
15088  assert(lp->nrows == lp->nlpirows);
15089  assert(lp->nchgrows == 0);
15090  assert(lp->flushed);
15091 
15092  lp->lpifirstchgrow = lp->nlpirows;
15093 
15094  /* mark the current solution invalid */
15095  lp->solved = FALSE;
15096  lp->dualfeasible = FALSE;
15097  lp->dualchecked = FALSE;
15098  lp->lpobjval = SCIP_INVALID;
15100  }
15101 
15102  checkLinks(lp);
15103 
15104  return SCIP_OKAY;
15105 }
15106 
15107 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15108 static
15110  SCIP_LP* lp, /**< current LP data */
15111  SCIP_SET* set, /**< global SCIP settings */
15112  SCIP_STAT* stat, /**< problem statistics */
15113  int firstcol /**< first column to check for clean up */
15114  )
15115 {
15116  SCIP_COL** cols;
15117 #ifndef NDEBUG
15118  SCIP_COL** lpicols;
15119 #endif
15120  int* coldstat;
15121  int ncols;
15122  int ndelcols;
15123  int c;
15124 
15125  assert(lp != NULL);
15126  assert(lp->flushed);
15127  assert(lp->ncols == lp->nlpicols);
15128  assert(lp->nremovablecols <= lp->ncols);
15129  assert(!lp->diving);
15130  assert(set != NULL);
15131  assert(stat != NULL);
15132 
15133  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15134  return SCIP_OKAY;
15135 
15136  ncols = lp->ncols;
15137  cols = lp->cols;
15138 #ifndef NDEBUG
15139  lpicols = lp->lpicols;
15140 #endif
15141 
15142  /* get temporary memory */
15143  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15144 
15145  /* mark obsolete columns to be deleted */
15146  ndelcols = 0;
15147  BMSclearMemoryArray(coldstat, ncols);
15148  for( c = firstcol; c < ncols; ++c )
15149  {
15150  assert(cols[c] == lpicols[c]);
15151  assert(cols[c]->lppos == c);
15152  assert(cols[c]->lpipos == c);
15153  if( cols[c]->removable
15154  && 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 */
15155  && cols[c]->age > set->lp_colagelimit
15157  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15158  {
15159  assert(cols[c]->primsol == 0.0);
15160  coldstat[c] = 1;
15161  ndelcols++;
15162  cols[c]->obsoletenode = stat->nnodes;
15163  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15164  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15165  }
15166  }
15167 
15168  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15169 
15170  /* delete the marked columns in the LP solver interface, update the LP respectively */
15171  if( ndelcols > 0 )
15172  {
15173  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15174  }
15175  assert(lp->ncols == ncols - ndelcols);
15176 
15177  /* release temporary memory */
15178  SCIPsetFreeBufferArray(set, &coldstat);
15179 
15180  return SCIP_OKAY;
15181 }
15182 
15183 /** removes all basic rows, that are too old, beginning with the given firstrow */
15184 static
15186  SCIP_LP* lp, /**< current LP data */
15187  BMS_BLKMEM* blkmem, /**< block memory buffers */
15188  SCIP_SET* set, /**< global SCIP settings */
15189  SCIP_STAT* stat, /**< problem statistics */
15190  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15191  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15192  int firstrow /**< first row to check for clean up */
15193  )
15194 {
15195  SCIP_ROW** rows;
15196 #ifndef NDEBUG
15197  SCIP_ROW** lpirows;
15198 #endif
15199  int* rowdstat;
15200  int nrows;
15201  int ndelrows;
15202  int r;
15203 
15204  assert(lp != NULL);
15205  assert(lp->flushed);
15206  assert(lp->nrows == lp->nlpirows);
15207  assert(lp->nremovablerows <= lp->nrows);
15208  assert(!lp->diving);
15209  assert(set != NULL);
15210  assert(stat != NULL);
15211 
15212  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15213  return SCIP_OKAY;
15214 
15215  nrows = lp->nrows;
15216  rows = lp->rows;
15217 #ifndef NDEBUG
15218  lpirows = lp->lpirows;
15219 #endif
15220 
15221  /* get temporary memory */
15222  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15223 
15224  /* mark obsolete rows to be deleted */
15225  ndelrows = 0;
15226  BMSclearMemoryArray(rowdstat, nrows);
15227  for( r = firstrow; r < nrows; ++r )
15228  {
15229  assert(rows[r] == lpirows[r]);
15230  assert(rows[r]->lppos == r);
15231  assert(rows[r]->lpipos == r);
15232  if( rows[r]->removable
15233  && 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 */
15234  && rows[r]->age > set->lp_rowagelimit
15236  {
15237  rowdstat[r] = 1;
15238  ndelrows++;
15239  rows[r]->obsoletenode = stat->nnodes;
15240  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15241  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15242  }
15243  }
15244 
15245  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15246 
15247  /* delete the marked rows in the LP solver interface, update the LP respectively */
15248  if( ndelrows > 0 )
15249  {
15250  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15251  }
15252  assert(lp->nrows == nrows - ndelrows);
15253 
15254  /* release temporary memory */
15255  SCIPsetFreeBufferArray(set, &rowdstat);
15256 
15257  return SCIP_OKAY;
15258 }
15259 
15260 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15262  SCIP_LP* lp, /**< current LP data */
15263  BMS_BLKMEM* blkmem, /**< block memory buffers */
15264  SCIP_SET* set, /**< global SCIP settings */
15265  SCIP_STAT* stat, /**< problem statistics */
15266  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15267  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15268  )
15269 {
15270  assert(lp != NULL);
15271  assert(lp->solved);
15272  assert(!lp->diving);
15274  assert(set != NULL);
15275 
15276  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15277  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15278 
15279  if( lp->firstnewcol < lp->ncols )
15280  {
15281  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15282  }
15283  if( lp->firstnewrow < lp->nrows )
15284  {
15285  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15286  }
15287 
15288  return SCIP_OKAY;
15289 }
15290 
15291 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15293  SCIP_LP* lp, /**< current LP data */
15294  BMS_BLKMEM* blkmem, /**< block memory buffers */
15295  SCIP_SET* set, /**< global SCIP settings */
15296  SCIP_STAT* stat, /**< problem statistics */
15297  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15298  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15299  )
15300 {
15301  assert(lp != NULL);
15302  assert(lp->solved);
15303  assert(!lp->diving);
15305  assert(set != NULL);
15306 
15307  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15308 
15309  if( 0 < lp->ncols )
15310  {
15311  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15312  }
15313  if( 0 < lp->nrows )
15314  {
15315  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15316  }
15317 
15318  return SCIP_OKAY;
15319 }
15320 
15321 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15322 static
15324  SCIP_LP* lp, /**< current LP data */
15325  SCIP_SET* set, /**< global SCIP settings */
15326  SCIP_STAT* stat, /**< problem statistics */
15327  int firstcol /**< first column to check for clean up */
15328  )
15329 {
15330  SCIP_COL** cols;
15331  SCIP_COL** lpicols;
15332  int* coldstat;
15333  int ncols;
15334  int ndelcols;
15335  int c;
15336 
15337  assert(lp != NULL);
15338  assert(lp->flushed);
15339  assert(lp->ncols == lp->nlpicols);
15340  assert(!lp->diving);
15341  assert(stat != NULL);
15342  assert(lp->validsollp == stat->lpcount);
15343  assert(0 <= firstcol && firstcol < lp->ncols);
15344 
15345  if( lp->nremovablecols == 0 || !lp->solisbasic )
15346  return SCIP_OKAY;
15347 
15348  ncols = lp->ncols;
15349  cols = lp->cols;
15350  lpicols = lp->lpicols;
15351 
15352  /* get temporary memory */
15353  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15354 
15355  /* mark unused columns to be deleted */
15356  ndelcols = 0;
15357  BMSclearMemoryArray(coldstat, ncols);
15358  for( c = firstcol; c < ncols; ++c )
15359  {
15360  assert(cols[c] == lpicols[c]);
15361  assert(cols[c]->lppos == c);
15362  assert(cols[c]->lpipos == c);
15363  if( lpicols[c]->removable
15364  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15365  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15366  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15367  {
15368  coldstat[c] = 1;
15369  ndelcols++;
15370  }
15371  }
15372 
15373  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15374 
15375  /* delete the marked columns in the LP solver interface, update the LP respectively */
15376  if( ndelcols > 0 )
15377  {
15378  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15379  }
15380  assert(lp->ncols == ncols - ndelcols);
15381 
15382  /* release temporary memory */
15383  SCIPsetFreeBufferArray(set, &coldstat);
15384 
15385  return SCIP_OKAY;
15386 }
15387 
15388 /** removes all basic rows beginning with the given firstrow */
15389 static
15391  SCIP_LP* lp, /**< current LP data */
15392  BMS_BLKMEM* blkmem, /**< block memory buffers */
15393  SCIP_SET* set, /**< global SCIP settings */
15394  SCIP_STAT* stat, /**< problem statistics */
15395  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15396  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15397  int firstrow /**< first row to check for clean up */
15398  )
15399 {
15400 #ifndef NDEBUG
15401  SCIP_ROW** rows;
15402 #endif
15403  SCIP_ROW** lpirows;
15404  int* rowdstat;
15405  int nrows;
15406  int ndelrows;
15407  int r;
15408 
15409  assert(lp != NULL);
15410  assert(lp->flushed);
15411  assert(lp->ncols == lp->nlpicols);
15412  assert(lp->nrows == lp->nlpirows);
15413  assert(!lp->diving);
15414  assert(stat != NULL);
15415  assert(lp->validsollp == stat->lpcount);
15416  assert(0 <= firstrow && firstrow < lp->nrows);
15417 
15418  if( lp->nremovablerows == 0 || !lp->solisbasic )
15419  return SCIP_OKAY;
15420 
15421 #ifndef NDEBUG
15422  rows = lp->rows;
15423 #endif
15424  nrows = lp->nrows;
15425  lpirows = lp->lpirows;
15426 
15427  /* get temporary memory */
15428  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15429 
15430  /* mark unused rows to be deleted */
15431  ndelrows = 0;
15432  BMSclearMemoryArray(rowdstat, nrows);
15433  for( r = firstrow; r < nrows; ++r )
15434  {
15435  assert(rows[r] == lpirows[r]);
15436  assert(rows[r]->lppos == r);
15437  assert(rows[r]->lpipos == r);
15438  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15439  {
15440  rowdstat[r] = 1;
15441  ndelrows++;
15442  }
15443  }
15444 
15445  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15446 
15447  /* delete the marked rows in the LP solver interface, update the LP respectively */
15448  if( ndelrows > 0 )
15449  {
15450  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15451  }
15452  assert(lp->nrows == nrows - ndelrows);
15453 
15454  /* release temporary memory */
15455  SCIPsetFreeBufferArray(set, &rowdstat);
15456 
15457  return SCIP_OKAY;
15458 }
15459 
15460 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15462  SCIP_LP* lp, /**< current LP data */
15463  BMS_BLKMEM* blkmem, /**< block memory buffers */
15464  SCIP_SET* set, /**< global SCIP settings */
15465  SCIP_STAT* stat, /**< problem statistics */
15466  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15467  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15468  SCIP_Bool root /**< are we at the root node? */
15469  )
15470 {
15471  SCIP_Bool cleanupcols;
15472  SCIP_Bool cleanuprows;
15473 
15474  assert(lp != NULL);
15475  assert(lp->solved);
15476  assert(!lp->diving);
15478  assert(set != NULL);
15479 
15480  /* check, if we want to clean up the columns and rows */
15481  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15482  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15483 
15484  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15485  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15486 
15487  if( cleanupcols && lp->firstnewcol < lp->ncols )
15488  {
15489  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15490  }
15491  if( cleanuprows && lp->firstnewrow < lp->nrows )
15492  {
15493  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15494  }
15495 
15496  return SCIP_OKAY;
15497 }
15498 
15499 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15501  SCIP_LP* lp, /**< current LP data */
15502  BMS_BLKMEM* blkmem, /**< block memory buffers */
15503  SCIP_SET* set, /**< global SCIP settings */
15504  SCIP_STAT* stat, /**< problem statistics */
15505  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15506  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15507  SCIP_Bool root /**< are we at the root node? */
15508  )
15509 {
15510  SCIP_Bool cleanupcols;
15511  SCIP_Bool cleanuprows;
15512 
15513  assert(lp != NULL);
15514  assert(lp->solved);
15515  assert(!lp->diving);
15517  assert(set != NULL);
15518 
15519  /* check, if we want to clean up the columns and rows */
15520  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15521  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15522 
15523  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15524  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15525 
15526  if( cleanupcols && 0 < lp->ncols )
15527  {
15528  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15529  }
15530  if( cleanuprows && 0 < lp->nrows )
15531  {
15532  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15533  }
15534 
15535  return SCIP_OKAY;
15536 }
15537 
15538 /** removes all redundant rows that were added at the current node */
15540  SCIP_LP* lp, /**< current LP data */
15541  BMS_BLKMEM* blkmem, /**< block memory buffers */
15542  SCIP_SET* set, /**< global SCIP settings */
15543  SCIP_STAT* stat, /**< problem statistics */
15544  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15545  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15546  )
15547 {
15548 #ifndef NDEBUG
15549  SCIP_ROW** rows;
15550 #endif
15551  SCIP_ROW** lpirows;
15552  int* rowdstat;
15553  int nrows;
15554  int ndelrows;
15555  int r;
15556 
15557  assert(lp != NULL);
15558  assert(lp->flushed);
15559  assert(lp->ncols == lp->nlpicols);
15560  assert(lp->nrows == lp->nlpirows);
15561  assert(!lp->diving);
15562  assert(stat != NULL);
15563  assert(lp->validsollp == stat->lpcount);
15564  assert(lp->firstnewrow <= lp->nrows);
15565 
15566  if( lp->firstnewrow == lp->nrows )
15567  return SCIP_OKAY;
15568 
15569 #ifndef NDEBUG
15570  rows = lp->rows;
15571 #endif
15572  nrows = lp->nrows;
15573  lpirows = lp->lpirows;
15574 
15575  /* get temporary memory */
15576  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15577 
15578  /* mark redundant rows to be deleted (only delete basic rows!) */
15579  ndelrows = 0;
15580  BMSclearMemoryArray(rowdstat, nrows);
15581  for( r = lp->firstnewrow; r < nrows; ++r )
15582  {
15583  assert(rows[r] == lpirows[r]);
15584  assert(rows[r]->lppos == r);
15585  assert(rows[r]->lpipos == r);
15586  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15587  && SCIProwIsRedundant(lpirows[r], set, stat) )
15588  {
15589  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15590  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15591  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15592  rowdstat[r] = 1;
15593  ndelrows++;
15594  }
15595  }
15596 
15597  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15598 
15599  /* delete the marked rows in the LP solver interface, update the LP respectively */
15600  if( ndelrows > 0 )
15601  {
15602  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15603  }
15604  assert(lp->nrows == nrows - ndelrows);
15605 
15606  /* release temporary memory */
15607  SCIPsetFreeBufferArray(set, &rowdstat);
15608 
15609  return SCIP_OKAY;
15610 }
15611 
15612 /** initiates LP diving */
15614  SCIP_LP* lp, /**< current LP data */
15615  BMS_BLKMEM* blkmem, /**< block memory */
15616  SCIP_SET* set, /**< global SCIP settings */
15617  SCIP_STAT* stat /**< problem statistics */
15618  )
15619 {
15620  int c;
15621  int r;
15622 
15623  assert(lp != NULL);
15624  assert(lp->flushed || !lp->solved);
15625  assert(!lp->diving);
15626  assert(!lp->probing);
15627  assert(lp->divelpistate == NULL);
15628  assert(lp->divelpwasprimfeas);
15629  assert(lp->divelpwasdualfeas);
15630  assert(lp->validsollp <= stat->lpcount);
15631  assert(blkmem != NULL);
15632  assert(set != NULL);
15633  assert(lp->ndivechgsides == 0);
15634 
15635  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15636  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15637 
15638 #ifndef NDEBUG
15639  for( c = 0; c < lp->ncols; ++c )
15640  {
15641  assert(lp->cols[c] != NULL);
15642  assert(lp->cols[c]->var != NULL);
15643  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15644  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15645  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15646  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15647  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15648  }
15649 #endif
15650 
15651  /* save current LPI state (basis information) */
15652  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15654  lp->divelpwasdualfeas = lp->dualfeasible;
15657 
15658  /* save current LP values dependent on the solution */
15659  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15660  assert(lp->storedsolvals != NULL);
15661  if( !set->lp_resolverestore && lp->solved )
15662  {
15663  SCIP_Bool store = TRUE;
15664 
15665  switch ( lp->lpsolstat )
15666  {
15668  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15669  assert(lp->validsollp == stat->lpcount);
15670  break;
15672  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15673  assert(lp->validsollp == stat->lpcount);
15674  break;
15678  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15679  assert(lp->validsollp == stat->lpcount);
15680  break;
15682  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
15683  break;
15685  case SCIP_LPSOLSTAT_ERROR:
15686  default:
15687  store = FALSE;
15688  }
15689 
15690  if ( store )
15691  {
15692  for( c = 0; c < lp->ncols; ++c )
15693  {
15694  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15695  }
15696  for( r = 0; r < lp->nrows; ++r )
15697  {
15699  }
15700  }
15701  }
15702 
15703  /* store LPI iteration limit */
15705 
15706  /* remember the number of domain changes */
15707  lp->divenolddomchgs = stat->domchgcount;
15708 
15709  /* store current number of rows */
15710  lp->ndivingrows = lp->nrows;
15711 
15712  /* switch to diving mode */
15713  lp->diving = TRUE;
15714 
15715  return SCIP_OKAY;
15716 }
15717 
15718 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15720  SCIP_LP* lp, /**< current LP data */
15721  BMS_BLKMEM* blkmem, /**< block memory */
15722  SCIP_SET* set, /**< global SCIP settings */
15723  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15724  SCIP_STAT* stat, /**< problem statistics */
15725  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15726  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15727  SCIP_PROB* prob, /**< problem data */
15728  SCIP_VAR** vars, /**< array with all active variables */
15729  int nvars /**< number of active variables */
15730  )
15731 {
15732  SCIP_VAR* var;
15733  int v;
15734 
15735  assert(lp != NULL);
15736  assert(lp->diving);
15737  assert(blkmem != NULL);
15738  assert(nvars == 0 || vars != NULL);
15739 
15740  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15741 
15742  /* reset all columns' objective values and bounds to its original values */
15743  for( v = 0; v < nvars; ++v )
15744  {
15745  var = vars[v];
15746  assert(var != NULL);
15748  {
15749  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15750  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15751  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15752  }
15753  }
15754 
15755  /* remove rows which were added in diving mode */
15756  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15757 
15758  /* undo changes to left hand sides and right hand sides */
15759  while( lp->ndivechgsides > 0 )
15760  {
15761  SCIP_Real oldside;
15762  SCIP_SIDETYPE sidetype;
15763  SCIP_ROW* row;
15764 
15765  lp->ndivechgsides--;
15766  oldside = lp->divechgsides[lp->ndivechgsides];
15767  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15768  row = lp->divechgrows[lp->ndivechgsides];
15769 
15770  if( sidetype == SCIP_SIDETYPE_LEFT )
15771  {
15772  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15773  }
15774  else
15775  {
15776  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15777  }
15778  }
15779 
15780  /* restore LPI iteration limit */
15782 
15783  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15784  * happens
15785  */
15786  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15788  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15789  lp->divelpwasprimfeas = TRUE;
15790  lp->divelpwasdualfeas = TRUE;
15791  lp->divelpwasprimchecked = TRUE;
15792  lp->divelpwasdualchecked = TRUE;
15793  assert(lp->divelpistate == NULL);
15794 
15795  /* switch to standard (non-diving) mode */
15796  lp->diving = FALSE;
15797  lp->divingobjchg = FALSE;
15798 
15799  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15800  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15801  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15802  * the parameter resolverestore to TRUE
15803  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15804  */
15805  assert(lp->storedsolvals != NULL);
15806  if( lp->storedsolvals->lpissolved
15807  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
15808  {
15809  SCIP_Bool lperror;
15810 
15811  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15812  if( lperror )
15813  {
15814  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
15815  lp->resolvelperror = TRUE;
15816  }
15821  {
15822  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15823  "LP was not resolved to a sufficient status after diving\n");
15824  lp->resolvelperror = TRUE;
15825  }
15826  }
15827  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15828  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15829  * re-solve as above can lead to a different LP status
15830  */
15831  else
15832  {
15833  int c;
15834  int r;
15835 
15836  /* if there are lazy bounds, remove them from the LP */
15837  if( lp->nlazycols > 0 )
15838  {
15839  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15840  * first resolve LP?
15841  */
15842  SCIP_CALL( updateLazyBounds(lp, set) );
15843  assert(lp->diving == lp->divinglazyapplied);
15844 
15845  /* flush changes to the LP solver */
15846  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15847  }
15848 
15849  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15850  SCIPstatIncrement(stat, set, lpcount);
15851 
15852  /* restore LP solution values in lp data, columns and rows */
15853  if( lp->storedsolvals->lpissolved &&
15860  )
15861  {
15862  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15863 
15864  for( c = 0; c < lp->ncols; ++c )
15865  {
15866  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15867  }
15868  for( r = 0; r < lp->nrows; ++r )
15869  {
15870  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15871  }
15872  }
15873  else
15874  {
15875  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15876  }
15877  }
15878 
15879 #ifndef NDEBUG
15880  {
15881  int c;
15882  for( c = 0; c < lp->ncols; ++c )
15883  {
15884  assert(lp->cols[c] != NULL);
15885  assert(lp->cols[c]->var != NULL);
15886  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15887  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15888  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15889  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15890  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15891  }
15892  }
15893 #endif
15894 
15895  return SCIP_OKAY;
15896 }
15897 
15898 #define DIVESTACKGROWFACT 1.5
15899 
15900 /** records a current row side such that any change will be undone after diving */
15902  SCIP_LP* lp, /**< LP data object */
15903  SCIP_ROW* row, /**< row affected by the change */
15904  SCIP_SIDETYPE sidetype /**< side type */
15905  )
15906 {
15907  assert(lp != NULL);
15908  assert(row != NULL);
15909 
15910  if( lp->ndivechgsides == lp->divechgsidessize )
15911  {
15913  }
15914  assert(lp->ndivechgsides < lp->divechgsidessize);
15915 
15916  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
15917  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
15918  lp->divechgrows[lp->ndivechgsides] = row;
15919  lp->ndivechgsides++;
15920 
15921  return SCIP_OKAY;
15922 }
15923 
15924 /** informs the LP that probing mode was initiated */
15926  SCIP_LP* lp /**< current LP data */
15927  )
15928 {
15929  assert(lp != NULL);
15930  assert(!lp->probing);
15931  assert(!lp->strongbranching);
15932  assert(!lp->strongbranchprobing);
15933 
15934  lp->probing = TRUE;
15935 
15936  return SCIP_OKAY;
15937 }
15938 
15939 /** informs the LP that probing mode was finished */
15941  SCIP_LP* lp /**< current LP data */
15942  )
15943 {
15944  assert(lp != NULL);
15945  assert(lp->probing);
15946  assert(!lp->strongbranching);
15947  assert(!lp->strongbranchprobing);
15948 
15949  lp->probing = FALSE;
15950 
15951  return SCIP_OKAY;
15952 }
15953 
15954 /** informs the LP that the probing mode is now used for strongbranching */
15956  SCIP_LP* lp /**< current LP data */
15957  )
15958 {
15959  assert(lp != NULL);
15960  assert(lp->probing);
15961  assert(!lp->strongbranching);
15962  assert(!lp->strongbranchprobing);
15963 
15964  lp->strongbranchprobing = TRUE;
15965 }
15966 
15967 /** informs the LP that the probing mode is not used for strongbranching anymore */
15969  SCIP_LP* lp /**< current LP data */
15970  )
15971 {
15972  assert(lp != NULL);
15973  assert(lp->probing);
15974  assert(!lp->strongbranching);
15975  assert(lp->strongbranchprobing);
15976 
15977  lp->strongbranchprobing = FALSE;
15978 }
15979 
15980 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
15981  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
15982  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
15983  * we have only left hand sides):
15984  * min{cx | b <= Ax, lb <= x <= ub}
15985  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
15986  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
15987  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
15988  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
15989  */
15990 static
15992  SCIP_LP* lp, /**< current LP data */
15993  SCIP_SET* set, /**< global SCIP settings */
15994  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
15995  SCIP_Real* bound /**< result of interval arithmetic minimization */
15996  )
15997 {
15998  SCIP_INTERVAL* yinter;
15999  SCIP_INTERVAL b;
16000  SCIP_INTERVAL ytb;
16001  SCIP_INTERVAL prod;
16002  SCIP_INTERVAL diff;
16003  SCIP_INTERVAL x;
16004  SCIP_INTERVAL minprod;
16005  SCIP_INTERVAL a;
16006  SCIP_ROW* row;
16007  SCIP_COL* col;
16008  SCIP_Real y;
16009  SCIP_Real c;
16010  int i;
16011  int j;
16012 
16013  assert(lp != NULL);
16014  assert(lp->solved);
16015  assert(set != NULL);
16016  assert(bound != NULL);
16017 
16018  /* allocate buffer for storing y in interval arithmetic */
16019  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16020 
16021  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16022  SCIPintervalSet(&ytb, 0.0);
16023  for( j = 0; j < lp->nrows; ++j )
16024  {
16025  row = lp->rows[j];
16026  assert(row != NULL);
16027 
16028  y = (usefarkas ? row->dualfarkas : row->dualsol);
16029 
16030  if( SCIPsetIsFeasPositive(set, y) )
16031  {
16032  SCIPintervalSet(&yinter[j], y);
16033  SCIPintervalSet(&b, row->lhs - row->constant);
16034  }
16035  else if( SCIPsetIsFeasNegative(set, y) )
16036  {
16037  SCIPintervalSet(&yinter[j], y);
16038  SCIPintervalSet(&b, row->rhs - row->constant);
16039  }
16040  else
16041  {
16042  SCIPintervalSet(&yinter[j], 0.0);
16043  SCIPintervalSet(&b, 0.0);
16044  }
16045 
16046  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16047  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16048  }
16049 
16050  /* calculate min{(c^T - y^TA)x} */
16051  SCIPintervalSet(&minprod, 0.0);
16052  for( j = 0; j < lp->ncols; ++j )
16053  {
16054  col = lp->cols[j];
16055  assert(col != NULL);
16056  assert(col->nunlinked == 0);
16057 
16059 
16060  c = usefarkas ? 0.0 : col->obj;
16061  SCIPintervalSet(&diff, c);
16062 
16063  for( i = 0; i < col->nlprows; ++i )
16064  {
16065  assert(col->rows[i] != NULL);
16066  assert(col->rows[i]->lppos >= 0);
16067  assert(col->linkpos[i] >= 0);
16068  SCIPintervalSet(&a, col->vals[i]);
16069  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16070  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16071  }
16072 
16073 #ifndef NDEBUG
16074  for( i = col->nlprows; i < col->len; ++i )
16075  {
16076  assert(col->rows[i] != NULL);
16077  assert(col->rows[i]->lppos == -1);
16078  assert(col->rows[i]->dualsol == 0.0);
16079  assert(col->rows[i]->dualfarkas == 0.0);
16080  assert(col->linkpos[i] >= 0);
16081  }
16082 #endif
16083 
16084  SCIPintervalSetBounds(&x, col->lb, col->ub);
16085  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16086  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16087  }
16088 
16089  /* add y^Tb */
16090  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16091 
16092  /* free buffer for storing y in interval arithmetic */
16093  SCIPsetFreeBufferArray(set, &yinter);
16094 
16095  *bound = SCIPintervalGetInf(minprod);
16096 
16097  return SCIP_OKAY;
16098 }
16099 
16100 /** gets proven lower (dual) bound of last LP solution */
16102  SCIP_LP* lp, /**< current LP data */
16103  SCIP_SET* set, /**< global SCIP settings */
16104  SCIP_Real* bound /**< pointer to store proven dual bound */
16105  )
16106 {
16107  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16108 
16109  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16110 
16111  return SCIP_OKAY;
16112 }
16113 
16114 /** gets proven dual bound of last LP solution */
16116  SCIP_LP* lp, /**< current LP data */
16117  SCIP_SET* set, /**< global SCIP settings */
16118  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16119  )
16120 {
16121  SCIP_Real bound;
16122 
16123  assert(proved != NULL);
16124 
16125  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16126 
16127  *proved = (bound > 0.0);
16128 
16129  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16130 
16131  return SCIP_OKAY;
16132 }
16133 
16134 
16135 
16136 /** writes LP to a file */
16138  SCIP_LP* lp, /**< current LP data */
16139  const char* fname /**< file name */
16140  )
16141 {
16142  assert(lp != NULL);
16143  assert(lp->flushed);
16144  assert(fname != NULL);
16145 
16146  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16147 
16148  return SCIP_OKAY;
16149 }
16150 
16151 /** writes MIP relaxation of the current B&B node to a file */
16153  SCIP_LP* lp, /**< current LP data */
16154  SCIP_SET* set, /**< global SCIP settings */
16155  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16156  const char* fname, /**< file name */
16157  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16158  * troubles with reserved symbols? */
16159  SCIP_Bool origobj, /**< should the original objective function be used? */
16160  SCIP_OBJSENSE objsense, /**< objective sense */
16161  SCIP_Real objscale, /**< objective scaling factor */
16162  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16163  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16164  )
16165 {
16166  FILE* file;
16167  int i;
16168  int j;
16169  char rowname[SCIP_MAXSTRLEN];
16170  SCIP_Real coeff;
16171 
16172  assert(lp != NULL);
16173  assert(lp->flushed);
16174  assert(fname != NULL);
16175 
16176  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16177  file = fopen(fname, "w");
16178  if( file == NULL )
16179  {
16180  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16181  SCIPprintSysError(fname);
16182  return SCIP_FILECREATEERROR;
16183  }
16184 
16185  /* print comments */
16186  if( genericnames )
16187  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16188  else
16189  {
16190  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16191  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16192  }
16193 
16194  if( origobj && objoffset != 0.0 )
16195  {
16196  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16197  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16198  }
16199 
16200  /* print objective function */
16201  /**@note the transformed problem in SCIP is always a minimization problem */
16202  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16203  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16204  else
16205  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16206 
16207  /* print objective */
16208  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16209  j = 0;
16210  for( i = 0; i < lp->ncols; ++i )
16211  {
16212  if( lp->cols[i]->obj != 0.0 )
16213  {
16214  coeff = lp->cols[i]->obj;
16215  if( origobj )
16216  {
16217  coeff *= (SCIP_Real) objsense;
16218  coeff *= objscale;
16219  }
16220 
16221  if( genericnames )
16222  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16223  else
16224  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16225 
16226  ++j;
16227  if( j % 10 == 0 )
16228  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16229  }
16230  }
16231  /* add artificial variable 'objoffset' to transfer objective offset */
16232  if( origobj && objoffset != 0.0 )
16233  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16234 
16235  /* print constraint section */
16236  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16237  for( i = 0; i < lp->nrows; i++ )
16238  {
16239  char type = 'i';
16240 
16241  /* skip removable rows if we want to write them as lazy constraints */
16242  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16243  continue;
16244 
16245  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16246  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16247  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16248  * type 'i' means: lhs and rhs are both infinite */
16249  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16250  type = 'r';
16251  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16252  type = 'l';
16253  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16254  type = 'e';
16255  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16256  type = 'b';
16257 
16258  /* print name of row */
16259  if( genericnames )
16260  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16261  else
16262  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16263 
16264  WRITEROW:
16265  switch( type )
16266  {
16267  case 'r':
16268  case 'l':
16269  case 'e':
16270  if( strlen(rowname) > 0 )
16271  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16272  break;
16273  case 'i':
16274  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16275  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16276  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16277  type = 'b';
16278  /*lint -fallthrough*/
16279  case 'b':
16280  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16281  break;
16282  default:
16283  assert(type == 'B');
16284  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16285  break;
16286  }
16287 
16288  /* print coefficients and variables */
16289  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16290  {
16291  if( genericnames )
16292  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16293  else
16294  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16295 
16296  if( (j+1) % 10 == 0 )
16297  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16298  }
16299 
16300  /* print right hand side */
16301  switch( type )
16302  {
16303  case 'b':
16304  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16305  type = 'B';
16306  goto WRITEROW;
16307  case 'l':
16308  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16309  break;
16310  case 'B':
16311  case 'r':
16312  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16313  break;
16314  case 'e':
16315  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16316  break;
16317  default:
16318  SCIPerrorMessage("Undefined row type!\n");
16319  return SCIP_ERROR;
16320  }
16321  }
16322 
16323  if ( lazyconss )
16324  {
16325  /* print lazy constraint section */
16326  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16327  for( i = 0; i < lp->nrows; i++ )
16328  {
16329  char type = 'i';
16330 
16331  /* skip non-removable rows if we want to write lazy constraints */
16332  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16333  continue;
16334 
16335  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16336  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16337  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16338  * type 'i' means: lhs and rhs are both infinite */
16339  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16340  type = 'r';
16341  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16342  type = 'l';
16343  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16344  type = 'e';
16345  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16346  type = 'b';
16347 
16348  /* print name of row */
16349  if( genericnames )
16350  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16351  else
16352  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16353 
16354  WRITELAZYROW:
16355  switch( type )
16356  {
16357  case 'r':
16358  case 'l':
16359  case 'e':
16360  if( strlen(rowname) > 0 )
16361  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16362  break;
16363  case 'i':
16364  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16365  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16366  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16367  type = 'b';
16368  /*lint -fallthrough*/
16369  case 'b':
16370  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16371  break;
16372  default:
16373  assert(type == 'B');
16374  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16375  break;
16376  }
16377 
16378  /* print coefficients and variables */
16379  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16380  {
16381  if( genericnames )
16382  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16383  else
16384  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16385 
16386  if( (j+1) % 10 == 0 )
16387  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16388  }
16389 
16390  /* print right hand side */
16391  switch( type )
16392  {
16393  case 'b':
16394  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16395  type = 'B';
16396  goto WRITELAZYROW;
16397  case 'l':
16398  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16399  break;
16400  case 'B':
16401  case 'r':
16402  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16403  break;
16404  case 'e':
16405  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16406  break;
16407  default:
16408  SCIPerrorMessage("Undefined row type!\n");
16409  return SCIP_ERROR;
16410  }
16411  }
16412  }
16413 
16414  /* print variable bounds */
16415  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16416  for( i = 0; i < lp->ncols; ++i )
16417  {
16418  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16419  {
16420  /* print lower bound as far this one is not infinity */
16421  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16422  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16423 
16424  /* print variable name */
16425  if( genericnames )
16426  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16427  else
16428  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16429 
16430  /* print upper bound as far this one is not infinity */
16431  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16432  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16433  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16434  }
16435  }
16436  if( origobj && objoffset != 0.0 )
16437  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16438 
16439  /* print integer variables */
16440  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16441  j = 0;
16442  for( i = 0; i < lp->ncols; ++i )
16443  {
16444  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16445  {
16446  /* print variable name */
16447  if( genericnames )
16448  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16449  else
16450  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16451 
16452  j++;
16453  if( j % 10 == 0 )
16454  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16455  }
16456  }
16457 
16458  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16459  fclose(file);
16460 
16461  return SCIP_OKAY;
16462 }
16463 
16464 /*
16465  * simple functions implemented as defines
16466  */
16467 
16468 /* In debug mode, the following methods are implemented as function calls to ensure
16469  * type validity.
16470  * In optimized mode, the methods are implemented as defines to improve performance.
16471  * However, we want to have them in the library anyways, so we have to undef the defines.
16472  */
16473 
16474 #undef SCIPcolGetObj
16475 #undef SCIPcolGetLb
16476 #undef SCIPcolGetUb
16477 #undef SCIPcolGetBestBound
16478 #undef SCIPcolGetPrimsol
16479 #undef SCIPcolGetMinPrimsol
16480 #undef SCIPcolGetMaxPrimsol
16481 #undef SCIPcolGetBasisStatus
16482 #undef SCIPcolGetVar
16483 #undef SCIPcolGetIndex
16484 #undef SCIPcolIsIntegral
16485 #undef SCIPcolIsRemovable
16486 #undef SCIPcolGetLPPos
16487 #undef SCIPcolGetLPDepth
16488 #undef SCIPcolIsInLP
16489 #undef SCIPcolGetNNonz
16490 #undef SCIPcolGetNLPNonz
16491 #undef SCIPcolGetRows
16492 #undef SCIPcolGetVals
16493 #undef SCIPcolGetStrongbranchNode
16494 #undef SCIPcolGetNStrongbranchs
16495 #undef SCIPboundtypeOpposite
16496 #undef SCIProwGetNNonz
16497 #undef SCIProwGetNLPNonz
16498 #undef SCIProwGetCols
16499 #undef SCIProwGetVals
16500 #undef SCIProwGetConstant
16501 #undef SCIProwGetNorm
16502 #undef SCIProwGetSumNorm
16503 #undef SCIProwGetLhs
16504 #undef SCIProwGetRhs
16505 #undef SCIProwGetDualsol
16506 #undef SCIProwGetDualfarkas
16507 #undef SCIProwGetBasisStatus
16508 #undef SCIProwGetName
16509 #undef SCIProwGetIndex
16510 #undef SCIProwGetAge
16511 #undef SCIProwGetRank
16512 #undef SCIProwIsIntegral
16513 #undef SCIProwIsLocal
16514 #undef SCIProwIsModifiable
16515 #undef SCIProwIsRemovable
16516 #undef SCIProwGetOrigintype
16517 #undef SCIProwGetOriginCons
16518 #undef SCIProwGetOriginSepa
16519 #undef SCIProwIsInGlobalCutpool
16520 #undef SCIProwGetLPPos
16521 #undef SCIProwGetLPDepth
16522 #undef SCIProwIsInLP
16523 #undef SCIProwGetActiveLPCount
16524 #undef SCIProwGetNLPsAfterCreation
16525 #undef SCIProwChgRank
16526 #undef SCIPlpGetCols
16527 #undef SCIPlpGetNCols
16528 #undef SCIPlpGetRows
16529 #undef SCIPlpGetNRows
16530 #undef SCIPlpGetNewcols
16531 #undef SCIPlpGetNNewcols
16532 #undef SCIPlpGetNewrows
16533 #undef SCIPlpGetNNewrows
16534 #undef SCIPlpGetObjNorm
16535 #undef SCIPlpGetRootObjval
16536 #undef SCIPlpGetRootColumnObjval
16537 #undef SCIPlpGetRootLooseObjval
16538 #undef SCIPlpGetLPI
16539 #undef SCIPlpSetIsRelax
16540 #undef SCIPlpIsRelax
16541 #undef SCIPlpIsSolved
16542 #undef SCIPlpIsSolBasic
16543 #undef SCIPlpDiving
16544 #undef SCIPlpDivingObjChanged
16545 #undef SCIPlpMarkDivingObjChanged
16546 #undef SCIPlpUnmarkDivingObjChanged
16547 #undef SCIPlpDivingRowsChanged
16548 
16549 /** gets objective value of column */
16551  SCIP_COL* col /**< LP column */
16552  )
16553 {
16554  assert(col != NULL);
16555 
16556  return col->obj;
16557 }
16558 
16559 /** gets lower bound of column */
16561  SCIP_COL* col /**< LP column */
16562  )
16563 {
16564  assert(col != NULL);
16565 
16566  return col->lb;
16567 }
16568 
16569 /** gets upper bound of column */
16571  SCIP_COL* col /**< LP column */
16572  )
16573 {
16574  assert(col != NULL);
16575 
16576  return col->ub;
16577 }
16578 
16579 /** gets best bound of column with respect to the objective function */
16581  SCIP_COL* col /**< LP column */
16582  )
16583 {
16584  assert(col != NULL);
16585 
16586  if( col->obj >= 0.0 )
16587  return col->lb;
16588  else
16589  return col->ub;
16590 }
16591 
16592 /** gets the primal LP solution of a column */
16594  SCIP_COL* col /**< LP column */
16595  )
16596 {
16597  assert(col != NULL);
16598 
16599  if( col->lppos >= 0 )
16600  return col->primsol;
16601  else
16602  return 0.0;
16603 }
16604 
16605 /** gets the minimal LP solution value, this column ever assumed */
16607  SCIP_COL* col /**< LP column */
16608  )
16609 {
16610  assert(col != NULL);
16611 
16612  return col->minprimsol;
16613 }
16614 
16615 /** gets the maximal LP solution value, this column ever assumed */
16617  SCIP_COL* col /**< LP column */
16618  )
16619 {
16620  assert(col != NULL);
16621 
16622  return col->maxprimsol;
16623 }
16624 
16625 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16626  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16627  */
16629  SCIP_COL* col /**< LP column */
16630  )
16631 {
16632  assert(col != NULL);
16633  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16634 
16635  return (SCIP_BASESTAT)col->basisstatus;
16636 }
16637 
16638 /** gets variable this column represents */
16640  SCIP_COL* col /**< LP column */
16641  )
16642 {
16643  assert(col != NULL);
16644 
16645  return col->var;
16646 }
16647 
16648 /** gets unique index of col */
16650  SCIP_COL* col /**< LP col */
16651  )
16652 {
16653  assert(col != NULL);
16654 
16655  return col->index;
16656 }
16657 
16658 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16660  SCIP_COL* col /**< LP column */
16661  )
16662 {
16663  assert(col != NULL);
16664  assert(SCIPvarIsIntegral(col->var) == col->integral);
16665 
16666  return col->integral;
16667 }
16668 
16669 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16671  SCIP_COL* col /**< LP column */
16672  )
16673 {
16674  assert(col != NULL);
16675 
16676  return col->removable;
16677 }
16678 
16679 /** gets position of column in current LP, or -1 if it is not in LP */
16681  SCIP_COL* col /**< LP column */
16682  )
16683 {
16684  assert(col != NULL);
16685  assert((col->lppos == -1) == (col->lpdepth == -1));
16686 
16687  return col->lppos;
16688 }
16689 
16690 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16692  SCIP_COL* col /**< LP column */
16693  )
16694 {
16695  assert(col != NULL);
16696  assert((col->lppos == -1) == (col->lpdepth == -1));
16697 
16698  return col->lpdepth;
16699 }
16700 
16701 /** returns TRUE iff column is member of current LP */
16703  SCIP_COL* col /**< LP column */
16704  )
16705 {
16706  assert(col != NULL);
16707  assert((col->lppos == -1) == (col->lpdepth == -1));
16708 
16709  return (col->lppos >= 0);
16710 }
16711 
16712 /** get number of nonzero entries in column vector */
16714  SCIP_COL* col /**< LP column */
16715  )
16716 {
16717  assert(col != NULL);
16718 
16719  return col->len;
16720 }
16721 
16722 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16723  *
16724  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16725  * 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
16726  */
16728  SCIP_COL* col /**< LP column */
16729  )
16730 {
16731  assert(col != NULL);
16732  assert(col->nunlinked == 0);
16733 
16734  return col->nlprows;
16735 }
16736 
16737 /** gets array with rows of nonzero entries */
16739  SCIP_COL* col /**< LP column */
16740  )
16741 {
16742  assert(col != NULL);
16743 
16744  return col->rows;
16745 }
16746 
16747 /** gets array with coefficients of nonzero entries */
16749  SCIP_COL* col /**< LP column */
16750  )
16751 {
16752  assert(col != NULL);
16753 
16754  return col->vals;
16755 }
16756 
16757 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16758  * given column, or -1 if strong branching was never applied to the column in current run
16759  */
16761  SCIP_COL* col /**< LP column */
16762  )
16763 {
16764  assert(col != NULL);
16765 
16766  return col->sbnode;
16767 }
16768 
16769 /** gets number of times, strong branching was applied in current run on the given column */
16771  SCIP_COL* col /**< LP column */
16772  )
16773 {
16774  assert(col != NULL);
16775 
16776  return col->nsbcalls;
16777 }
16778 
16779 /** gets opposite bound type of given bound type */
16781  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16782  )
16783 {
16784  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16785 
16787 }
16788 
16789 /** get number of nonzero entries in row vector */
16791  SCIP_ROW* row /**< LP row */
16792  )
16793 {
16794  assert(row != NULL);
16795 
16796  return row->len;
16797 }
16798 
16799 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16800  *
16801  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16802  * 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
16803  */
16805  SCIP_ROW* row /**< LP row */
16806  )
16807 {
16808  assert(row != NULL);
16809  assert(row->nunlinked == 0);
16810 
16811  return row->nlpcols;
16812 }
16813 
16814 /** gets array with columns of nonzero entries */
16816  SCIP_ROW* row /**< LP row */
16817  )
16818 {
16819  assert(row != NULL);
16820 
16821  return row->cols;
16822 }
16823 
16824 /** gets array with coefficients of nonzero entries */
16826  SCIP_ROW* row /**< LP row */
16827  )
16828 {
16829  assert(row != NULL);
16830 
16831  return row->vals;
16832 }
16833 
16834 /** gets constant shift of row */
16836  SCIP_ROW* row /**< LP row */
16837  )
16838 {
16839  assert(row != NULL);
16840 
16841  return row->constant;
16842 }
16843 
16844 /** gets Euclidean norm of row vector */
16846  SCIP_ROW* row /**< LP row */
16847  )
16848 {
16849  assert(row != NULL);
16850 
16851  checkRowSqrnorm(row);
16852 
16853  return sqrt(row->sqrnorm);
16854 }
16855 
16856 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16858  SCIP_ROW* row /**< LP row */
16859  )
16860 {
16861  assert(row != NULL);
16862 
16863  checkRowSumnorm(row);
16864 
16865  return row->sumnorm;
16866 }
16867 
16868 /** returns the left hand side of the row */
16870  SCIP_ROW* row /**< LP row */
16871  )
16872 {
16873  assert(row != NULL);
16874 
16875  return row->lhs;
16876 }
16877 
16878 /** returns the right hand side of the row */
16880  SCIP_ROW* row /**< LP row */
16881  )
16882 {
16883  assert(row != NULL);
16884 
16885  return row->rhs;
16886 }
16887 
16888 /** gets the dual LP solution of a row */
16890  SCIP_ROW* row /**< LP row */
16891  )
16892 {
16893  assert(row != NULL);
16894 
16895  if( row->lppos >= 0 )
16896  return row->dualsol;
16897  else
16898  return 0.0;
16899 }
16900 
16901 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16903  SCIP_ROW* row /**< LP row */
16904  )
16905 {
16906  assert(row != NULL);
16907 
16908  if( row->lppos >= 0 )
16909  return row->dualfarkas;
16910  else
16911  return 0.0;
16912 }
16913 
16914 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16915  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
16916  */
16918  SCIP_ROW* row /**< LP row */
16919  )
16920 {
16921  assert(row != NULL);
16922  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
16923 
16924  return (SCIP_BASESTAT)row->basisstatus;
16925 }
16926 
16927 /** returns the name of the row */
16928 const char* SCIProwGetName(
16929  SCIP_ROW* row /**< LP row */
16930  )
16931 {
16932  assert(row != NULL);
16933 
16934  return row->name;
16935 }
16936 
16937 /** gets unique index of row */
16939  SCIP_ROW* row /**< LP row */
16940  )
16941 {
16942  assert(row != NULL);
16943 
16944  return row->index;
16945 }
16946 
16947 /** gets age of row */
16949  SCIP_ROW* row /**< LP row */
16950  )
16951 {
16952  assert(row != NULL);
16953 
16954  return row->age;
16955 }
16956 
16957 /** gets rank of row */
16959  SCIP_ROW* row /**< LP row */
16960  )
16961 {
16962  assert(row != NULL);
16963 
16964  return row->rank;
16965 }
16966 
16967 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
16969  SCIP_ROW* row /**< LP row */
16970  )
16971 {
16972  assert(row != NULL);
16973 
16974  return row->integral;
16975 }
16976 
16977 /** returns TRUE iff row is only valid locally */
16979  SCIP_ROW* row /**< LP row */
16980  )
16981 {
16982  assert(row != NULL);
16983 
16984  return row->local;
16985 }
16986 
16987 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
16989  SCIP_ROW* row /**< LP row */
16990  )
16991 {
16992  assert(row != NULL);
16993 
16994  return row->modifiable;
16995 }
16996 
16997 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
16999  SCIP_ROW* row /**< LP row */
17000  )
17001 {
17002  assert(row != NULL);
17003 
17004  return row->removable;
17005 }
17006 
17007 /** returns type of origin that created the row */
17009  SCIP_ROW* row /**< LP row */
17010  )
17011 {
17012  assert( row != NULL );
17013 
17014  return (SCIP_ROWORIGINTYPE) row->origintype;
17015 }
17016 
17017 /** returns origin constraint handler that created the row (NULL if not available) */
17019  SCIP_ROW* row /**< LP row */
17020  )
17021 {
17022  assert( row != NULL );
17023 
17025  {
17026  assert( row->origin != NULL );
17027  return (SCIP_CONSHDLR*) row->origin;
17028  }
17029  return NULL;
17030 }
17031 
17032 /** returns origin separator that created the row (NULL if not available) */
17034  SCIP_ROW* row /**< LP row */
17035  )
17036 {
17037  assert( row != NULL );
17038 
17040  {
17041  assert( row->origin != NULL );
17042  return (SCIP_SEPA*) row->origin;
17043  }
17044  return NULL;
17045 }
17046 
17047 /** returns TRUE iff row is member of the global cut pool */
17049  SCIP_ROW* row /**< LP row */
17050  )
17051 {
17052  assert(row != NULL);
17053 
17054  return row->inglobalcutpool;
17055 }
17056 
17057 /** gets position of row in current LP, or -1 if it is not in LP */
17059  SCIP_ROW* row /**< LP row */
17060  )
17061 {
17062  assert(row != NULL);
17063  assert((row->lppos == -1) == (row->lpdepth == -1));
17064 
17065  return row->lppos;
17066 }
17067 
17068 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17070  SCIP_ROW* row /**< LP row */
17071  )
17072 {
17073  assert(row != NULL);
17074  assert((row->lppos == -1) == (row->lpdepth == -1));
17075 
17076  return row->lpdepth;
17077 }
17078 
17079 /** returns TRUE iff row is member of current LP */
17081  SCIP_ROW* row /**< LP row */
17082  )
17083 {
17084  assert(row != NULL);
17085  assert((row->lppos == -1) == (row->lpdepth == -1));
17086 
17087  return (row->lppos >= 0);
17088 }
17089 
17090 /** changes the rank of LP row */
17092  SCIP_ROW* row, /**< LP row */
17093  int rank /**< new value for rank */
17094  )
17095 {
17096  assert(row != NULL);
17097 
17098  row->rank = rank;
17099 }
17100 
17101 /** returns the number of times that this row has been sharp in an optimal LP solution */
17103  SCIP_ROW* row /**< row */
17104  )
17105 {
17106  assert(row != NULL);
17107 
17108  return row->activeinlpcounter;
17109 }
17110 
17111 /** returns the number of LPs since this row has been created */
17113  SCIP_ROW* row /**< row */
17114  )
17115 {
17116  assert(row != NULL);
17117 
17118  return row->nlpsaftercreation;
17119 }
17120 
17121 /** gets array with columns of the LP */
17123  SCIP_LP* lp /**< current LP data */
17124  )
17125 {
17126  assert(lp != NULL);
17127 
17128  return lp->cols;
17129 }
17130 
17131 /** gets current number of columns in LP */
17133  SCIP_LP* lp /**< current LP data */
17134  )
17135 {
17136  assert(lp != NULL);
17137 
17138  return lp->ncols;
17139 }
17140 
17141 /** gets array with rows of the LP */
17143  SCIP_LP* lp /**< current LP data */
17144  )
17145 {
17146  assert(lp != NULL);
17147 
17148  return lp->rows;
17149 }
17150 
17151 /** gets current number of rows in LP */
17153  SCIP_LP* lp /**< current LP data */
17154  )
17155 {
17156  assert(lp != NULL);
17157 
17158  return lp->nrows;
17159 }
17160 
17161 /** gets array with newly added columns after the last mark */
17163  SCIP_LP* lp /**< current LP data */
17164  )
17165 {
17166  assert(lp != NULL);
17167  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17168 
17169  return &(lp->cols[lp->firstnewcol]);
17170 }
17171 
17172 /** gets number of newly added columns after the last mark */
17174  SCIP_LP* lp /**< current LP data */
17175  )
17176 {
17177  assert(lp != NULL);
17178  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17179 
17180  return lp->ncols - lp->firstnewcol;
17181 }
17182 
17183 /** gets array with newly added rows after the last mark */
17185  SCIP_LP* lp /**< current LP data */
17186  )
17187 {
17188  assert(lp != NULL);
17189  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17190 
17191  return &(lp->rows[lp->firstnewrow]);
17192 }
17193 
17194 /** gets number of newly added rows after the last mark */
17196  SCIP_LP* lp /**< current LP data */
17197  )
17198 {
17199  assert(lp != NULL);
17200  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17201 
17202  return lp->nrows - lp->firstnewrow;
17203 }
17204 
17205 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17207  SCIP_SET* set, /**< global SCIP settings */
17208  SCIP_LP* lp /**< LP data */
17209  )
17210 {
17211  if( lp->objsqrnormunreliable )
17212  {
17213  SCIP_COL** cols;
17214  int c;
17215 
17216  cols = lp->cols;
17217  assert(cols != NULL || lp->ncols == 0);
17218 
17219  lp->objsqrnorm = 0.0;
17220 
17221  for( c = lp->ncols - 1; c >= 0; --c )
17222  {
17223  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17224  }
17225  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17226 
17227  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17228  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17229 
17231  }
17232  return;
17233 }
17234 
17235 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17236  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17238  SCIP_LP* lp /**< LP data */
17239  )
17240 {
17241  assert(lp != NULL);
17242  assert(!lp->objsqrnormunreliable);
17243  assert(lp->objsqrnorm >= 0.0);
17244 
17245  return SQRT(lp->objsqrnorm);
17246 }
17247 
17248 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17250  SCIP_LP* lp, /**< LP data */
17251  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17252  )
17253 {
17254  assert(lp != NULL);
17255 
17256  lp->rootlpisrelax = isrelax;
17257 }
17258 
17259 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17261  SCIP_LP* lp /**< LP data */
17262  )
17263 {
17264  assert(lp != NULL);
17265 
17266  return lp->rootlpisrelax;
17267 }
17268 
17269 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17271  SCIP_LP* lp /**< LP data */
17272  )
17273 {
17274  assert(lp != NULL);
17275 
17276  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17277 }
17278 
17279 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17280  * returns SCIP_INVALID if the root node LP was not (yet) solved
17281  */
17283  SCIP_LP* lp /**< LP data */
17284  )
17285 {
17286  assert(lp != NULL);
17287 
17288  return lp->rootlpobjval;
17289 }
17290 
17291 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17292  * returns SCIP_INVALID if the root node LP was not (yet) solved
17293  */
17295  SCIP_LP* lp /**< LP data */
17296  )
17297 {
17298  assert(lp != NULL);
17299 
17300  return lp->rootlooseobjval;
17301 }
17302 
17303 /** gets the LP solver interface */
17305  SCIP_LP* lp /**< current LP data */
17306  )
17307 {
17308  assert(lp != NULL);
17309 
17310  return lp->lpi;
17311 }
17312 
17313 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17315  SCIP_LP* lp, /**< LP data */
17316  SCIP_Bool relax /**< is the current lp a relaxation? */
17317  )
17318 {
17319  assert(lp != NULL);
17320 
17321  lp->isrelax = relax;
17322 }
17323 
17324 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17325  * solution value a valid local lower bound?
17326  */
17328  SCIP_LP* lp /**< LP data */
17329  )
17330 {
17331  assert(lp != NULL);
17332 
17333  return lp->isrelax;
17334 }
17335 
17336 /** returns whether the current LP is flushed and solved */
17338  SCIP_LP* lp /**< current LP data */
17339  )
17340 {
17341  assert(lp != NULL);
17342 
17343  return lp->flushed && lp->solved;
17344 }
17345 
17346 /** return whether the current LP solution passed the primal feasibility check */
17348  SCIP_LP* lp /**< current LP data */
17349  )
17350 {
17351  assert(lp != NULL);
17352 
17353  return (lp->primalchecked && lp->primalfeasible);
17354 }
17355 
17356 /** return whether the current LP solution passed the dual feasibility check */
17358  SCIP_LP* lp /**< current LP data */
17359  )
17360 {
17361  assert(lp != NULL);
17362 
17363  return (lp->dualchecked && lp->dualfeasible);
17364 }
17365 
17366 /** returns whether the current LP solution is a basic solution */
17368  SCIP_LP* lp /**< current LP data */
17369  )
17370 {
17371  assert(lp != NULL);
17372 
17373  return lp->solisbasic;
17374 }
17375 
17376 /** returns whether the LP is in diving mode */
17378  SCIP_LP* lp /**< current LP data */
17379  )
17380 {
17381  assert(lp != NULL);
17382 
17383  return lp->diving;
17384 }
17385 
17386 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17388  SCIP_LP* lp /**< current LP data */
17389  )
17390 {
17391  assert(lp != NULL);
17392 
17393  return lp->divingobjchg;
17394 }
17395 
17396 /** marks the diving LP to have a changed objective function */
17398  SCIP_LP* lp /**< current LP data */
17399  )
17400 {
17401  assert(lp != NULL);
17402  assert(lp->diving || lp->probing);
17403 
17404  lp->divingobjchg = TRUE;
17405 }
17406 
17407 /** marks the diving LP to not have a changed objective function anymore */
17409  SCIP_LP* lp /**< current LP data */
17410  )
17411 {
17412  assert(lp != NULL);
17413  assert(lp->diving || lp->probing);
17414 
17415  lp->divingobjchg = FALSE;
17416 }
17417 
17418 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17420  SCIP_LP* lp /**< current LP data */
17421  )
17422 {
17423  assert(lp != NULL);
17424  assert(lp->diving || lp->ndivechgsides == 0);
17425 
17426  return (lp->ndivechgsides > 0);
17427 }
17428 
17429 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17430 static
17432  SCIP_LPI* lpi, /**< auxiliary LP interface */
17433  SCIP_SET* set, /**< global SCIP settings */
17434  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17435  SCIP_LP* lp, /**< LP data */
17436  SCIP_PROB* prob, /**< problem data */
17437  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17438  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17439  SCIP_Real timelimit, /**< time limit for LP solver */
17440  int iterlimit, /**< iteration limit for LP solver */
17441  SCIP_Real* point, /**< array to store relative interior point on exit */
17442  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17443  )
17444 {
17445  SCIP_RETCODE retcode;
17446  SCIP_Real* primal;
17447  SCIP_Real* obj;
17448  SCIP_Real* lb;
17449  SCIP_Real* ub;
17450  SCIP_Real* matvals;
17451  SCIP_Real* matlhs;
17452  SCIP_Real* matrhs;
17453  SCIP_Real objval;
17454  SCIP_Real alpha;
17455  int* matinds;
17456  int* matbeg;
17457 #ifndef NDEBUG
17458  int nslacks;
17459 #endif
17460  int nnewcols;
17461  int ntotnonz = 0;
17462  int ntotrows = 0;
17463  int matrowidx;
17464  int matidx;
17465  int cnt;
17466  int j;
17467  int i;
17468 
17469  assert(lpi != NULL);
17470 
17472  if( retcode != SCIP_OKAY )
17473  {
17474  /* stop execution on error, since result is likely to be unsuable */
17475  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17476  return SCIP_LPERROR;
17477  }
17478 
17480  if( retcode != SCIP_OKAY )
17481  {
17482  /* stop execution on error, since result is likely to be unsuable */
17483  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17484  return SCIP_LPERROR;
17485  }
17486 
17487  /* get storage */
17488  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17489  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17490  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17491  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17492 
17493  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17494  for( j = 0; j < lp->ncols; ++j )
17495  {
17496  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17497  obj[j] = 0.0;
17498  lb[j] = -SCIPlpiInfinity(lpi);
17499  ub[j] = SCIPlpiInfinity(lpi);
17500  /* note: we could also use the original bounds - free variables seem to be faster. */
17501  }
17502 
17503  /* add artificial alpha variable */
17504  nnewcols = lp->ncols;
17505  obj[nnewcols] = 0.0;
17506  lb[nnewcols] = 1.0;
17507  ub[nnewcols] = SCIPlpiInfinity(lpi);
17508  ++nnewcols;
17509 
17510  /* create slacks for rows */
17511  for( i = 0; i < lp->nrows; ++i )
17512  {
17513  SCIP_ROW* row;
17514 
17515  row = lp->rows[i];
17516  assert( row != NULL );
17517 
17518  if( SCIProwIsModifiable(row) )
17519  continue;
17520 
17521  /* make sure row is sorted */
17522  rowSortLP(row);
17523  assert( row->lpcolssorted );
17524 
17525  /* check whether we have an equation */
17526  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17527  {
17528  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17529  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17530  ntotnonz += row->nlpcols + 1;
17531  ++ntotrows;
17532  }
17533  else
17534  {
17535  /* otherwise add slacks for each side if necessary */
17536  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17537  {
17538  if ( relaxrows )
17539  {
17540  lb[nnewcols] = 0.0;
17541  ub[nnewcols] = 1.0;
17542  obj[nnewcols++] = 1.0;
17543  ntotnonz += row->nlpcols + 2;
17544  }
17545  else
17546  ntotnonz += row->nlpcols + 1;
17547  ++ntotrows;
17548  }
17549  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17550  {
17551  if ( relaxrows )
17552  {
17553  lb[nnewcols] = 0.0;
17554  ub[nnewcols] = 1.0;
17555  obj[nnewcols++] = 1.0;
17556  ntotnonz += row->nlpcols + 2;
17557  }
17558  else
17559  ntotnonz += row->nlpcols + 1;
17560  ++ntotrows;
17561  }
17562  }
17563  }
17564 
17565  /* create slacks for objective cutoff row */
17566  if( inclobjcutoff && relaxrows )
17567  {
17568  /* add slacks for right hand side */
17569  lb[nnewcols] = 0.0;
17570  ub[nnewcols] = 1.0;
17571  obj[nnewcols++] = 1.0;
17572  ntotnonz += lp->ncols + 2;
17573  ++ntotrows;
17574  }
17575 
17576  /* create slacks for bounds */
17577  for( j = 0; j < lp->ncols; ++j )
17578  {
17579  SCIP_COL* col;
17580 
17581  col = lp->cols[j];
17582  assert( col != NULL );
17583 
17584  /* no slacks for fixed variables */
17585  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17586  {
17587  ++ntotrows;
17588  ntotnonz += 2;
17589  }
17590  else
17591  {
17592  /* add slacks for each bound if necessary */
17593  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17594  {
17595  lb[nnewcols] = 0.0;
17596  ub[nnewcols] = 1.0;
17597  obj[nnewcols++] = 1.0;
17598  ntotnonz += 3;
17599  ++ntotrows;
17600  }
17601  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
17602  {
17603  lb[nnewcols] = 0.0;
17604  ub[nnewcols] = 1.0;
17605  obj[nnewcols++] = 1.0;
17606  ntotnonz += 3;
17607  ++ntotrows;
17608  }
17609  }
17610  }
17611 #ifndef NDEBUG
17612  nslacks = nnewcols - lp->ncols - 1;
17613  assert( nslacks >= 0 );
17614  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17615 #endif
17616 
17617  /* add columns */
17618  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17619 
17620  /* free storage */
17621  SCIPsetFreeBufferArray(set, &obj);
17622  SCIPsetFreeBufferArray(set, &ub);
17623  SCIPsetFreeBufferArray(set, &lb);
17624 
17625  /* prepare storage for rows */
17626  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
17627  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
17628  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
17629  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
17630  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
17631 
17632  /* create rows arising from original rows */
17633  cnt = 0;
17634  matrowidx = 0;
17635  matidx = 0;
17636  for( i = 0; i < lp->nrows; ++i )
17637  {
17638  SCIP_ROW* row;
17639  SCIP_COL** rowcols;
17640  SCIP_Real* rowvals;
17641  SCIP_Real lhs;
17642  SCIP_Real rhs;
17643  int nnonz;
17644 
17645  row = lp->rows[i];
17646  assert( row != NULL );
17647 
17648  if( SCIProwIsModifiable(row) )
17649  continue;
17650  assert( row->lpcolssorted );
17651 
17652  /* get row data */
17653  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17654  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17655  nnonz = row->nlpcols;
17656  assert( nnonz <= lp->ncols );
17657  rowcols = row->cols;
17658  rowvals = row->vals;
17659 
17660  /* if we have an equation */
17661  if( SCIPsetIsEQ(set, lhs, rhs) )
17662  {
17663  /* set up indices */
17664  matbeg[matrowidx] = matidx;
17665  for( j = 0; j < nnonz; ++j )
17666  {
17667  assert( rowcols[j] != NULL );
17668  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17669  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17670  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17671  matinds[matidx] = rowcols[j]->lppos;
17672  matvals[matidx++] = rowvals[j];
17673  assert( matidx <= ntotnonz );
17674  }
17675 
17676  /* add artificial variable */
17677  if ( ! SCIPsetIsZero(set, rhs) )
17678  {
17679  matinds[matidx] = lp->ncols;
17680  matvals[matidx++] = -rhs;
17681  assert( matidx <= ntotnonz );
17682  }
17683 
17684  matlhs[matrowidx] = 0.0;
17685  matrhs[matrowidx++] = 0.0;
17686  assert( matrowidx <= ntotrows );
17687  }
17688  else
17689  {
17690  SCIP_Real abslhs = REALABS(lhs);
17691  SCIP_Real absrhs = REALABS(rhs);
17692 
17693  assert(!SCIPsetIsEQ(set, lhs, rhs));
17694 
17695  /* treat lhs */
17696  if( !SCIPsetIsInfinity(set, abslhs) )
17697  {
17698  /* set up indices */
17699  matbeg[matrowidx] = matidx;
17700  for( j = 0; j < nnonz; ++j )
17701  {
17702  assert( rowcols[j] != NULL );
17703  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17704  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17705  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17706  matinds[matidx] = rowcols[j]->lppos;
17707  matvals[matidx++] = rowvals[j];
17708  assert( matidx <= ntotnonz );
17709  }
17710 
17711  /* add artificial variable */
17712  if ( ! SCIPsetIsZero(set, lhs) )
17713  {
17714  matinds[matidx] = lp->ncols;
17715  matvals[matidx++] = -lhs;
17716  assert( matidx <= ntotnonz );
17717  }
17718 
17719  if( relaxrows )
17720  {
17721  /* add slack variable */
17722  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
17723  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17724  assert( matidx <= ntotnonz );
17725  ++cnt;
17726  }
17727 
17728  matlhs[matrowidx] = 0.0;
17729  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
17730  assert( matrowidx <= ntotrows );
17731  }
17732 
17733  /* treat rhs */
17734  if( !SCIPsetIsInfinity(set, absrhs) )
17735  {
17736  /* set up indices */
17737  matbeg[matrowidx] = matidx;
17738  for( j = 0; j < nnonz; ++j )
17739  {
17740  assert( rowcols[j] != NULL );
17741  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17742  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17743  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17744  matinds[matidx] = rowcols[j]->lppos;
17745  matvals[matidx++] = rowvals[j];
17746  assert( matidx <= ntotnonz );
17747  }
17748 
17749  /* add artificial variable */
17750  if ( ! SCIPsetIsZero(set, rhs) )
17751  {
17752  matinds[matidx] = lp->ncols;
17753  matvals[matidx++] = -rhs;
17754  assert( matidx <= ntotnonz );
17755  }
17756 
17757  if( relaxrows )
17758  {
17759  /* add slack variable */
17760  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
17761  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17762  ++cnt;
17763  }
17764 
17765  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
17766  matrhs[matrowidx++] = 0.0;
17767  assert( matrowidx <= ntotrows );
17768  }
17769  }
17770  }
17771 
17772  /* create row arising from objective cutoff */
17773  if( inclobjcutoff )
17774  {
17775  SCIP_Real rhs;
17776 
17777  /* get row data */
17778  assert(lp->looseobjvalinf == 0);
17779  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17780 
17781  /* set up indices and coefficients */
17782  matbeg[matrowidx] = matidx;
17783  for( j = 0; j < lp->ncols; ++j )
17784  {
17785  assert( lp->cols[j] != NULL );
17786  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17787  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17788 
17789  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
17790  {
17791  matinds[matidx] = lp->cols[j]->lppos;
17792  matvals[matidx++] = lp->cols[j]->obj;
17793  assert( matidx <= ntotnonz );
17794  }
17795  }
17796 
17797  /* treat rhs */
17798 
17799  /* add artificial variable */
17800  if ( ! SCIPsetIsZero(set, rhs) )
17801  {
17802  matinds[matidx] = lp->ncols;
17803  matvals[matidx++] = -rhs;
17804  assert( matidx <= ntotnonz );
17805  }
17806 
17807  if( relaxrows )
17808  {
17809  SCIP_Real absrhs = REALABS(rhs);
17810 
17811  /* add slack variable */
17812  matvals[matidx] = MAX(1.0, absrhs);
17813  matinds[matidx++] = lp->ncols + 1 + cnt;
17814  assert( matidx <= ntotnonz );
17815  ++cnt;
17816  }
17817  matlhs[matrowidx] = -SCIPsetInfinity(set);
17818  matrhs[matrowidx++] = 0.0;
17819  assert( matrowidx <= ntotrows );
17820  }
17821 
17822  /* create rows arising from bounds */
17823  for( j = 0; j < lp->ncols; ++j )
17824  {
17825  SCIP_COL* col;
17826  SCIP_Real abscollb;
17827  SCIP_Real abscolub;
17828 
17829  col = lp->cols[j];
17830  assert( col != NULL );
17831  assert( col->lppos == j );
17832 
17833  /* fixed variable */
17834  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17835  {
17836  /* set up index of column */
17837  matbeg[matrowidx] = matidx;
17838 
17839  matinds[matidx] = j;
17840  matvals[matidx++] = 1.0;
17841  assert( matidx <= ntotnonz );
17842 
17843  /* add artificial variable */
17844  if ( ! SCIPsetIsZero(set, col->ub) )
17845  {
17846  matinds[matidx] = lp->ncols;
17847  matvals[matidx++] = -col->lb;
17848  assert( matidx <= ntotnonz );
17849  }
17850 
17851  matlhs[matrowidx] = 0.0;
17852  matrhs[matrowidx++] = 0.0;
17853  assert( matrowidx <= ntotrows );
17854 
17855  continue;
17856  }
17857 
17858  abscollb = REALABS(col->lb);
17859  abscolub = REALABS(col->ub);
17860 
17861  /* lower bound */
17862  if ( ! SCIPsetIsInfinity(set, abscollb) )
17863  {
17864  /* set up index of column */
17865  matbeg[matrowidx] = matidx;
17866 
17867  matinds[matidx] = j;
17868  matvals[matidx++] = 1.0;
17869  assert( matidx <= ntotnonz );
17870 
17871  /* add artificial variable */
17872  if ( ! SCIPsetIsZero(set, col->lb) )
17873  {
17874  matinds[matidx] = lp->ncols;
17875  matvals[matidx++] = -col->lb;
17876  assert( matidx <= ntotnonz );
17877  }
17878 
17879  /* add slack variable */
17880  matvals[matidx] = -MAX(1.0, abscollb);
17881  matinds[matidx++] = lp->ncols + 1 + cnt;
17882  assert( matidx <= ntotnonz );
17883  ++cnt;
17884 
17885  matlhs[matrowidx] = 0.0;
17886  matrhs[matrowidx++] = SCIPsetInfinity(set);
17887  assert( matrowidx <= ntotrows );
17888  }
17889 
17890  /* upper bound */
17891  if ( ! SCIPsetIsInfinity(set, abscolub) )
17892  {
17893  /* set up index of column */
17894  matbeg[matrowidx] = matidx;
17895 
17896  matinds[matidx] = j;
17897  matvals[matidx++] = 1.0;
17898  assert( matidx <= ntotnonz );
17899 
17900  /* add artificial variable */
17901  if ( ! SCIPsetIsZero(set, col->ub) )
17902  {
17903  matinds[matidx] = lp->ncols;
17904  matvals[matidx++] = -col->ub;
17905  assert( matidx <= ntotnonz );
17906  }
17907 
17908  /* add slack variable */
17909  matvals[matidx] = MAX(1.0, abscolub);
17910  matinds[matidx++] = lp->ncols + 1 + cnt;
17911  assert( matidx <= ntotnonz );
17912  ++cnt;
17913 
17914  matlhs[matrowidx] = -SCIPsetInfinity(set);
17915  matrhs[matrowidx++] = 0.0;
17916  assert( matrowidx <= ntotrows );
17917  }
17918  }
17919  assert( cnt == nslacks );
17920  assert( matrowidx == ntotrows );
17921 
17922  /* add rows */
17923  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
17924 
17925  SCIPsetFreeBufferArray(set, &matrhs);
17926  SCIPsetFreeBufferArray(set, &matlhs);
17927  SCIPsetFreeBufferArray(set, &matbeg);
17928  SCIPsetFreeBufferArray(set, &matvals);
17929  SCIPsetFreeBufferArray(set, &matinds);
17930 
17931 #ifdef SCIP_OUTPUT
17932  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
17933 #endif
17934 
17935 #ifndef NDEBUG
17936  {
17937  int ncols;
17938  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
17939  assert( ncols == nnewcols );
17940  }
17941 #endif
17942 
17943  /* set time limit */
17944  if( SCIPsetIsInfinity(set, timelimit) )
17945  timelimit = SCIPlpiInfinity(lpi);
17946  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
17947 
17948  /* check, if parameter is unknown */
17949  if( retcode == SCIP_PARAMETERUNKNOWN )
17950  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
17951  else if ( retcode != SCIP_OKAY )
17952  return retcode;
17953 
17954  /* set iteration limit */
17955  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
17956 
17957  /* check, if parameter is unknown */
17958  if( retcode == SCIP_PARAMETERUNKNOWN )
17959  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
17960  else if ( retcode != SCIP_OKAY )
17961  return retcode;
17962 
17963  /* solve and store point */
17964  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
17965  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
17966 
17967 #ifndef NDEBUG
17968  if ( SCIPlpiIsIterlimExc(lpi) )
17969  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
17970  if ( SCIPlpiIsTimelimExc(lpi) )
17971  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
17972 #endif
17973 
17974  if( SCIPlpiIsOptimal(lpi) )
17975  {
17976  /* get primal solution */
17977  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
17978  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
17979  alpha = primal[lp->ncols];
17980  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
17981 
17982  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
17983 
17984  /* construct relative interior point */
17985  for( j = 0; j < lp->ncols; ++j )
17986  point[j] = primal[j]/alpha;
17987 
17988 #ifdef SCIP_DEBUG
17989  /* check whether the point is a relative interior point */
17990  cnt = 0;
17991  if( relaxrows )
17992  {
17993  for( i = 0; i < lp->nrows; ++i )
17994  {
17995  SCIP_ROW* row;
17996  SCIP_COL** rowcols;
17997  SCIP_Real* rowvals;
17998  SCIP_Real lhs;
17999  SCIP_Real rhs;
18000  SCIP_Real sum;
18001  int nnonz;
18002 
18003  row = lp->rows[i];
18004  assert( row != NULL );
18005 
18006  /* get row data */
18007  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18008  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18009  nnonz = row->nlpcols;
18010  assert( nnonz <= lp->ncols );
18011  rowcols = row->cols;
18012  rowvals = row->vals;
18013 
18014  sum = 0.0;
18015  for( j = 0; j < nnonz; ++j )
18016  sum += rowvals[j] * primal[rowcols[j]->lppos];
18017  sum /= alpha;
18018 
18019  /* if we have an equation */
18020  if( SCIPsetIsEQ(set, lhs, rhs) )
18021  {
18022  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18023  }
18024  else
18025  {
18026  /* treat lhs */
18027  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18028  {
18029  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18030  ++cnt;
18031  }
18032  /* treat rhs */
18033  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18034  {
18035  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18036  ++cnt;
18037  }
18038  }
18039  }
18040  if( inclobjcutoff )
18041  {
18042  SCIP_Real sum;
18043 #ifndef NDEBUG
18044  SCIP_Real rhs;
18045 
18046  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18047 #endif
18048  sum = 0.0;
18049  for( j = 0; j < lp->ncols; ++j )
18050  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18051  sum /= alpha;
18052 
18053  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18054  ++cnt;
18055  }
18056  }
18057  /* check bounds */
18058  for( j = 0; j < lp->ncols; ++j )
18059  {
18060  SCIP_COL* col;
18061 #ifndef NDEBUG
18062  SCIP_Real val;
18063 #endif
18064 
18065  col = lp->cols[j];
18066  assert( col != NULL );
18067 #ifndef NDEBUG
18068  val = primal[col->lppos] / alpha;
18069 #endif
18070  /* if the variable is not fixed */
18071  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18072  {
18073  /* treat lb */
18074  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18075  {
18076  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18077  ++cnt;
18078  }
18079  /* treat rhs */
18080  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18081  {
18082  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18083  ++cnt;
18084  }
18085  }
18086  }
18087 #endif
18088 
18089  /* free */
18090  SCIPsetFreeBufferArray(set, &primal);
18091 
18092  *success = TRUE;
18093  }
18094 
18095  return SCIP_OKAY;
18096 }
18097 
18098 /** compute relative interior point
18099  *
18100  * We use the approach of@par
18101  * R. Freund, R. Roundy, M. J. Todd@par
18102  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18103  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18104  *
18105  * to compute a relative interior point for the current LP.
18106  *
18107  * Assume the original LP looks as follows:
18108  * \f[
18109  * \begin{array}{rrl}
18110  * \min & c^T x &\\
18111  * & A x & \geq a\\
18112  * & B x & \leq b\\
18113  * & D x & = d.
18114  * \end{array}
18115  * \f]
18116  * Note that bounds should be included in the system.
18117  *
18118  * To find an interior point the following LP does the job:
18119  * \f[
18120  * \begin{array}{rrl}
18121  * \max & 1^T y &\\
18122  * & A x - y - \alpha a & \geq 0\\
18123  * & B x + y - \alpha b & \leq 0\\
18124  * & D x - \alpha d & = 0\\
18125  * & 0 \leq y & \leq 1\\
18126  * & \alpha & \geq 1.
18127  * \end{array}
18128  * \f]
18129  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18130  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18131  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18132  */
18134  SCIP_SET* set, /**< global SCIP settings */
18135  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18136  SCIP_LP* lp, /**< LP data */
18137  SCIP_PROB* prob, /**< problem data */
18138  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18139  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18140  SCIP_Real timelimit, /**< time limit for LP solver */
18141  int iterlimit, /**< iteration limit for LP solver */
18142  SCIP_Real* point, /**< array to store relative interior point on exit */
18143  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18144  )
18145 {
18146  SCIP_LPI* lpi;
18147  SCIP_RETCODE retcode;
18148 
18149  assert(set != NULL);
18150  assert(lp != NULL);
18151  assert(point != NULL);
18152  assert(success != NULL);
18153 
18154  *success = FALSE;
18155 
18156  /* check time and iteration limits */
18157  if ( timelimit <= 0.0 || iterlimit <= 0 )
18158  return SCIP_OKAY;
18159 
18160  /* exit if there are no columns */
18161  assert(lp->nrows >= 0);
18162  assert(lp->ncols >= 0);
18163  if( lp->ncols == 0 )
18164  return SCIP_OKAY;
18165 
18166  /* disable objective cutoff if we have none */
18167  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18168  inclobjcutoff = FALSE;
18169 
18170  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18171 
18172  /* if there are no rows, we return the zero point */
18173  if( lp->nrows == 0 && !inclobjcutoff )
18174  {
18175  /* create zero point */
18176  BMSclearMemoryArray(point, lp->ncols);
18177  *success = TRUE;
18178 
18179  return SCIP_OKAY;
18180  }
18181 
18182  /* create auxiliary LP */
18183  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18184 
18185  /* catch return code and ensure that lpi is freed, anyway */
18186  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18187 
18188  SCIP_CALL( SCIPlpiFree(&lpi) );
18189 
18190  /* return error, unless we obtained an LP error */
18191  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18192  {
18193  SCIP_CALL( retcode );
18194  }
18195 
18196  return SCIP_OKAY;
18197 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:395
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:7068
SCIP_Longint nprimallps
Definition: struct_stat.h:178
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:16998
SCIP_Bool solisbasic
Definition: struct_lp.h:357
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:1734
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:17431
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4674
int firstnewrow
Definition: struct_lp.h:321
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16101
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6415
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:12979
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:4630
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:91
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
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:361
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5953
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6256
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2528
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2827
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6610
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:449
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2727
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:13513
#define NULL
Definition: def.h:239
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8842
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:859
internal methods for managing events
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10052
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17419
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2802
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7272
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6011
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17195
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6461
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2928
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:6915
void * origin
Definition: struct_lp.h:216
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:222
static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
Definition: lp.c:4863
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13816
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
SCIP_STATUS status
Definition: struct_stat.h:170
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17377
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:1847
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9597
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17314
SCIP_Longint validactivitylp
Definition: struct_lp.h:223
int lpifirstchgrow
Definition: struct_lp.h:306
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2380
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6274
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3581
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:16948
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1384
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17033
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:93
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:193
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:5855
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6594
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:78
int * cols_index
Definition: struct_lp.h:219
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15968
int nremovablecols
Definition: struct_lp.h:316
char * name
Definition: struct_var.h:229
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition: set.c:7133
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15323
SCIP_Bool primalfeasible
Definition: struct_lp.h:353
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:18133
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:888
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3077
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:878
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
int nchgrows
Definition: struct_lp.h:310
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:222
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8578
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9764
char * name
Definition: struct_lp.h:217
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:17491
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6181
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:3450
int nlpicols
Definition: struct_lp.h:302
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6351
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:527
enum SCIP_BaseStat SCIP_BASESTAT
Definition: type_lpi.h:86
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15292
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6329
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17249
SCIP_Longint nlps
Definition: struct_stat.h:176
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:2153
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17343
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6547
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:339
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
#define SCIP_MAXSTRLEN
Definition: def.h:260
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:7912
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16628
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6079
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17206
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:68
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:13390
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16748
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16760
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6076
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:111
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16790
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
SCIP_Real objsumnorm
Definition: struct_lp.h:281
#define SQR(x)
Definition: def.h:191
SCIP_Longint ndivinglps
Definition: struct_stat.h:190
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:1892
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17399
SCIP_ROW ** chgrows
Definition: struct_lp.h:286
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5246
SCIP_COL ** chgcols
Definition: struct_lp.h:285
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:5492
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:14912
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14837
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11804
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16928
int rank
Definition: struct_lp.h:239
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:1016
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16909
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5813
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1251
int rowssize
Definition: struct_lp.h:318
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8807
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3635
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7804
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17102
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13058
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:14664
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13707
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13995
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:612
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11321
unsigned int nonlprowssorted
Definition: struct_lp.h:172
int nclockskipsleft
Definition: struct_stat.h:258
SCIP_COL ** cols
Definition: struct_lp.h:287
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9991
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1287
int nlpirows
Definition: struct_lp.h:305
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:97
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:131
int soldirectionsize
Definition: struct_lp.h:312
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:16804
#define debugColPrint(x, y)
Definition: lp.c:144
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:3216
static const int nscalars
Definition: lp.c:5651
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:9645
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
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:13680
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16869
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:65
int lppos
Definition: struct_lp.h:163
SCIP_Real lazylb
Definition: struct_lp.h:132
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
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:16137
#define EPSEQ(x, y, eps)
Definition: def.h:175
#define EPSISINT(x, eps)
Definition: def.h:187
int pseudoobjvalinf
Definition: struct_lp.h:325
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17367
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:288
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13748
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6494
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:762
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:16659
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3556
int divinglpiitlim
Definition: struct_lp.h:329
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16570
SCIP_Bool solved
Definition: struct_lp.h:352
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:1681
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:10325
struct SCIP_LPiNorms SCIP_LPINORMS
Definition: type_lpi.h:98
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_Longint nrootlps
Definition: struct_stat.h:177
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:16917
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16550
SCIP_Bool dualchecked
Definition: struct_lp.h:356
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10017
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6065
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16115
#define TRUE
Definition: def.h:64
#define SCIPdebug(x)
Definition: pub_message.h:74
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8135
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool lpifromscratch
Definition: struct_lp.h:370
unsigned int basisstatus
Definition: struct_lp.h:240
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2764
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6715
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:9925
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:17282
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:15955
SCIP_Real dualsol
Definition: struct_lp.h:98
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1904
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:447
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2568
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:5383
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17036
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:345
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:15898
unsigned int delaysort
Definition: struct_lp.h:243
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5503
unsigned int basisstatus
Definition: struct_lp.h:170
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:16691
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Real lpidualfeastol
Definition: struct_lp.h:277
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:63
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15261
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6162
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3054
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:8963
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:331
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
public methods for problem variables
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:105
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6871
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1891
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:15719
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:5888
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:2903
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:12211
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:151
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12129
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17142
SCIP_Bool diving
Definition: struct_lp.h:365
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7826
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:13431
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13090
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6658
SCIP_Real rootlooseobjval
Definition: struct_lp.h:273
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
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:3501
int firstnewcol
Definition: struct_lp.h:317
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:15500
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3405
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10066
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, 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:5033
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:14852
unsigned int integral
Definition: struct_lp.h:248
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:453
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:10032
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1120
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:94
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6087
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17008
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:2989
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1049
#define SCIP_LONGINT_MAX
Definition: def.h:136
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:153
int lpifirstchgcol
Definition: struct_lp.h:303
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1911
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:127
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:15940
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2540
#define checkRow(row)
Definition: lp.c:678
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6307
int maxdepth
Definition: struct_stat.h:219
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:8937
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:76
int looseobjvalinf
Definition: struct_lp.h:322
SCIP_Real obj
Definition: struct_var.h:203
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:346
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:5435
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:16889
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:283
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12891
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition: lp.c:268
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4662
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
int lazycolssize
Definition: struct_lp.h:314
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13908
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:846
SCIP_Real objprod
Definition: struct_lp.h:201
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:17260
int colssize
Definition: struct_lp.h:311
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:340
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:15901
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:376
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:386
SCIP_Bool lpipresolving
Definition: struct_lp.h:371
int nremovablerows
Definition: struct_lp.h:320
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)
SCIP_Bool primalchecked
Definition: struct_lp.h:354
real eps
SCIP_Bool strongbranching
Definition: struct_lp.h:362
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1299
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
#define checkLinks(lp)
Definition: lp.c:1607
int lpithreads
Definition: struct_lp.h:332
int ndivechgsides
Definition: struct_lp.h:327
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17132
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12102
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11373
#define SCIP_DEFAULT_EPSILON
Definition: def.h:156
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:11376
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6047
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17080
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:6823
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2336
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int integral
Definition: struct_lp.h:177
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:8727
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:3945
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
int nloosevars
Definition: struct_lp.h:323
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:1968
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17270
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3784
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4753
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17353
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6066
int divechgsidessize
Definition: struct_lp.h:328
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5993
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:15461
int * linkpos
Definition: struct_lp.h:157
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:358
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6220
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)
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:39
int lpiitlim
Definition: struct_lp.h:330
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:9949
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: lp.c:7740
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:278
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:3384
int glbpseudoobjvalinf
Definition: struct_lp.h:324
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17173
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13775
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16857
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:443
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2462
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14040
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:480
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15613
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16593
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6626
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:15925
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5573
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:5923
int lpirefactorinterval
Definition: struct_lp.h:336
SCIP_ROW ** divechgrows
Definition: struct_lp.h:294
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:382
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:8086
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:1799
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:16152
SCIP_Bool installing
Definition: struct_lp.h:361
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:387
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:17347
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16780
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:4823
SCIP_Real SCIPsetLpfeastol(SCIP_SET *set)
Definition: set.c:5875
#define SCIPerrorMessage
Definition: pub_message.h:45
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:668
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition: lp.c:3166
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14118
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17357
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:174
SCIP_Bool lpilpinfo
Definition: struct_lp.h:372
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:16738
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
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)
SCIP_Real pseudoactivity
Definition: struct_lp.h:207
SCIP_PRICING lpipricing
Definition: struct_lp.h:337
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9342
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:985
#define COPYSIGN
Definition: def.h:230
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9525
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17122
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16978
SCIP_Bool adjustlpval
Definition: struct_lp.h:369
SCIP_Real minval
Definition: struct_lp.h:203
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:4019
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIPInterval sqrt(const SCIPInterval &x)
SCIP_ROW ** lpirows
Definition: struct_lp.h:284
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:180
SCIP_Longint validsoldirlp
Definition: struct_lp.h:299
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:15390
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8530
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5637
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_Longint validfarkaslp
Definition: struct_lp.h:298
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:9839
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9682
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:5888
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16560
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:96
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
int nuses
Definition: struct_lp.h:229
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16729
int lpiscaling
Definition: struct_lp.h:335
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:2026
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:16968
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)
struct SCIP_LPiState SCIP_LPISTATE
Definition: type_lpi.h:97
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6243
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14430
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6055
SCIP_Real cutoffbound
Definition: struct_lp.h:274
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6357
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:9401
internal miscellaneous methods
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17018
SCIP_Bool isrelax
Definition: struct_lp.h:359
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17237
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6628
int numintcols
Definition: struct_lp.h:235
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
#define REALABS(x)
Definition: def.h:174
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:295
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2690
SCIP_Bool looseobjvalid
Definition: struct_lp.h:343
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:351
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6439
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:17481
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6433
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17152
int lpirandomseed
Definition: struct_lp.h:334
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:584
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:214
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17397
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:349
SCIP_Bool resolvelperror
Definition: struct_lp.h:368
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)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:16879
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8283
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11312
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5975
#define lpCutoffDisabled(set)
Definition: lp.c:2641
int lpicolssize
Definition: struct_lp.h:301
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17304
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12907
SCIP_LPI * lpi
Definition: struct_lp.h:282
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5206
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2419
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:16988
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1802
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:266
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6395
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16815
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6815
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:185
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:293
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2283
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4117
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6642
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:153
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:1507
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:8915
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8767
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5259
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:11835
SCIP_Longint nduallps
Definition: struct_stat.h:180
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6373
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:16649
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:446
internal methods for problem variables
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7877
#define SCIP_UNKNOWN
Definition: def.h:171
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9708
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6098
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16825
int nchgcols
Definition: struct_lp.h:308
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
public data structures and miscellaneous methods
int len
Definition: struct_lp.h:160
SCIP_Real * soldirection
Definition: struct_lp.h:290
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17294
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9663
#define SCIP_Bool
Definition: def.h:62
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12990
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:5845
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:186
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:435
int numminval
Definition: struct_lp.h:237
int lpipos
Definition: struct_lp.h:231
int size
Definition: struct_lp.h:225
unsigned int modifiable
Definition: struct_lp.h:250
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:804
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
void SCIPprintSysError(const char *message)
Definition: misc.c:9926
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15011
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:9264
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16580
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:5956
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:95
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3836
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:945
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
int chgrowssize
Definition: struct_lp.h:309
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17184
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:17730
SCIP_Longint validfarkaslp
Definition: struct_lp.h:155
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:311
unsigned int lbchanged
Definition: struct_lp.h:174
SCIP_Bool divingobjchg
Definition: struct_lp.h:366
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9742
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:448
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17387
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3694
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition: lp.c:1084
unsigned int basisstatus
Definition: struct_lp.h:88
#define MIN(x, y)
Definition: def.h:209
SCIP_Bool updateintegrality
Definition: struct_lp.h:350
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17201
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:8980
#define SCIPsetDebugMsg
Definition: set.h:1940
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:380
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:4147
int minidx
Definition: struct_lp.h:233
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:16670
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2167
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2267
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:385
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17191
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:5337
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:8983
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9725
unsigned int lpcolssorted
Definition: struct_lp.h:241
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:367
SCIP_Longint validsollp
Definition: struct_lp.h:297
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3334
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9694
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16902
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17057
SCIP_CLOCK * resolveinstablelptime
Definition: struct_stat.h:152
static void colSortLP(SCIP_COL *col)
Definition: lp.c:952
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13398
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6772
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6831
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:245
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15539
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6373
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6184
SCIP_ROW ** rows
Definition: struct_lp.h:289
SCIP_SOL * validsoldirsol
Definition: struct_lp.h:296
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:3739
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1198
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:291
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10008
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3074
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:7764
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3314
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3344
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12191
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1159
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:897
SCIP_Real flushedrhs
Definition: struct_lp.h:198
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:16958
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:13218
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:150
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16606
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9309
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:4394
#define SCIP_REAL_MAX
Definition: def.h:151
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5285
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6683
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6526
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:13349
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:11092
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7631
#define checkRowObjprod(row)
Definition: lp.c:753
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12946
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:15991
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8070
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:13120
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:564
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:2604
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:154
methods for sorting joint arrays of various types
SCIP_COL ** lazycols
Definition: struct_lp.h:288
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:1449
#define SCIP_LONGINT_FORMAT
Definition: def.h:142
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)
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:268
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16835
#define SQRT(x)
Definition: def.h:192
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:15109
SCIP_VAR ** b
Definition: circlepacking.c:56
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12966
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16713
#define MAX(x, y)
Definition: def.h:208
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6756
int age
Definition: struct_lp.h:168
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:210
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:150
SCIP_Real * vals
Definition: struct_lp.h:153
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6505
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:364
SCIP_Real rellooseobjval
Definition: struct_lp.h:264
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16639
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8881
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10076
static const SCIP_Real scalars[]
Definition: lp.c:5650
int lpipos
Definition: struct_lp.h:164
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_Real objlim)
Definition: lp.c:2648
int chgcolssize
Definition: struct_lp.h:307
int lpitiming
Definition: struct_lp.h:333
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:623
SCIP_Longint domchgcount
Definition: struct_stat.h:105
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:215
SCIP_Real * divechgsides
Definition: struct_lp.h:292
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:17091
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8639
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1616
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
SCIP_Real rootlpobjval
Definition: struct_lp.h:272
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1759
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:135
unsigned int coefchanged
Definition: struct_lp.h:247
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:144
SCIP_Longint nbarrierlps
Definition: struct_stat.h:183
SCIP_Bool flushed
Definition: struct_lp.h:351
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8431
SCIP_CLOCK * primallptime
Definition: struct_stat.h:148
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13626
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6318
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:128
int lpdepth
Definition: struct_lp.h:165
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
unsigned int inglobalcutpool
Definition: struct_lp.h:252
int nrows
Definition: struct_lp.h:319
#define checkRowSqrnorm(row)
Definition: lp.c:751
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:15185
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:157
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13861
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:176
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
data structures for LP management
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4694
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:384
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:230
SCIP_VAR * a
Definition: circlepacking.c:57
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:608
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6161
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6029
datastructures for problem variables
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:16770
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16848
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
struct SCIP_LPi SCIP_LPI
Definition: type_lpi.h:96
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17058
int ndivingrows
Definition: struct_lp.h:326
SCIP_Longint divenolddomchgs
Definition: struct_lp.h:300
SCIP_Real lpobjval
Definition: struct_lp.h:261
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, 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:4236
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:10145
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:150
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17337
int size
Definition: struct_lp.h:159
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7707
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6472
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:3669
SCIP_Real lpiobjlim
Definition: struct_lp.h:275
SCIP_VAR ** y
Definition: circlepacking.c:55
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:5865
#define SCIPsetDebugMsgPrint
Definition: set.h:1941
int lpirowssize
Definition: struct_lp.h:304
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4098
#define BMSallocMemory(ptr)
Definition: memory.h:101
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14097
#define SCIP_INVALID
Definition: def.h:170
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:109
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:5605
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17327
SCIP_CLOCK * duallptime
Definition: struct_stat.h:149
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:135
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17455
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6672
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10122
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3012
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17069
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14603
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2953
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:5654
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:342
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6417
SCIP_VAR * var
Definition: struct_lp.h:151
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9790
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7785
int nlazycols
Definition: struct_lp.h:315
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:16938
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:334
SCIP_Bool dualfeasible
Definition: struct_lp.h:355
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6578
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4072
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6131
unsigned int nlocks
Definition: struct_lp.h:254
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2853
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17409
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:433
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6694
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3372
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3913
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:933
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:112
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9815
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13973
SCIP_Longint obsoletenode
Definition: struct_lp.h:212
SCIP_Longint nnodes
Definition: struct_stat.h:73
SCIP_Real lpifeastol
Definition: struct_lp.h:276
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13160
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:910
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4201
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13837
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:1479
#define SCIP_CALL_ABORT(x)
Definition: def.h:330
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3136
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17162
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16616
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:5316
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:3889
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:14136
#define SCIP_ALLOC(x)
Definition: def.h:362
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12935
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6302
#define SCIPABORT()
Definition: def.h:323
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2878
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:199
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:338
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:2227
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:16727
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6584
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2501
unsigned int nonlpcolssorted
Definition: struct_lp.h:242
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:16680
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16920
const char * SCIPlpiGetSolverName(void)
SCIP_Bool flushaddedcols
Definition: struct_lp.h:347
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:10494
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17112
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:344
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:10303
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:8454
int ncols
Definition: struct_lp.h:313
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2593
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4132
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:16845
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17408
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:439
SCIP_Real objsqrnorm
Definition: struct_lp.h:280
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1347
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3599
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:16702
unsigned int local
Definition: struct_lp.h:249
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
#define ABS(x)
Definition: def.h:204
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5174
SCIP_Bool probing
Definition: struct_lp.h:363
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:348
SCIP_Real looseobjval
Definition: struct_lp.h:262
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7695
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6483
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3189
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:12013
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9472
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:11229
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
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:5547
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:922
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5300
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:3824
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:3967
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:279
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3102
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17048
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:752