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-2019 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 
11472  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11473  * optimal without preforming scaling/change tolerances/presolving */
11474  resolve = FALSE;
11475 
11476  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11477  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11478  return SCIP_OKAY;
11479 
11480  if( !set->lp_checkstability )
11481  {
11482  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11483  if( success )
11484  {
11485  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11486  return SCIP_OKAY;
11487  }
11488  }
11489 
11490  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11491  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11492  */
11493 
11494  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11495  * do this only if the iteration limit was not exceeded in the last LP solving call
11496  */
11497  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11498  {
11499  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11500  if( success )
11501  {
11502  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11503  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11504 
11505  /* check for stability */
11506  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11507  return SCIP_OKAY;
11508 
11509  if( !set->lp_checkstability )
11510  {
11511  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11512  if( success )
11513  {
11514  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11515  return SCIP_OKAY;
11516  }
11517  }
11518  }
11519  }
11520 
11521  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11522  * and go directly to solving the LP from scratch
11523  */
11524  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11525  {
11526  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11527  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11528  if( success )
11529  {
11530  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11531  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11532  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11533 
11534  /* check for stability */
11535  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11536  return SCIP_OKAY;
11537 
11538  if( !set->lp_checkstability )
11539  {
11540  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11541  if( success )
11542  {
11543  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11544  return SCIP_OKAY;
11545  }
11546  }
11547 
11548  /* reset scaling */
11549  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11550  assert(success);
11551  }
11552  }
11553 
11554  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11555  * and go directly to solving the LP from scratch */
11556  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11557  {
11558  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11559  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11560  if( success )
11561  {
11562  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11563  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11564  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11565 
11566  /* check for stability */
11567  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11568  return SCIP_OKAY;
11569 
11570  if( !set->lp_checkstability )
11571  {
11572  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11573  if( success )
11574  {
11575  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11576  return SCIP_OKAY;
11577  }
11578  }
11579 
11580  /* reset presolving */
11581  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11582  assert(success);
11583  }
11584  }
11585 
11586  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11587  * do this only if the iteration limit was not exceeded in the last LP solving call
11588  */
11589  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11590  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11591  {
11592  success = FALSE;
11593  if( !tightprimfeastol )
11594  {
11595  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11596  }
11597 
11598  success2 = FALSE;
11599  if( !tightdualfeastol )
11600  {
11602  }
11603 
11604  success3 = FALSE;
11605  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11606  {
11608  }
11609 
11610  if( success || success2 || success3 )
11611  {
11612  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11613  lpalgoName(lpalgo));
11614  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11615 
11616  /* check for stability */
11617  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11618  return SCIP_OKAY;
11619 
11620  if( !set->lp_checkstability )
11621  {
11622  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11623  if( success )
11624  {
11625  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11626  return SCIP_OKAY;
11627  }
11628  }
11629 
11630  /* reset feasibility tolerance */
11631  if( !tightprimfeastol )
11632  {
11633  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11634  }
11635  if( !tightdualfeastol )
11636  {
11637  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11638  }
11639  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11640  {
11641  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11642  }
11643  }
11644  }
11645 
11646  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11647  * the given iteration limit might be a soft one to restrict resolving calls only */
11648  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11649 
11650  /* if not already done, solve again from scratch */
11651  if( !fromscratch && simplex )
11652  {
11653  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11654  if( success )
11655  {
11656  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11657  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11658 
11659  /* check for stability */
11660  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11661  return SCIP_OKAY;
11662 
11663  if( !set->lp_checkstability )
11664  {
11665  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11666  if( success )
11667  {
11668  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11669  return SCIP_OKAY;
11670  }
11671  }
11672  }
11673  }
11674 
11675  /* solve again, use other simplex this time */
11676  if( simplex )
11677  {
11679  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11680  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11681 
11682  /* check for stability */
11683  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11684  return SCIP_OKAY;
11685 
11686  if( !set->lp_checkstability )
11687  {
11688  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11689  if( success )
11690  {
11691  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11692  return SCIP_OKAY;
11693  }
11694  }
11695 
11696  /* solve again with opposite scaling and other simplex */
11697  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11698  if( success )
11699  {
11700  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11701  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11702  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11703 
11704  /* check for stability */
11705  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11706  return SCIP_OKAY;
11707 
11708  if( !set->lp_checkstability )
11709  {
11710  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11711  if( success )
11712  {
11713  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11714  return SCIP_OKAY;
11715  }
11716  }
11717 
11718  /* reset scaling */
11719  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11720  assert(success);
11721  }
11722 
11723  /* solve again with opposite presolving and other simplex */
11724  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11725  if( success )
11726  {
11727  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11728  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11729  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11730 
11731  /* check for stability */
11732  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11733  return SCIP_OKAY;
11734 
11735  if( !set->lp_checkstability )
11736  {
11737  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11738  if( success )
11739  {
11740  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11741  return SCIP_OKAY;
11742  }
11743  }
11744 
11745  /* reset presolving */
11746  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11747  assert(success);
11748  }
11749 
11750  /* solve again with tighter feasibility tolerance, use other simplex this time */
11751  if( !tightprimfeastol || !tightdualfeastol )
11752  {
11753  success = FALSE;
11754  if( !tightprimfeastol )
11755  {
11756  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * SCIPsetLpfeastol(set), &success) );
11757  }
11758 
11759  success2 = FALSE;
11760  if( !tightdualfeastol )
11761  {
11763  }
11764 
11765  if( success || success2 )
11766  {
11767  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11768  lpalgoName(lpalgo));
11769  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11770 
11771  /* check for stability */
11772  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11773  return SCIP_OKAY;
11774 
11775  if( !set->lp_checkstability )
11776  {
11777  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, &success) );
11778  if( success )
11779  {
11780  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11781  return SCIP_OKAY;
11782  }
11783  }
11784 
11785  /* reset feasibility tolerance */
11786  if( !tightprimfeastol )
11787  {
11788  SCIP_CALL( lpSetFeastol(lp, SCIPsetLpfeastol(set), &success) );
11789  }
11790  if( !tightdualfeastol )
11791  {
11792  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11793  }
11794  }
11795  }
11796  }
11797 
11798  /* nothing worked -- exit with an LPERROR */
11799  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11800  *lperror = TRUE;
11801 
11802  return SCIP_OKAY;
11803 }
11804 
11805 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11806 static
11808  SCIP_LP* lp, /**< current LP data */
11809  SCIP_SET* set, /**< global SCIP settings */
11810  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11811  )
11812 {
11813  assert(lp != NULL);
11814  assert(set != NULL);
11815 
11816  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11817  {
11818  if( !lp->adjustlpval && messagehdlr != NULL )
11819  {
11820  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
11821  lp->adjustlpval = TRUE;
11822  }
11823  lp->lpobjval = SCIPsetInfinity(set);
11824  }
11825  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
11826  {
11827  if( !lp->adjustlpval && messagehdlr != NULL )
11828  {
11829  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
11830  lp->adjustlpval = TRUE;
11831  }
11832  lp->lpobjval = -SCIPsetInfinity(set);
11833  }
11834 }
11835 
11836 /** solves the LP with the given algorithm and evaluates return status */
11837 static
11839  SCIP_LP* lp, /**< current LP data */
11840  SCIP_SET* set, /**< global SCIP settings */
11841  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11842  SCIP_STAT* stat, /**< problem statistics */
11843  SCIP_PROB* prob, /**< problem data */
11844  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11845  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
11846  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11847  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
11848  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
11849  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11850  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11851  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11852  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11853  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11854  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11855  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11856  )
11857 {
11858  SCIP_Bool solvedprimal;
11859  SCIP_Bool solveddual;
11860  SCIP_Bool timelimit;
11861  int itlim;
11862 
11863  assert(lp != NULL);
11864  assert(lp->flushed);
11865  assert(set != NULL);
11866  assert(stat != NULL);
11867  assert(lperror != NULL);
11868 
11869  checkLinks(lp);
11870 
11871  solvedprimal = FALSE;
11872  solveddual = FALSE;
11873  timelimit = FALSE;
11874 
11875  /* select the basic iteration limit depending on whether this is a resolving call or not */
11876  itlim = ( resolve ? resolveitlim : harditlim );
11877 
11878  SOLVEAGAIN:
11879  /* call simplex */
11880  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
11881  keepsol, &timelimit, lperror) );
11882  resolve = FALSE; /* only the first solve should be counted as resolving call */
11883  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
11884  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
11885 
11886  /* check, if an error occurred */
11887  if( *lperror )
11888  {
11889  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
11890  lp->solved = FALSE;
11892  return SCIP_OKAY;
11893  }
11894 
11895  /* check, if a time limit was exceeded */
11896  if( timelimit )
11897  {
11898  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
11899  lp->solved = TRUE;
11901  lp->lpobjval = -SCIPsetInfinity(set);
11902  return SCIP_OKAY;
11903  }
11904 
11905  /* only one should return true */
11906  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
11908 
11909  /* evaluate solution status */
11910  if( SCIPlpiIsOptimal(lp->lpi) )
11911  {
11912  assert(lp->primalfeasible);
11913  assert(lp->dualfeasible);
11915  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11916  adjustLPobjval(lp, set, messagehdlr);
11917 
11918  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
11919  {
11920  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
11921  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
11923  lp->lpobjval = SCIPsetInfinity(set);
11924  }
11925  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
11926  * reached if the LP objective value is greater than the cutoff bound
11927  */
11929  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
11930  }
11931  else if( SCIPlpiIsObjlimExc(lp->lpi) )
11932  {
11933  assert(!lpCutoffDisabled(set));
11935  lp->lpobjval = SCIPsetInfinity(set);
11936  }
11937  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
11938  {
11939  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11940  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
11941  {
11942  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11943  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11944  goto SOLVEAGAIN;
11945  }
11947  lp->lpobjval = SCIPsetInfinity(set);
11948  }
11949  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
11950  {
11951  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
11952  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
11953  {
11954  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
11955  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11956  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11957  goto SOLVEAGAIN;
11958  }
11960  lp->lpobjval = -SCIPsetInfinity(set);
11961  }
11962  else if( SCIPlpiIsIterlimExc(lp->lpi) )
11963  {
11964  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
11965 
11966  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
11967  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
11968  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
11969  adjustLPobjval(lp, set, NULL);
11970  else
11971  adjustLPobjval(lp, set, messagehdlr);
11972 
11974  }
11975  else if( SCIPlpiIsTimelimExc(lp->lpi) )
11976  {
11977  lp->lpobjval = -SCIPsetInfinity(set);
11979  }
11980  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
11981  {
11982  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
11983  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
11984  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11985  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11986  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11987  goto SOLVEAGAIN;
11988  }
11989  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
11990  {
11991  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
11992  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
11993  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
11994  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
11995  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
11996  goto SOLVEAGAIN;
11997  }
11998  else
11999  {
12000  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12001  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12003  return SCIP_LPERROR;
12004  }
12005 
12006  lp->solved = TRUE;
12007 
12008  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12011 
12012  return SCIP_OKAY;
12013 }
12014 
12015 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12016 static
12018  SCIP_LP* lp, /**< current LP data */
12019  BMS_BLKMEM* blkmem, /**< block memory */
12020  SCIP_SET* set, /**< global SCIP settings */
12021  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12022  SCIP_STAT* stat, /**< problem statistics */
12023  SCIP_PROB* prob, /**< problem data */
12024  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12025  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12026  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12027  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12028  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12029  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12030  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12031  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12032  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12033  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12034  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12035  )
12036 {
12037  SCIP_Bool resolve;
12038  char algo;
12039 
12040  assert(lp != NULL);
12041  assert(set != NULL);
12042  assert(lperror != NULL);
12043 
12044  /* flush changes to the LP solver */
12045  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12046  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12047 
12048  /* select LP algorithm to apply */
12049  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12050  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12051 
12052  switch( algo )
12053  {
12054  case 's':
12055  /* select simplex method */
12056  if( lp->dualfeasible || !lp->primalfeasible )
12057  {
12058  SCIPsetDebugMsg(set, "solving dual LP\n");
12059  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12060  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12061  }
12062  else
12063  {
12064  SCIPsetDebugMsg(set, "solving primal LP\n");
12065  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12066  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12067  }
12068  break;
12069 
12070  case 'p':
12071  SCIPsetDebugMsg(set, "solving primal LP\n");
12072  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12073  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12074  break;
12075 
12076  case 'd':
12077  SCIPsetDebugMsg(set, "solving dual LP\n");
12078  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12079  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12080  break;
12081 
12082  case 'b':
12083  SCIPsetDebugMsg(set, "solving barrier LP\n");
12084  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12085  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12086  break;
12087 
12088  case 'c':
12089  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12090  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12091  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12092  break;
12093 
12094  default:
12095  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12096  return SCIP_PARAMETERWRONGVAL;
12097  }
12098  assert(!(*lperror) || !lp->solved);
12099 
12100  return SCIP_OKAY;
12101 }
12102 
12103 #ifndef NDEBUG
12104 /** checks if the lazy bounds are valid */
12105 static
12107  SCIP_LP* lp, /**< LP data */
12108  SCIP_SET* set /**< global SCIP settings */
12109  )
12110 {
12111  SCIP_COL* col;
12112  int c;
12113 
12114  assert(lp->flushed);
12115 
12116  for( c = 0; c < lp->nlazycols; ++c )
12117  {
12118  col = lp->lazycols[c];
12119 
12120  /* in case lazy bounds are given, check that the primal solution satisfies them */
12121  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12122  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12123  }
12124 }
12125 #else
12126 #define checkLazyBounds(lp, set) /**/
12127 #endif
12128 
12129 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12130  * diving
12131  */
12132 static
12134  SCIP_LP* lp, /**< LP data */
12135  SCIP_SET* set /**< global SCIP settings */
12136  )
12137 {
12138  SCIP_COL* col;
12139  int c;
12140 
12141  assert(lp->nlazycols > 0);
12142 
12143  /* return, if we are in diving, and bounds were already applied
12144  * or if we are not in diving and bounds were not applied
12145  */
12146  if( lp->diving == lp->divinglazyapplied )
12147  return SCIP_OKAY;
12148 
12149  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12150  lp->diving, lp->divinglazyapplied);
12151 
12152  for( c = 0; c < lp->nlazycols; ++c )
12153  {
12154  col = lp->lazycols[c];
12155 
12156  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12157  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12158  {
12159  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb)); /*lint !e777*/
12160  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12161  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12162 
12163  /* insert column in the chgcols list (if not already there) */
12164  SCIP_CALL( insertColChgcols(col, set, lp) );
12165 
12166  /* mark bound change in the column */
12167  col->lbchanged = TRUE;
12168  }
12169 
12170  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12171  if( !SCIPsetIsInfinity(set, col->lazyub) )
12172  {
12173  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub)); /*lint !e777*/
12174  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12175  || (col->flushedub == SCIPlpiInfinity(lp->lpi))); /*lint !e777*/
12176 
12177  /* insert column in the chgcols list (if not already there) */
12178  SCIP_CALL( insertColChgcols(col, set, lp) );
12179 
12180  /* mark bound change in the column */
12181  col->ubchanged = TRUE;
12182  }
12183  }
12184 
12185  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12186  * if not, we just removed them
12187  */
12188  lp->divinglazyapplied = lp->diving;
12189 
12190  return SCIP_OKAY;
12191 }
12192 
12193 /** returns the iteration limit for an LP resolving call */
12194 static
12196  SCIP_SET* set, /**< global SCIP settings */
12197  SCIP_STAT* stat, /**< dynamic problem statistics */
12198  int itlim /**< hard iteration limit */
12199  )
12200 {
12201  /* no limit set or average not yet reliable */
12202  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12203  return itlim;
12204  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12205  if( itlim == -1 )
12206  itlim = INT_MAX;
12207  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12208  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12209  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12210 }
12211 
12212 
12213 
12214 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12216  SCIP_LP* lp, /**< LP data */
12217  SCIP_SET* set, /**< global SCIP settings */
12218  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12219  BMS_BLKMEM* blkmem, /**< block memory buffers */
12220  SCIP_STAT* stat, /**< problem statistics */
12221  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12222  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12223  SCIP_PROB* prob, /**< problem data */
12224  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12225  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12226  * (limit is computed within the method w.r.t. the average LP iterations) */
12227  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12228  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12229  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12230  )
12231 {
12232  SCIP_RETCODE retcode;
12233  SCIP_Bool needprimalray;
12234  SCIP_Bool needdualray;
12235  int harditlim;
12236  int resolveitlim;
12237 
12238  assert(lp != NULL);
12239  assert(prob != NULL);
12240  assert(prob->nvars >= lp->ncols);
12241  assert(lperror != NULL);
12242 
12243  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12244  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12245 
12246  retcode = SCIP_OKAY;
12247  *lperror = FALSE;
12248 
12249  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12250  needprimalray = TRUE;
12251  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12252  || (set->conf_enable && set->conf_useinflp != 'o'));
12253 
12254  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12255  harditlim = (int) MIN(itlim, INT_MAX);
12256  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12257  assert(harditlim == -1 || (resolveitlim <= harditlim));
12258 
12259  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12260  * or removed from the LP (diving was ended)
12261  */
12262  if( lp->nlazycols > 0 )
12263  {
12264  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12265  * first resolve LP?
12266  */
12267  SCIP_CALL( updateLazyBounds(lp, set) );
12268  assert(lp->diving == lp->divinglazyapplied);
12269  }
12270 
12271  /* flush changes to the LP solver */
12272  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
12273  assert(lp->flushed);
12274 
12275  /* 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
12276  * to run again anyway, since there seems to be some time left / the time limit was increased
12277  */
12278  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12279  {
12280  SCIP_Bool* primalfeaspointer;
12281  SCIP_Bool* dualfeaspointer;
12282  SCIP_Bool primalfeasible;
12283  SCIP_Bool dualfeasible;
12284  SCIP_Bool farkasvalid;
12285  SCIP_Bool rayfeasible;
12286  SCIP_Bool tightprimfeastol;
12287  SCIP_Bool tightdualfeastol;
12288  SCIP_Bool fromscratch;
12289  SCIP_Bool wasfromscratch;
12290  SCIP_Longint oldnlps;
12291  int fastmip;
12292 
12293  /* set initial LP solver settings */
12294  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12295  tightprimfeastol = FALSE;
12296  tightdualfeastol = FALSE;
12297  fromscratch = FALSE;
12298  primalfeasible = FALSE;
12299  dualfeasible = FALSE;
12300  wasfromscratch = (stat->nlps == 0);
12301 
12302  SOLVEAGAIN:
12303  /* solve the LP */
12304  oldnlps = stat->nlps;
12305  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12306  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12307  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12308  assert(!(*lperror) || !lp->solved);
12309 
12310  /* check for error */
12311  if( *lperror )
12312  {
12313  retcode = SCIP_OKAY;
12314  goto TERMINATE;
12315  }
12316 
12317  /* evaluate solution status */
12318  switch( SCIPlpGetSolstat(lp) )
12319  {
12321  /* get LP solution and possibly check the solution's feasibility again */
12322  if( set->lp_checkprimfeas )
12323  {
12324  primalfeaspointer = &primalfeasible;
12325  lp->primalchecked = TRUE;
12326  }
12327  else
12328  {
12329  /* believe in the primal feasibility of the LP solution */
12330  primalfeasible = TRUE;
12331  primalfeaspointer = NULL;
12332  lp->primalchecked = FALSE;
12333  }
12334  if( set->lp_checkdualfeas )
12335  {
12336  dualfeaspointer = &dualfeasible;
12337  lp->dualchecked = TRUE;
12338  }
12339  else
12340  {
12341  /* believe in the dual feasibility of the LP solution */
12342  dualfeasible = TRUE;
12343  dualfeaspointer = NULL;
12344  lp->dualchecked = FALSE;
12345  }
12346 
12347  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12348 
12349  /* in debug mode, check that lazy bounds (if present) are not violated */
12350  checkLazyBounds(lp, set);
12351 
12352  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12353  {
12354  /* update ages and remove obsolete columns and rows from LP */
12355  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12356  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12357  {
12358  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12359  }
12360 
12361  if( !lp->solved )
12362  {
12363  /* resolve LP after removing obsolete columns and rows */
12364  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12365  aging = FALSE; /* to prevent infinite loops */
12366  goto SOLVEAGAIN;
12367  }
12368  }
12369  if( !primalfeasible || !dualfeasible )
12370  {
12372 
12373  if( (fastmip > 0) && simplex )
12374  {
12375  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12376  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12377  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again without FASTMIP\n",
12378  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12379  fastmip = 0;
12380  goto SOLVEAGAIN;
12381  }
12382  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12383  {
12384  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12385  * tolerance
12386  */
12387  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12388  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again with tighter feasibility tolerance\n",
12389  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12390  tightprimfeastol = tightprimfeastol || !primalfeasible;
12391  tightdualfeastol = tightdualfeastol || !dualfeasible;
12392  goto SOLVEAGAIN;
12393  }
12394  else if( !fromscratch && !wasfromscratch && simplex )
12395  {
12396  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12397  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12398  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, dfeas=%d) -- solving again from scratch\n",
12399  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12400  fromscratch = TRUE;
12401  goto SOLVEAGAIN;
12402  }
12403  else
12404  {
12405  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12406  lp->solved = FALSE;
12408  *lperror = TRUE;
12409  }
12410  }
12411  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12412  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12413  lp->lpsolstat, lp->cutoffbound);
12414  break;
12415 
12417  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12418  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12419  {
12420  if( SCIPlpiHasDualRay(lp->lpi) )
12421  {
12422  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12423  }
12424  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12425  * with the primal simplex due to numerical problems) - treat this case like an LP error
12426  */
12427  else
12428  {
12429  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12430  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12431  lp->solved = FALSE;
12433  farkasvalid = FALSE;
12434  *lperror = TRUE;
12435  }
12436  }
12437  else
12438  farkasvalid = TRUE;
12439 
12440  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12441  if( !farkasvalid && !(*lperror) )
12442  {
12444 
12445  if( (fastmip > 0) && simplex )
12446  {
12447  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12448  * without FASTMIP
12449  */
12450  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12451  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12452  stat->nnodes, stat->nlps);
12453  fastmip = 0;
12454  goto SOLVEAGAIN;
12455  }
12456  else if( !tightdualfeastol )
12457  {
12458  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12459  * solve again with tighter feasibility tolerance
12460  */
12461  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12462  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12463  stat->nnodes, stat->nlps);
12464  tightdualfeastol = TRUE;
12465  goto SOLVEAGAIN;
12466  }
12467  else if( !fromscratch && simplex )
12468  {
12469  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12470  * from scratch
12471  */
12472  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12473  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12474  stat->nnodes, stat->nlps);
12475  fromscratch = TRUE;
12476  goto SOLVEAGAIN;
12477  }
12478  else
12479  {
12480  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12481  * helped forget about the LP at this node and mark it to be unsolved
12482  */
12483  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12484  lp->solved = FALSE;
12486  *lperror = TRUE;
12487  }
12488  }
12489 
12490  break;
12491 
12493  if( set->lp_checkprimfeas )
12494  {
12495  /* get unbounded LP solution and check the solution's feasibility again */
12496  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12497 
12498  lp->primalchecked = TRUE;
12499  }
12500  else
12501  {
12502  /* get unbounded LP solution believing in the feasibility of the LP solution */
12503  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12504 
12505  primalfeasible = TRUE;
12506  rayfeasible = TRUE;
12507  lp->primalchecked = FALSE;
12508  }
12509 
12510  /* in debug mode, check that lazy bounds (if present) are not violated */
12511  checkLazyBounds(lp, set);
12512 
12513  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12514  primalfeasible, rayfeasible);
12515 
12516  if( !primalfeasible || !rayfeasible )
12517  {
12519 
12520  if( (fastmip > 0) && simplex )
12521  {
12522  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12523  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12524  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again without FASTMIP\n",
12525  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12526  fastmip = 0;
12527  goto SOLVEAGAIN;
12528  }
12529  else if( !tightprimfeastol )
12530  {
12531  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12532  * tolerance
12533  */
12534  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12535  "(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",
12536  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12537  tightprimfeastol = TRUE;
12538  goto SOLVEAGAIN;
12539  }
12540  else if( !fromscratch && simplex )
12541  {
12542  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12543  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12544  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%d, rfeas=%d) -- solving again from scratch\n",
12545  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12546  fromscratch = TRUE;
12547  goto SOLVEAGAIN;
12548  }
12549  else
12550  {
12551  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12552  * forget about the LP at this node and mark it to be unsolved
12553  */
12554  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12555  lp->solved = FALSE;
12557  *lperror = TRUE;
12558  }
12559  }
12560 
12561  break;
12562 
12564  assert(!lpCutoffDisabled(set));
12565  /* if we do branch-and-price, make sure that a dual feasible solution exists, that exceeds the objective limit;
12566  * With FASTMIP setting, CPLEX does not apply the final pivot to reach the dual solution exceeding the objective
12567  * limit. Therefore, we have to either turn off FASTMIP and resolve the problem or continue solving it without
12568  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12569  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12570  * FASTMIP and solve again.
12571  */
12572  if( !SCIPprobAllColsInLP(prob, set, lp) && fastmip )
12573  {
12574  SCIP_LPI* lpi;
12575  SCIP_Real objval;
12576 
12577  lpi = SCIPlpGetLPI(lp);
12578 
12579  assert(lpi != NULL);
12580  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12581  * the assert by using !SCIPsetIsFeasNegative()
12582  */
12583  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12584 
12585  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12586 
12587  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12588  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12589  {
12590  SCIP_Real tmpcutoff;
12591  char tmppricingchar;
12592  SCIP_LPSOLSTAT solstat;
12593 
12594  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12595 
12596  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12597  fromscratch = FALSE;
12598 
12599  /* temporarily disable cutoffbound, which also disables the objective limit */
12600  tmpcutoff = lp->cutoffbound;
12601  lp->cutoffbound = SCIPlpiInfinity(lpi);
12602 
12603  /* set lp pricing strategy to steepest edge */
12604  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12605  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12606 
12607  /* resolve LP with an iteration limit of 1 */
12608  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12609  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12610 
12611  /* reinstall old cutoff bound and lp pricing strategy */
12612  lp->cutoffbound = tmpcutoff;
12613  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12614 
12615  /* get objective value */
12616  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12617 
12618  /* get solution status for the lp */
12619  solstat = SCIPlpGetSolstat(lp);
12620  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12621 
12622  if( !(*lperror) && solstat != SCIP_LPSOLSTAT_ERROR && solstat != SCIP_LPSOLSTAT_NOTSOLVED )
12623  {
12624  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12625  }
12626 
12627  /* disable fastmip for subsequent LP calls (if objective limit is not yet exceeded or LP solution is infeasible) */
12628  fastmip = 0;
12629 
12630  /* the solution is still not exceeding the objective limit and the solving process
12631  * was stopped due to time or iteration limit, solve again with fastmip turned off
12632  */
12633  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12634  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12635  {
12636  assert(!(*lperror));
12637 
12638  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12639  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12640 
12641  /* get objective value */
12642  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12643 
12644  /* get solution status for the lp */
12645  solstat = SCIPlpGetSolstat(lp);
12646 
12647  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12648  }
12649 
12650  /* check for lp errors */
12651  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12652  {
12653  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12654  lp->solved = FALSE;
12656 
12657  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12658  goto TERMINATE;
12659  }
12660 
12661  lp->solved = TRUE;
12662 
12663  /* optimal solution / objlimit with fastmip turned off / itlimit or timelimit, but objlimit exceeded */
12664  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12665  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12666  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12667  {
12668  /* get LP solution and possibly check the solution's feasibility again */
12669  if( set->lp_checkprimfeas )
12670  {
12671  primalfeaspointer = &primalfeasible;
12672  lp->primalchecked = TRUE;
12673  }
12674  else
12675  {
12676  /* believe in the primal feasibility of the LP solution */
12677  primalfeasible = TRUE;
12678  primalfeaspointer = NULL;
12679  lp->primalchecked = FALSE;
12680  }
12681  if( set->lp_checkdualfeas )
12682  {
12683  dualfeaspointer = &dualfeasible;
12684  lp->dualchecked = TRUE;
12685  }
12686  else
12687  {
12688  /* believe in the dual feasibility of the LP solution */
12689  dualfeasible = TRUE;
12690  dualfeaspointer = NULL;
12691  lp->dualchecked = FALSE;
12692  }
12693 
12694  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12695 
12696  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12697  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12698  {
12699  checkLazyBounds(lp, set);
12700  }
12701 
12702  /* if objective value is larger than the cutoff bound, set solution status to objective
12703  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12704  * this was already done in the lpSolve() method
12705  */
12706  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12707  {
12709  lp->lpobjval = SCIPsetInfinity(set);
12710  }
12711 
12712  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12713  * the cutoffbound; mark the LP to be unsolved
12714  */
12715  if( !primalfeasible || !dualfeasible
12716  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12717  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12718  {
12719  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12720  lp->solved = FALSE;
12722  *lperror = TRUE;
12723  }
12724 
12725  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12726  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12727  lp->lpsolstat, lp->cutoffbound);
12728  }
12729  /* infeasible solution */
12730  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12731  {
12732  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12733 
12734  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12735  {
12736  if( SCIPlpiHasDualRay(lp->lpi) )
12737  {
12738  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12739  }
12740  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12741  * with the primal simplex due to numerical problems) - treat this case like an LP error
12742  */
12743  else
12744  {
12745  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12746  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12747  lp->solved = FALSE;
12749  farkasvalid = FALSE;
12750  *lperror = TRUE;
12751  }
12752  }
12753  else
12754  farkasvalid = TRUE;
12755 
12756  if( !farkasvalid )
12757  {
12759 
12760  if( !tightprimfeastol )
12761  {
12762  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12763  * solve again with tighter feasibility tolerance
12764  */
12765  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12766  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12767  stat->nnodes, stat->nlps);
12768  tightprimfeastol = TRUE;
12769  goto SOLVEAGAIN;
12770  }
12771  else if( simplex )
12772  {
12773  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12774  * from scratch
12775  */
12776  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12777  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12778  stat->nnodes, stat->nlps);
12779  fromscratch = TRUE;
12780  goto SOLVEAGAIN;
12781  }
12782  else
12783  {
12784  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12785  * helped forget about the LP at this node and mark it to be unsolved
12786  */
12787  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12788  lp->solved = FALSE;
12790  *lperror = TRUE;
12791  }
12792  }
12793  }
12794  /* unbounded solution */
12795  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12796  {
12797  if( set->lp_checkprimfeas )
12798  {
12799  /* get unbounded LP solution and check the solution's feasibility again */
12800  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12801 
12802  lp->primalchecked = TRUE;
12803  }
12804  else
12805  {
12806  /* get unbounded LP solution believing in its feasibility */
12807  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12808 
12809  primalfeasible = TRUE;
12810  rayfeasible = TRUE;
12811  lp->primalchecked = FALSE;
12812  }
12813 
12814  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
12815 
12816  /* in debug mode, check that lazy bounds (if present) are not violated */
12817  checkLazyBounds(lp, set);
12818 
12819  if( !primalfeasible || !rayfeasible )
12820  {
12821  /* unbounded solution is infeasible (this can happen due to numerical problems):
12822  * forget about the LP at this node and mark it to be unsolved
12823  *
12824  * @todo: like in the default LP solving evaluation, solve without fastmip,
12825  * with tighter feasibility tolerance and from scratch
12826  */
12827  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
12828  lp->solved = FALSE;
12830  *lperror = TRUE;
12831  }
12832  }
12833 
12834  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
12835  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
12837  }
12838  else
12839  {
12840  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12841  }
12842  }
12843  else if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12844  {
12845  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
12846  }
12847  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
12848  break;
12849 
12851  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
12852  break;
12853 
12855  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
12856 
12857  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
12858  stat->nclockskipsleft = 0;
12859  if( !SCIPsolveIsStopped(set, stat, FALSE) )
12860  {
12861  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
12862  "you might consider switching the clock type of SCIP\n");
12863  stat->status = SCIP_STATUS_TIMELIMIT;
12864  }
12865  break;
12866 
12867  case SCIP_LPSOLSTAT_ERROR:
12869  SCIPerrorMessage("error in LP solver\n");
12870  retcode = SCIP_LPERROR;
12871  goto TERMINATE;
12872 
12873  default:
12874  SCIPerrorMessage("unknown LP solution status\n");
12875  retcode = SCIP_ERROR;
12876  goto TERMINATE;
12877  }
12878  }
12879  assert(!(*lperror) || !lp->solved);
12880 
12881  TERMINATE:
12882  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
12883  * may happen that we continue to solve from scratch during strong branching */
12884  if( lp->lpifromscratch )
12885  {
12886  SCIP_Bool success;
12887  (void) lpSetFromscratch(lp, FALSE, &success);
12888  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
12889  }
12890 
12891  return retcode;
12892 }
12893 
12894 /** gets solution status of current LP */
12896  SCIP_LP* lp /**< current LP data */
12897  )
12898 {
12899  assert(lp != NULL);
12900  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
12901 
12902  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
12903 }
12904 
12905 /** gets objective value of current LP
12906  *
12907  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
12908  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
12909  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
12910  */
12912  SCIP_LP* lp, /**< current LP data */
12913  SCIP_SET* set, /**< global SCIP settings */
12914  SCIP_PROB* prob /**< problem data */
12915  )
12916 {
12917  assert(lp != NULL);
12918  assert(lp->solved);
12919  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12920  assert(set != NULL);
12921 
12922  if( !lp->flushed )
12923  return SCIP_INVALID;
12924  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
12925  return lp->lpobjval;
12926  else if( lp->looseobjvalinf > 0 )
12927  return -SCIPsetInfinity(set);
12928  else
12929  {
12930  /* recalculate the loose objective value, if needed */
12931  if( !lp->looseobjvalid )
12932  recomputeLooseObjectiveValue(lp, set, prob);
12933 
12934  return lp->lpobjval + lp->looseobjval;
12935  }
12936 }
12937 
12938 /** gets part of objective value of current LP that results from COLUMN variables only */
12940  SCIP_LP* lp /**< current LP data */
12941  )
12942 {
12943  assert(lp != NULL);
12944  assert(lp->solved);
12945 
12946  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
12947 }
12948 
12949 /** gets part of objective value of current LP that results from LOOSE variables only */
12951  SCIP_LP* lp, /**< current LP data */
12952  SCIP_SET* set, /**< global SCIP settings */
12953  SCIP_PROB* prob /**< problem data */
12954  )
12955 {
12956  assert(lp != NULL);
12957  assert(lp->solved);
12958  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
12959  assert(set != NULL);
12960 
12961  if( !lp->flushed )
12962  return SCIP_INVALID;
12963  else if( lp->looseobjvalinf > 0 )
12964  return -SCIPsetInfinity(set);
12965  else
12966  return getFiniteLooseObjval(lp, set, prob);
12967 }
12968 
12969 /** remembers the current LP objective value as root solution value */
12971  SCIP_LP* lp, /**< current LP data */
12972  SCIP_SET* set, /**< global SCIP settings */
12973  SCIP_PROB* prob /**< problem data */
12974  )
12975 {
12976  assert(lp != NULL);
12977 
12979  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
12980 }
12981 
12982 /** invalidates the root LP solution value */
12984  SCIP_LP* lp /**< current LP data */
12985  )
12986 {
12987  assert(lp != NULL);
12988 
12989  lp->rootlpobjval = SCIP_INVALID;
12991 }
12992 
12993 /** recomputes local and global pseudo objective values */
12995  SCIP_LP* lp, /**< current LP data */
12996  SCIP_SET* set, /**< global SCIP settings */
12997  SCIP_PROB* prob /**< problem data */
12998  )
12999 {
13000  SCIP_VAR** vars;
13001  int nvars;
13002  int v;
13003 
13004  assert(lp != NULL);
13005  assert(set != NULL);
13006  assert(prob != NULL);
13007 
13008  vars = prob->vars;
13009  nvars = prob->nvars;
13010 
13011  lp->glbpseudoobjvalinf = 0;
13012  lp->glbpseudoobjval = 0.0;
13013 
13014  lp->pseudoobjvalinf = 0;
13015  lp->pseudoobjval = 0.0;
13016 
13017  for( v = 0; v < nvars; ++v )
13018  {
13019  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13020 
13021  if( SCIPsetIsPositive(set, obj) )
13022  {
13023  /* update the global pseudo objective value */
13024  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13025  ++(lp->glbpseudoobjvalinf);
13026  else
13027  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13028 
13029  /* update the local pseudo objective value */
13030  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13031  ++(lp->pseudoobjvalinf);
13032  else
13033  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13034  }
13035 
13036  if( SCIPsetIsNegative(set, obj) )
13037  {
13038  /* update the global pseudo objective value */
13039  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13040  ++(lp->glbpseudoobjvalinf);
13041  else
13042  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13043 
13044  /* update the local pseudo objective value */
13045  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13046  ++(lp->pseudoobjvalinf);
13047  else
13048  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13049  }
13050  }
13051 
13052  /* the recomputed values are reliable */
13054  lp->glbpseudoobjvalid = TRUE;
13055  lp->relpseudoobjval = lp->pseudoobjval;
13056  lp->pseudoobjvalid = TRUE;
13057 }
13058 
13059 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13060  * global bound
13061  */
13063  SCIP_LP* lp, /**< current LP data */
13064  SCIP_SET* set, /**< global SCIP settings */
13065  SCIP_PROB* prob /**< problem data */
13066  )
13067 {
13068  assert(lp != NULL);
13069  assert(lp->glbpseudoobjvalinf >= 0);
13070  assert(set != NULL);
13071 
13072  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13073  return -SCIPsetInfinity(set);
13074  else
13075  {
13076  /* recalculate the global pseudo solution value, if needed */
13077  if( !lp->glbpseudoobjvalid )
13078  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13079 
13080  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13081  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13082  return -SCIPsetInfinity(set);
13083 
13084  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13085  return SCIPsetInfinity(set);
13086 
13087  return lp->glbpseudoobjval;
13088  }
13089 }
13090 
13091 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13092  * objective function) local bound
13093  */
13095  SCIP_LP* lp, /**< current LP data */
13096  SCIP_SET* set, /**< global SCIP settings */
13097  SCIP_PROB* prob /**< problem data */
13098  )
13099 {
13100  assert(lp != NULL);
13101  assert(lp->pseudoobjvalinf >= 0);
13102  assert(set != NULL);
13103 
13104  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13105  return -SCIPsetInfinity(set);
13106  else
13107  {
13108  /* recalculate the pseudo solution value, if needed */
13109  if( !lp->pseudoobjvalid )
13110  recomputePseudoObjectiveValue(lp, set, prob);
13111 
13112  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13113  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13114  return -SCIPsetInfinity(set);
13115 
13116  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13117  return SCIPsetInfinity(set);
13118 
13119  return lp->pseudoobjval;
13120  }
13121 }
13122 
13123 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13125  SCIP_LP* lp, /**< current LP data */
13126  SCIP_SET* set, /**< global SCIP settings */
13127  SCIP_PROB* prob, /**< problem data */
13128  SCIP_VAR* var, /**< problem variable */
13129  SCIP_Real oldbound, /**< old value for bound */
13130  SCIP_Real newbound, /**< new value for bound */
13131  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13132  )
13133 {
13134  SCIP_Real pseudoobjval;
13135  int pseudoobjvalinf;
13136  SCIP_Real obj;
13137 
13138  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13139  pseudoobjvalinf = lp->pseudoobjvalinf;
13140  obj = SCIPvarGetObj(var);
13141  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13142  {
13143  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13144  pseudoobjvalinf--;
13145  else
13146  pseudoobjval -= oldbound * obj;
13147  assert(pseudoobjvalinf >= 0);
13148  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13149  pseudoobjvalinf++;
13150  else
13151  pseudoobjval += newbound * obj;
13152  }
13153  assert(pseudoobjvalinf >= 0);
13154 
13155  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13156  return -SCIPsetInfinity(set);
13157  else
13158  return pseudoobjval;
13159 }
13160 
13161 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13162  * perform calculations with interval arithmetic to get an exact lower bound
13163  */
13165  SCIP_LP* lp, /**< current LP data */
13166  SCIP_SET* set, /**< global SCIP settings */
13167  SCIP_VAR* var, /**< problem variable */
13168  SCIP_Real oldbound, /**< old value for bound */
13169  SCIP_Real newbound, /**< new value for bound */
13170  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13171  )
13172 {
13173  SCIP_Real pseudoobjval;
13174  int pseudoobjvalinf;
13175  SCIP_Real obj;
13176 
13177  assert(lp->pseudoobjvalid);
13178 
13179  pseudoobjval = lp->pseudoobjval;
13180  pseudoobjvalinf = lp->pseudoobjvalinf;
13181  obj = SCIPvarGetObj(var);
13182  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13183  {
13184  SCIP_INTERVAL objint;
13185  SCIP_INTERVAL bd;
13186  SCIP_INTERVAL prod;
13187  SCIP_INTERVAL psval;
13188 
13189  SCIPintervalSet(&psval, pseudoobjval);
13190  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13191 
13192  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13193  pseudoobjvalinf--;
13194  else
13195  {
13196  SCIPintervalSet(&bd, oldbound);
13197  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13198  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13199  }
13200  assert(pseudoobjvalinf >= 0);
13201  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13202  pseudoobjvalinf++;
13203  else
13204  {
13205  SCIPintervalSet(&bd, newbound);
13206  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13207  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13208  }
13209 
13210  pseudoobjval = SCIPintervalGetInf(psval);
13211  }
13212  assert(pseudoobjvalinf >= 0);
13213 
13214  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13215  return -SCIPsetInfinity(set);
13216  else
13217  return pseudoobjval;
13218 }
13219 
13220 /** compute the objective delta due the new objective coefficient */
13221 static
13223  SCIP_SET* set, /**< global SCIP settings */
13224  SCIP_Real oldobj, /**< old objective value of variable */
13225  SCIP_Real newobj, /**< new objective value of variable */
13226  SCIP_Real lb, /**< lower bound of variable */
13227  SCIP_Real ub, /**< upper bound of variable */
13228  SCIP_Real* deltaval, /**< pointer to store the delta value */
13229  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13230  )
13231 {
13232  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13233  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13234  assert(!SCIPsetIsInfinity(set, lb));
13235  assert(!SCIPsetIsInfinity(set, -ub));
13236  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13237 
13238  (*deltaval) = 0.0;
13239  (*deltainf) = 0;
13240 
13241  if( SCIPsetIsPositive(set, oldobj) )
13242  {
13243  /* sign of objective did not change */
13244  if( SCIPsetIsPositive(set, newobj) )
13245  {
13246  /* if the bound is finite, calculate the deltaval */
13247  if( !SCIPsetIsInfinity(set, -lb) )
13248  (*deltaval) = lb * (newobj - oldobj);
13249  }
13250  /* sign of objective did change, so the best bound does change */
13251  else if( SCIPsetIsNegative(set, newobj) )
13252  {
13253  if( SCIPsetIsInfinity(set, -lb) )
13254  {
13255  /* old best bound was infinite while new one is not */
13256  if( !SCIPsetIsInfinity(set, ub) )
13257  {
13258  (*deltainf) = -1;
13259  (*deltaval) = ub * newobj;
13260  }
13261  }
13262  else
13263  {
13264  /* new best bound is infinite while old one was not */
13265  if( SCIPsetIsInfinity(set, ub) )
13266  {
13267  (*deltainf) = 1;
13268  (*deltaval) = -lb * oldobj;
13269  }
13270  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13271  else
13272  {
13273  (*deltaval) = (ub * newobj) - (lb * oldobj);
13274  }
13275  }
13276  }
13277  /* new objective is 0.0 */
13278  else
13279  {
13280  if( SCIPsetIsInfinity(set, -lb) )
13281  (*deltainf) = -1;
13282  else
13283  (*deltaval) = -lb * oldobj;
13284  }
13285  }
13286  else if( SCIPsetIsNegative(set, oldobj) )
13287  {
13288  /* sign of objective did not change */
13289  if( SCIPsetIsNegative(set, newobj) )
13290  {
13291  /* if the bound is finite, calculate the deltaval */
13292  if( !SCIPsetIsInfinity(set, ub) )
13293  (*deltaval) = ub * (newobj - oldobj);
13294  }
13295  /* sign of objective did change, so the best bound does change */
13296  else if( SCIPsetIsPositive(set, newobj) )
13297  {
13298  if( SCIPsetIsInfinity(set, ub) )
13299  {
13300  /* old best bound was infinite while new one is not */
13301  if( !SCIPsetIsInfinity(set, -lb) )
13302  {
13303  (*deltainf) = -1;
13304  (*deltaval) = lb * newobj;
13305  }
13306  }
13307  else
13308  {
13309  /* new best bound is infinite while old one was not */
13310  if( SCIPsetIsInfinity(set, -lb) )
13311  {
13312  (*deltainf) = 1;
13313  (*deltaval) = -ub * oldobj;
13314  }
13315  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13316  else
13317  {
13318  (*deltaval) = (lb * newobj) - (ub * oldobj);
13319  }
13320  }
13321  }
13322  /* new objective is 0.0 */
13323  else
13324  {
13325  if( SCIPsetIsInfinity(set, ub) )
13326  (*deltainf) = -1;
13327  else
13328  (*deltaval) = -ub * oldobj;
13329  }
13330  }
13331  /* old objective was 0.0 */
13332  else
13333  {
13334  if( SCIPsetIsNegative(set, newobj) )
13335  {
13336  if( SCIPsetIsInfinity(set, ub) )
13337  (*deltainf) = 1;
13338  else
13339  (*deltaval) = ub * newobj;
13340  }
13341  else if( SCIPsetIsPositive(set, newobj) )
13342  {
13343  if( SCIPsetIsInfinity(set, -lb) )
13344  (*deltainf) = 1;
13345  else
13346  (*deltaval) = lb * newobj;
13347  }
13348  }
13349 }
13350 
13351 /** compute the objective delta due the new lower bound */
13352 static
13354  SCIP_SET* set, /**< global SCIP settings */
13355  SCIP_Real obj, /**< objective value of variable */
13356  SCIP_Real oldlb, /**< old lower bound of variable */
13357  SCIP_Real newlb, /**< new lower bound of variable */
13358  SCIP_Real* deltaval, /**< pointer to store the delta value */
13359  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13360  )
13361 {
13362  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13363  assert(!SCIPsetIsInfinity(set, oldlb));
13364  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13365  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13366 
13367  if( SCIPsetIsInfinity(set, -oldlb) )
13368  {
13369  if( !SCIPsetIsInfinity(set, newlb) )
13370  {
13371  (*deltainf) = -1;
13372  (*deltaval) = newlb * obj;
13373  }
13374  else
13375  {
13376  (*deltainf) = 0;
13377  (*deltaval) = 0.0;
13378  }
13379  }
13380  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13381  {
13382  (*deltainf) = 1;
13383  (*deltaval) = -oldlb * obj;
13384  }
13385  else
13386  {
13387  (*deltainf) = 0;
13388  (*deltaval) = obj * (newlb - oldlb);
13389  }
13390 }
13391 
13392 /** compute the objective delta due the new upper bound */
13393 static
13395  SCIP_SET* set, /**< global SCIP settings */
13396  SCIP_Real obj, /**< objective value of variable */
13397  SCIP_Real oldub, /**< old upper bound of variable */
13398  SCIP_Real newub, /**< new upper bound of variable */
13399  SCIP_Real* deltaval, /**< pointer to store the delta value */
13400  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13401  )
13402 {
13403  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13404  assert(!SCIPsetIsInfinity(set, -oldub));
13405  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13406  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13407 
13408  if( SCIPsetIsInfinity(set, oldub) )
13409  {
13410  if( !SCIPsetIsInfinity(set, -newub) )
13411  {
13412  (*deltainf) = -1;
13413  (*deltaval) = newub * obj;
13414  }
13415  else
13416  {
13417  (*deltainf) = 0;
13418  (*deltaval) = 0.0;
13419  }
13420  }
13421  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13422  {
13423  (*deltainf) = 1;
13424  (*deltaval) = -oldub * obj;
13425  }
13426  else
13427  {
13428  (*deltainf) = 0;
13429  (*deltaval) = obj * (newub - oldub);
13430  }
13431 }
13432 
13433 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13434 static
13436  SCIP_LP* lp, /**< current LP data */
13437  SCIP_SET* set, /**< global SCIP settings */
13438  SCIP_VAR* var, /**< problem variable that changed */
13439  SCIP_Real deltaval, /**< delta value in the objective function */
13440  int deltainf, /**< delta value for the number of variables with infinite best bound */
13441  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13442  SCIP_Bool loose, /**< should the loose objective value be updated? */
13443  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13444  )
13445 {
13446  assert(lp != NULL);
13447  assert(lp->looseobjvalinf >= 0);
13448  assert(lp->pseudoobjvalinf >= 0);
13449  assert(lp->glbpseudoobjvalinf >= 0);
13450 
13451  /* update the pseudo objective value */
13452  if( local )
13453  {
13454  lp->pseudoobjvalinf += deltainf;
13455  if( lp->pseudoobjvalid )
13456  {
13457  lp->pseudoobjval += deltaval;
13458 
13459  /* if the absolute value was increased, this is regarded as reliable,
13460  * otherwise, we check whether we can still trust the updated value
13461  */
13462  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13463  lp->relpseudoobjval = lp->pseudoobjval;
13464  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13465  lp->pseudoobjvalid = FALSE;
13466  }
13467 
13468  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13470  loose = TRUE;
13471  }
13472  /* update the loose objective value */
13473  if( loose )
13474  {
13475  lp->looseobjvalinf += deltainf;
13476 
13477  if( deltaval != 0.0 && lp->looseobjvalid )
13478  {
13479  lp->looseobjval += deltaval;
13480 
13481  /* if the absolute value was increased, this is regarded as reliable,
13482  * otherwise, we check whether we can still trust the updated value
13483  */
13484  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13485  lp->rellooseobjval = lp->looseobjval;
13486  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13487  lp->looseobjvalid = FALSE;
13488  }
13489  }
13490  /* update the root pseudo objective values */
13491  if( global )
13492  {
13493  lp->glbpseudoobjvalinf += deltainf;
13494  if( lp->glbpseudoobjvalid )
13495  {
13496  lp->glbpseudoobjval += deltaval;
13497 
13498  /* if the absolute value was increased, this is regarded as reliable,
13499  * otherwise, we check whether we can still trust the updated value
13500  */
13504  lp->glbpseudoobjvalid = FALSE;
13505  }
13506  }
13507 
13508  assert(lp->looseobjvalinf >= 0);
13509  assert(lp->pseudoobjvalinf >= 0);
13510  assert(lp->glbpseudoobjvalinf >= 0);
13511 }
13512 
13513 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13514  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13515  */
13516 static
13518  SCIP_LP* lp, /**< current LP data */
13519  SCIP_SET* set, /**< global SCIP settings */
13520  SCIP_VAR* var, /**< problem variable that changed */
13521  SCIP_Real oldobj, /**< old objective value of variable */
13522  SCIP_Real oldlb, /**< old objective value of variable */
13523  SCIP_Real oldub, /**< old objective value of variable */
13524  SCIP_Real newobj, /**< new objective value of variable */
13525  SCIP_Real newlb, /**< new objective value of variable */
13526  SCIP_Real newub /**< new objective value of variable */
13527  )
13528 {
13529  SCIP_INTERVAL deltaval;
13530  SCIP_INTERVAL bd;
13531  SCIP_INTERVAL obj;
13532  SCIP_INTERVAL prod;
13533  SCIP_INTERVAL psval;
13534  int deltainf;
13535 
13536  assert(lp != NULL);
13537  assert(lp->pseudoobjvalinf >= 0);
13538  assert(lp->looseobjvalinf >= 0);
13539  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13540  assert(!SCIPsetIsInfinity(set, oldlb));
13541  assert(!SCIPsetIsInfinity(set, -oldub));
13542  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13543  assert(!SCIPsetIsInfinity(set, newlb));
13544  assert(!SCIPsetIsInfinity(set, -newub));
13545  assert(var != NULL);
13546 
13548  {
13549  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13550  return SCIP_INVALIDDATA;
13551  }
13552 
13553  assert(SCIPvarGetProbindex(var) >= 0);
13554 
13555  SCIPintervalSet(&deltaval, 0.0);
13556  deltainf = 0;
13557 
13558  /* subtract old pseudo objective value */
13559  if( oldobj > 0.0 )
13560  {
13561  if( SCIPsetIsInfinity(set, -oldlb) )
13562  deltainf--;
13563  else
13564  {
13565  SCIPintervalSet(&bd, oldlb);
13566  SCIPintervalSet(&obj, oldobj);
13567  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13568  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13569  }
13570  }
13571  else if( oldobj < 0.0 )
13572  {
13573  if( SCIPsetIsInfinity(set, oldub) )
13574  deltainf--;
13575  else
13576  {
13577  SCIPintervalSet(&bd, oldub);
13578  SCIPintervalSet(&obj, oldobj);
13579  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13580  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13581  }
13582  }
13583 
13584  /* add new pseudo objective value */
13585  if( newobj > 0.0 )
13586  {
13587  if( SCIPsetIsInfinity(set, -newlb) )
13588  deltainf++;
13589  else
13590  {
13591  SCIPintervalSet(&bd, newlb);
13592  SCIPintervalSet(&obj, newobj);
13593  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13594  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13595  }
13596  }
13597  else if( newobj < 0.0 )
13598  {
13599  if( SCIPsetIsInfinity(set, newub) )
13600  deltainf++;
13601  else
13602  {
13603  SCIPintervalSet(&bd, newub);
13604  SCIPintervalSet(&obj, newobj);
13605  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13606  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13607  }
13608  }
13609 
13610  /* update the pseudo and loose objective values */
13611  SCIPintervalSet(&psval, lp->pseudoobjval);
13612  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13613  lp->pseudoobjval = SCIPintervalGetInf(psval);
13614  lp->pseudoobjvalinf += deltainf;
13616  {
13617  SCIPintervalSet(&psval, lp->looseobjval);
13618  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13619  lp->looseobjval = SCIPintervalGetInf(psval);
13620  lp->looseobjvalinf += deltainf;
13621  }
13622 
13623  assert(lp->pseudoobjvalinf >= 0);
13624  assert(lp->looseobjvalinf >= 0);
13625 
13626  return SCIP_OKAY;
13627 }
13628 
13629 /** updates current pseudo and loose objective value for a change in a variable's objective value */
13631  SCIP_LP* lp, /**< current LP data */
13632  SCIP_SET* set, /**< global SCIP settings */
13633  SCIP_VAR* var, /**< problem variable that changed */
13634  SCIP_Real oldobj, /**< old objective value of variable */
13635  SCIP_Real newobj /**< new objective value of variable */
13636  )
13637 {
13638  assert(set != NULL);
13639  assert(var != NULL);
13640 
13641  if( set->misc_exactsolve )
13642  {
13643  if( oldobj != newobj ) /*lint !e777*/
13644  {
13645  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13646  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13647  }
13648  }
13649  else
13650  {
13651  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13652  {
13653  SCIP_Real deltaval;
13654  int deltainf;
13655 
13657  assert(SCIPvarGetProbindex(var) >= 0);
13658 
13659  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13660  * domain of the variable are the same
13661  */
13662  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13663  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13664 
13665  /* compute the pseudo objective delta due the new objective coefficient */
13666  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13667 
13668  /* update the local pseudo objective value */
13669  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13670 
13671  /* compute the pseudo objective delta due the new objective coefficient */
13672  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13673 
13674  /* update the global pseudo objective value */
13675  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13676  }
13677  }
13678 
13679  return SCIP_OKAY;
13680 }
13681 
13682 
13683 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13685  SCIP_LP* lp, /**< current LP data */
13686  SCIP_SET* set, /**< global SCIP settings */
13687  SCIP_VAR* var, /**< problem variable that changed */
13688  SCIP_Real oldlb, /**< old lower bound of variable */
13689  SCIP_Real newlb /**< new lower bound of variable */
13690  )
13691 {
13692  assert(set != NULL);
13693  assert(var != NULL);
13694 
13695  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13696  {
13697  SCIP_Real deltaval;
13698  int deltainf;
13699 
13700  /* compute the pseudo objective delta due the new lower bound */
13701  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13702 
13703  /* update the root pseudo objective values */
13704  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13705  }
13706 
13707  return SCIP_OKAY;
13708 }
13709 
13710 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13712  SCIP_LP* lp, /**< current LP data */
13713  SCIP_SET* set, /**< global SCIP settings */
13714  SCIP_VAR* var, /**< problem variable that changed */
13715  SCIP_Real oldlb, /**< old lower bound of variable */
13716  SCIP_Real newlb /**< new lower bound of variable */
13717  )
13718 {
13719  assert(set != NULL);
13720  assert(var != NULL);
13721 
13722  if( set->misc_exactsolve )
13723  {
13724  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13725  {
13726  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13727  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13728  }
13729  }
13730  else
13731  {
13732  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13733  {
13734  SCIP_Real deltaval;
13735  int deltainf;
13736 
13738  assert(SCIPvarGetProbindex(var) >= 0);
13739 
13740  /* compute the pseudo objective delta due the new lower bound */
13741  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13742 
13743  /* update the pseudo and loose objective values */
13744  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13745  }
13746  }
13747 
13748  return SCIP_OKAY;
13749 }
13750 
13751 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13753  SCIP_LP* lp, /**< current LP data */
13754  SCIP_SET* set, /**< global SCIP settings */
13755  SCIP_VAR* var, /**< problem variable that changed */
13756  SCIP_Real oldub, /**< old upper bound of variable */
13757  SCIP_Real newub /**< new upper bound of variable */
13758  )
13759 {
13760  assert(set != NULL);
13761  assert(var != NULL);
13762 
13763  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13764  {
13765  SCIP_Real deltaval;
13766  int deltainf;
13767 
13768  /* compute the pseudo objective delta due the new upper bound */
13769  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13770 
13771  /* update the root pseudo objective values */
13772  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13773  }
13774 
13775  return SCIP_OKAY;
13776 }
13777 
13778 /** updates current pseudo objective value for a change in a variable's upper bound */
13780  SCIP_LP* lp, /**< current LP data */
13781  SCIP_SET* set, /**< global SCIP settings */
13782  SCIP_VAR* var, /**< problem variable that changed */
13783  SCIP_Real oldub, /**< old upper bound of variable */
13784  SCIP_Real newub /**< new upper bound of variable */
13785  )
13786 {
13787  assert(set != NULL);
13788  assert(var != NULL);
13789 
13790  if( set->misc_exactsolve )
13791  {
13792  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13793  {
13794  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13795  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13796  }
13797  }
13798  else
13799  {
13800  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13801  {
13802  SCIP_Real deltaval;
13803  int deltainf;
13804 
13806  assert(SCIPvarGetProbindex(var) >= 0);
13807 
13808  /* compute the pseudo objective delta due the new upper bound */
13809  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13810 
13811  /* update the pseudo and loose objective values */
13812  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13813  }
13814  }
13815 
13816  return SCIP_OKAY;
13817 }
13818 
13819 /** informs LP, that given variable was added to the problem */
13821  SCIP_LP* lp, /**< current LP data */
13822  SCIP_SET* set, /**< global SCIP settings */
13823  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
13824  )
13825 {
13826  assert(lp != NULL);
13828  assert(SCIPvarGetProbindex(var) >= 0);
13829 
13830  /* add the variable to the loose objective value sum */
13831  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
13832 
13833  /* update the loose variables counter */
13835  lp->nloosevars++;
13836 
13837  return SCIP_OKAY;
13838 }
13839 
13840 /** informs LP, that given variable is to be deleted from the problem */
13842  SCIP_LP* lp, /**< current LP data */
13843  SCIP_SET* set, /**< global SCIP settings */
13844  SCIP_VAR* var /**< variable that will be deleted from the problem */
13845  )
13846 {
13847  assert(lp != NULL);
13849  assert(SCIPvarGetProbindex(var) >= 0);
13850 
13851  /* subtract the variable from the loose objective value sum */
13852  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
13853 
13854  /* update the loose variables counter */
13856  {
13857  SCIPlpDecNLoosevars(lp);
13858  }
13859 
13860  return SCIP_OKAY;
13861 }
13862 
13863 /** informs LP, that given formerly loose problem variable is now a column variable */
13864 static
13866  SCIP_LP* lp, /**< current LP data */
13867  SCIP_SET* set, /**< global SCIP settings */
13868  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13869  )
13870 {
13871  SCIP_Real obj;
13872  SCIP_Real lb;
13873  SCIP_Real ub;
13874 
13875  assert(lp != NULL);
13876  assert(lp->nloosevars > 0);
13877  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13878  assert(SCIPvarGetProbindex(var) >= 0);
13879  assert(lp->looseobjvalinf >= 0);
13880 
13881  obj = SCIPvarGetObj(var);
13882 
13883  /* update loose objective value */
13884  if( SCIPsetIsPositive(set, obj) )
13885  {
13886  lb = SCIPvarGetLbLocal(var);
13887  if( SCIPsetIsInfinity(set, -lb) )
13888  lp->looseobjvalinf--;
13889  else
13890  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
13891  }
13892  else if( SCIPsetIsNegative(set, obj) )
13893  {
13894  ub = SCIPvarGetUbLocal(var);
13895  if( SCIPsetIsInfinity(set, ub) )
13896  lp->looseobjvalinf--;
13897  else
13898  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
13899  }
13900 
13901  SCIPlpDecNLoosevars(lp);
13902 
13903  assert(lp->looseobjvalinf >= 0);
13904 
13905  return SCIP_OKAY;
13906 }
13907 
13908 /** informs LP, that given formerly loose problem variable is now a column variable
13909  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13910  */
13911 static
13913  SCIP_LP* lp, /**< current LP data */
13914  SCIP_SET* set, /**< global SCIP settings */
13915  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13916  )
13917 {
13918  SCIP_INTERVAL bd;
13919  SCIP_INTERVAL ob;
13920  SCIP_INTERVAL prod;
13921  SCIP_INTERVAL loose;
13922  SCIP_Real obj;
13923  SCIP_Real lb;
13924  SCIP_Real ub;
13925 
13926  assert(lp != NULL);
13927  assert(lp->nloosevars > 0);
13928  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
13929  assert(SCIPvarGetProbindex(var) >= 0);
13930 
13931  obj = SCIPvarGetObj(var);
13932 
13933  SCIPintervalSet(&loose, lp->looseobjval);
13934 
13935  /* update loose objective value corresponding to the deletion of variable */
13936  if( obj > 0.0 )
13937  {
13938  lb = SCIPvarGetLbLocal(var);
13939  if( SCIPsetIsInfinity(set, -lb) )
13940  lp->looseobjvalinf--;
13941  else
13942  {
13943  SCIPintervalSet(&bd, lb);
13944  SCIPintervalSet(&ob, obj);
13945  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13946  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
13947  }
13948  }
13949  else if( SCIPsetIsNegative(set, obj) )
13950  {
13951  ub = SCIPvarGetUbLocal(var);
13952  if( SCIPsetIsInfinity(set, ub) )
13953  lp->looseobjvalinf--;
13954  else
13955  {
13956  SCIPintervalSet(&bd, ub);
13957  SCIPintervalSet(&ob, obj);
13958  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
13959  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
13960  }
13961  }
13962  lp->nloosevars--;
13963 
13964  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
13965  if( lp->nloosevars == 0 )
13966  {
13967  assert(lp->looseobjvalinf == 0);
13968  lp->looseobjval = 0.0;
13969  }
13970  else
13971  lp->looseobjval = SCIPintervalGetInf(loose);
13972 
13973  return SCIP_OKAY;
13974 }
13975 
13976 /** informs LP, that given formerly loose problem variable is now a column variable */
13978  SCIP_LP* lp, /**< current LP data */
13979  SCIP_SET* set, /**< global SCIP settings */
13980  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
13981  )
13982 {
13983  assert(set != NULL);
13984 
13985  if( set->misc_exactsolve )
13986  {
13987  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
13988  }
13989  else
13990  {
13991  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
13992  }
13993 
13994  return SCIP_OKAY;
13995 }
13996 
13997 /** informs LP, that given formerly column problem variable is now again a loose variable */
13998 static
14000  SCIP_LP* lp, /**< current LP data */
14001  SCIP_SET* set, /**< global SCIP settings */
14002  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14003  )
14004 {
14005  SCIP_Real obj;
14006  SCIP_Real lb;
14007  SCIP_Real ub;
14008 
14009  assert(lp != NULL);
14010  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14011  assert(SCIPvarGetProbindex(var) >= 0);
14012  assert(lp->looseobjvalinf >= 0);
14013 
14014  obj = SCIPvarGetObj(var);
14015 
14016  /* update loose objective value corresponding to the addition of variable */
14017  if( SCIPsetIsPositive(set, obj) )
14018  {
14019  lb = SCIPvarGetLbLocal(var);
14020  if( SCIPsetIsInfinity(set, -lb) )
14021  lp->looseobjvalinf++;
14022  else
14023  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14024  }
14025  else if( SCIPsetIsNegative(set, obj) )
14026  {
14027  ub = SCIPvarGetUbLocal(var);
14028  if( SCIPsetIsInfinity(set, ub) )
14029  lp->looseobjvalinf++;
14030  else
14031  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14032  }
14033  lp->nloosevars++;
14034 
14035  assert(lp->looseobjvalinf >= 0);
14036 
14037  return SCIP_OKAY;
14038 }
14039 
14040 /** informs LP, that given formerly column problem variable is now again a loose variable
14041  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14042  */
14043 static
14045  SCIP_LP* lp, /**< current LP data */
14046  SCIP_SET* set, /**< global SCIP settings */
14047  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14048  )
14049 {
14050  SCIP_INTERVAL bd;
14051  SCIP_INTERVAL ob;
14052  SCIP_INTERVAL prod;
14053  SCIP_INTERVAL loose;
14054  SCIP_Real obj;
14055  SCIP_Real lb;
14056  SCIP_Real ub;
14057 
14058  assert(lp != NULL);
14059  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14060  assert(SCIPvarGetProbindex(var) >= 0);
14061 
14062  obj = SCIPvarGetObj(var);
14063 
14064  SCIPintervalSet(&loose, lp->looseobjval);
14065 
14066  /* update loose objective value corresponding to the deletion of variable */
14067  if( obj > 0.0 )
14068  {
14069  lb = SCIPvarGetLbLocal(var);
14070  if( SCIPsetIsInfinity(set, -lb) )
14071  lp->looseobjvalinf++;
14072  else
14073  {
14074  SCIPintervalSet(&bd, lb);
14075  SCIPintervalSet(&ob, obj);
14076  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14077  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14078  }
14079  }
14080  else if( SCIPsetIsNegative(set, obj) )
14081  {
14082  ub = SCIPvarGetUbLocal(var);
14083  if( SCIPsetIsInfinity(set, ub) )
14084  lp->looseobjvalinf++;
14085  else
14086  {
14087  SCIPintervalSet(&bd, ub);
14088  SCIPintervalSet(&ob, obj);
14089  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14090  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14091  }
14092  }
14093  lp->nloosevars++;
14094 
14095  lp->looseobjval = SCIPintervalGetInf(loose);
14096 
14097  return SCIP_OKAY;
14098 }
14099 
14100 /** informs LP, that given formerly column problem variable is now again a loose variable */
14102  SCIP_LP* lp, /**< current LP data */
14103  SCIP_SET* set, /**< global SCIP settings */
14104  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14105  )
14106 {
14107  assert(set != NULL);
14108 
14109  if( set->misc_exactsolve )
14110  {
14111  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14112  }
14113  else
14114  {
14115  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14116  }
14117 
14118  return SCIP_OKAY;
14119 }
14120 
14121 /** decrease the number of loose variables by one */
14123  SCIP_LP* lp /**< current LP data */
14124  )
14125 {
14126  assert(lp != NULL);
14127  assert(lp->nloosevars > 0);
14128 
14129  lp->nloosevars--;
14130 
14131  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14132  if( lp->nloosevars == 0 )
14133  {
14134  assert(lp->looseobjvalinf == 0);
14135  lp->looseobjval = 0.0;
14136  }
14137 }
14138 
14139 /** stores the LP solution in the columns and rows */
14141  SCIP_LP* lp, /**< current LP data */
14142  SCIP_SET* set, /**< global SCIP settings */
14143  SCIP_STAT* stat, /**< problem statistics */
14144  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14145  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14146  )
14147 {
14148  SCIP_COL** lpicols;
14149  SCIP_ROW** lpirows;
14150  SCIP_Real* primsol;
14151  SCIP_Real* dualsol;
14152  SCIP_Real* activity;
14153  SCIP_Real* redcost;
14154  SCIP_Real primalbound;
14155  SCIP_Real dualbound;
14156  SCIP_Bool stillprimalfeasible;
14157  SCIP_Bool stilldualfeasible;
14158  int* cstat;
14159  int* rstat;
14160  SCIP_Longint lpcount;
14161  int nlpicols;
14162  int nlpirows;
14163  int c;
14164  int r;
14165 
14166  assert(lp != NULL);
14167  assert(lp->flushed);
14168  assert(lp->solved);
14169  assert(set != NULL);
14170  assert(stat != NULL);
14171  assert(lp->validsollp <= stat->lpcount);
14172 
14173  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14174  * corresponding flag immediately to FALSE to skip all checks
14175  */
14176  if( primalfeasible == NULL )
14177  stillprimalfeasible = FALSE;
14178  else
14179  {
14180  *primalfeasible = TRUE;
14181  stillprimalfeasible = TRUE;
14182  }
14183  if( dualfeasible == NULL )
14184  stilldualfeasible = FALSE;
14185  else
14186  {
14187  *dualfeasible = TRUE;
14188  stilldualfeasible = TRUE;
14189  }
14190 
14191  /* check if the values are already calculated */
14192  if( lp->validsollp == stat->lpcount )
14193  return SCIP_OKAY;
14194  lp->validsollp = stat->lpcount;
14195 
14196  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14197  stat->lpcount, SCIPlpGetSolstat(lp));
14198 
14199  lpicols = lp->lpicols;
14200  lpirows = lp->lpirows;
14201  nlpicols = lp->nlpicols;
14202  nlpirows = lp->nlpirows;
14203  lpcount = stat->lpcount;
14204 
14205  /* get temporary memory */
14206  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14207  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14208  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14209  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14210  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14211  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14212 
14213  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14214  if( lp->solisbasic )
14215  {
14216  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14217  }
14218  else
14219  {
14220  BMSclearMemoryArray(cstat, nlpicols);
14221  BMSclearMemoryArray(rstat, nlpirows);
14222  }
14223 
14224  primalbound = 0.0;
14225  dualbound = 0.0;
14226 
14227  /* copy primal solution and reduced costs into columns */
14228  for( c = 0; c < nlpicols; ++c )
14229  {
14230  assert( 0 <= cstat[c] && cstat[c] < 4 );
14231  lpicols[c]->primsol = primsol[c];
14232  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14233  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14234  lpicols[c]->redcost = redcost[c];
14235  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14236  lpicols[c]->validredcostlp = lpcount;
14237  if( stillprimalfeasible )
14238  {
14239  stillprimalfeasible =
14240  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || !SCIPsetIsFeasNegative(set, lpicols[c]->primsol - lpicols[c]->lb))
14241  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || !SCIPsetIsFeasPositive(set, lpicols[c]->primsol - lpicols[c]->ub));
14242  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14243  }
14244  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14245  {
14246  double compslack;
14247 
14248  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14249  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14250  * variables, which would magnify even the tiniest violation in the dual multiplier
14251  */
14252  if( stilldualfeasible )
14253  {
14254  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14255  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14256  }
14257  if( stilldualfeasible )
14258  {
14259  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14260  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14261  }
14262 
14263  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14264  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14265  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14266  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14267  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14268  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14269  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14270  dualfeasible != NULL ? stilldualfeasible : TRUE);
14271  }
14272  else
14273  {
14274  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14275  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14276  {
14277  lpicols[c]->redcost = 0.0;
14278  }
14279 
14280  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14281  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14282  * bounds, its reduced cost must be zero
14283  */
14284  if( stilldualfeasible
14285  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb)) )
14286  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14287  if( stilldualfeasible
14288  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub)) )
14289  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14290 
14291  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14292  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14293  SCIPsetIsFeasGE(set, lpicols[c]->primsol, lpicols[c]->lb),
14294  SCIPsetIsFeasLE(set, lpicols[c]->primsol, lpicols[c]->ub),
14295  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14296  !SCIPsetIsFeasGT(set, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14297  !SCIPsetIsFeasLT(set, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14298  dualfeasible != NULL ? stilldualfeasible : TRUE);
14299  }
14300 
14301  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14302  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14303  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14304  */
14305  if( stilldualfeasible )
14306  {
14307  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14308  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14309  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14310  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14311  }
14312  }
14313 
14314  /* copy dual solution and activities into rows */
14315  for( r = 0; r < nlpirows; ++r )
14316  {
14317  assert( 0 <= rstat[r] && rstat[r] < 4 );
14318  lpirows[r]->dualsol = dualsol[r];
14319  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14320  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14321  lpirows[r]->validactivitylp = lpcount;
14322  if( stillprimalfeasible )
14323  {
14324  stillprimalfeasible =
14325  (SCIPsetIsInfinity(set,-lpirows[r]->lhs) ||SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14326  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14327  }
14328  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14329  {
14330  double compslack;
14331 
14332  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14333  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14334  * variables, which would magnify even the tiniest violation in the dual multiplier
14335  */
14336  if( stilldualfeasible )
14337  {
14338  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14339  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14340  }
14341  if( stilldualfeasible )
14342  {
14343  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14344  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14345  }
14346 
14347  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14348  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14349  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14350  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14351  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14352  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14353  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14354  dualfeasible != NULL ? stilldualfeasible : TRUE);
14355  }
14356  else
14357  {
14358  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14359  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14360  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14361  */
14362  if( stilldualfeasible &&
14363  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs)) )
14364  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14365  if( stilldualfeasible &&
14366  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs)) )
14367  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14368 
14369  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14370  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14371  SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs),
14372  SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs),
14373  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14374  !SCIPsetIsFeasGT(set, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14375  !SCIPsetIsFeasLT(set, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14376  dualfeasible != NULL ? stilldualfeasible : TRUE);
14377  }
14378 
14379  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14380  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14381  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14382  */
14383  if( stilldualfeasible )
14384  {
14385  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14386  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14387  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14388  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14389  }
14390  }
14391 
14392  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14393  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14394  * infinity
14395  */
14396  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14397  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14398  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14399  {
14400  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14401  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14402  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14403  }
14404 
14405  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14406  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14407  */
14408  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14409  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14410  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14411  {
14412  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14413  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14414  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14415  }
14416 
14417  if( primalfeasible != NULL )
14418  *primalfeasible = stillprimalfeasible;
14419  if( dualfeasible != NULL )
14420  *dualfeasible = stilldualfeasible;
14421 
14422  /* free temporary memory */
14423  SCIPsetFreeBufferArray(set, &rstat);
14424  SCIPsetFreeBufferArray(set, &cstat);
14425  SCIPsetFreeBufferArray(set, &redcost);
14426  SCIPsetFreeBufferArray(set, &activity);
14427  SCIPsetFreeBufferArray(set, &dualsol);
14428  SCIPsetFreeBufferArray(set, &primsol);
14429 
14430  return SCIP_OKAY;
14431 }
14432 
14433 /** stores LP solution with infinite objective value in the columns and rows */
14435  SCIP_LP* lp, /**< current LP data */
14436  SCIP_SET* set, /**< global SCIP settings */
14437  SCIP_STAT* stat, /**< problem statistics */
14438  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14439  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14440  )
14441 {
14442  SCIP_COL** lpicols;
14443  SCIP_ROW** lpirows;
14444  SCIP_Real* primsol;
14445  SCIP_Real* activity;
14446  SCIP_Real* ray;
14447  SCIP_Real rayobjval;
14448  SCIP_Real rayscale;
14449  SCIP_Longint lpcount;
14450  SCIP_COL* col;
14451  int nlpicols;
14452  int nlpirows;
14453  int c;
14454  int r;
14455 
14456  assert(lp != NULL);
14457  assert(lp->flushed);
14458  assert(lp->solved);
14459  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14460  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14461  assert(set != NULL);
14462  assert(stat != NULL);
14463  assert(lp->validsollp <= stat->lpcount);
14464 
14465  if( primalfeasible != NULL )
14466  *primalfeasible = TRUE;
14467  if( rayfeasible != NULL )
14468  *rayfeasible = TRUE;
14469 
14470  /* check if the values are already calculated */
14471  if( lp->validsollp == stat->lpcount )
14472  return SCIP_OKAY;
14473 
14474  /* check if the LP solver is able to provide a primal unbounded ray */
14475  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14476  {
14477  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness\n");
14478  return SCIP_LPERROR;
14479  }
14480 
14481  lp->validsollp = stat->lpcount;
14482 
14483  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14484 
14485  /* get temporary memory */
14486  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14487  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14488  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14489 
14490  /* get primal unbounded ray */
14491  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14492 
14493  lpicols = lp->lpicols;
14494  lpirows = lp->lpirows;
14495  nlpicols = lp->nlpicols;
14496  nlpirows = lp->nlpirows;
14497  lpcount = stat->lpcount;
14498 
14499  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14500  rayobjval = 0.0;
14501  for( c = 0; c < nlpicols; ++c )
14502  {
14503  assert(lpicols[c] != NULL);
14504  assert(lpicols[c]->var != NULL);
14505 
14506  col = lpicols[c];
14507 
14508  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14509  if( rayfeasible != NULL )
14510  {
14511  *rayfeasible = *rayfeasible
14512  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14513  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14514  }
14515 
14516  if( ! SCIPsetIsZero(set, ray[c]) )
14517  rayobjval += ray[c] * col->obj;
14518 
14519  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14520  * heuristically try to construct a primal solution.
14521  */
14522  primsol[c] = 0.0;
14523  if( SCIPsetIsFeasZero(set, ray[c]) )
14524  {
14525  /* if the ray component is 0, we try to satisfy as many rows as possible */
14526  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14527  primsol[c] = col->lb;
14528  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14529  primsol[c] = col->ub;
14530  }
14531 
14532  /* make sure we respect the bounds */
14533  primsol[c] = MAX(primsol[c], col->lb);
14534  primsol[c] = MIN(primsol[c], col->ub);
14535 
14536  assert( SCIPsetIsFeasGE(set, primsol[c], col->lb) && SCIPsetIsFeasGE(set, primsol[c], col->lb) );
14537  }
14538 
14539  /* check feasibility of heuristic solution and compute activity */
14540  for( r = 0; r < nlpirows; ++r )
14541  {
14542  SCIP_Real act = 0.0;
14543  SCIP_ROW* row;
14544 
14545  row = lpirows[r];
14546  assert( row != NULL );
14547 
14548  for( c = 0; c < row->nlpcols; ++c )
14549  {
14550  col = row->cols[c];
14551 
14552  assert( col != NULL );
14553  assert( col->lppos >= 0 );
14554  assert( row->linkpos[c] >= 0 );
14555  assert( primsol[col->lppos] < SCIP_INVALID );
14556 
14557  act += row->vals[c] * primsol[col->lppos];
14558  }
14559 
14560  if( row->nunlinked > 0 )
14561  {
14562  for( c = row->nlpcols; c < row->len; ++c )
14563  {
14564  col = row->cols[c];
14565 
14566  assert( col != NULL );
14567 
14568  if( col->lppos >= 0 )
14569  act += row->vals[c] * primsol[col->lppos];
14570  }
14571  }
14572 
14573  /* check feasibility */
14574  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPsetIsFeasLT(set, act, row->lhs) ) ||
14575  (! SCIPsetIsInfinity(set, row->rhs) && SCIPsetIsFeasGT(set, act, row->rhs) ) )
14576  break;
14577 
14578  activity[r] = act;
14579  }
14580 
14581  /* if heuristic solution is not feasible, try to obtain solution from LPI */
14582  if( r < nlpirows )
14583  {
14584  /* get primal feasible point */
14585  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, activity, NULL) );
14586 
14587  /* determine feasibility status */
14588  if( primalfeasible != NULL )
14589  {
14590  for( c = 0; c < nlpicols; ++c )
14591  {
14592  assert( lpicols[c] != NULL );
14593  assert( lpicols[c]->var != NULL );
14594 
14595  /* check primal feasibility of (finite) primal solution; note that the comparisons ensure that the primal
14596  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined
14597  */
14598  *primalfeasible = *primalfeasible
14599  && !SCIPsetIsFeasNegative(set, primsol[c] - lpicols[c]->lb)
14600  && !SCIPsetIsFeasPositive(set, primsol[c] - lpicols[c]->ub);
14601  }
14602  }
14603  }
14604  else
14605  {
14606  if( primalfeasible != NULL )
14607  *primalfeasible = TRUE;
14608  }
14609 
14610  if( primalfeasible != NULL && !(*primalfeasible) )
14611  {
14612  /* if the finite point is already infeasible, we do not have to add the ray */
14613  rayscale = 0.0;
14614  }
14615  else if( rayfeasible != NULL && !(*rayfeasible) )
14616  {
14617  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14618  rayscale = 0.0;
14619  }
14620  else if( !SCIPsetIsNegative(set, rayobjval) )
14621  {
14622  /* due to numerical problems, the objective of the ray might be nonnegative,
14623  *
14624  * @todo How to check for negative objective value here?
14625  */
14626  if( rayfeasible != NULL )
14627  {
14628  *rayfeasible = FALSE;
14629  }
14630 
14631  rayscale = 0.0;
14632  }
14633  else
14634  {
14635  assert(rayobjval != 0.0);
14636 
14637  /* scale the ray, such that the resulting point has infinite objective value */
14638  rayscale = -2*SCIPsetInfinity(set)/rayobjval;
14639  assert(SCIPsetIsFeasPositive(set, rayscale));
14640 
14641  /* ensure that unbounded point does not violate the bounds of the variables */
14642  for( c = 0; c < nlpicols; ++c )
14643  {
14644  if( SCIPsetIsPositive(set, ray[c]) )
14645  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c])/ray[c]);
14646  else if( SCIPsetIsNegative(set, ray[c]) )
14647  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c])/ray[c]);
14648 
14649  assert(SCIPsetIsFeasPositive(set, rayscale));
14650  }
14651  }
14652 
14653  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14654 
14655  /* calculate the unbounded point: x' = x + rayscale * ray */
14656  for( c = 0; c < nlpicols; ++c )
14657  {
14658  if( SCIPsetIsZero(set, ray[c]) )
14659  lpicols[c]->primsol = primsol[c];
14660  else
14661  {
14662  SCIP_Real primsolval;
14663  primsolval = primsol[c] + rayscale * ray[c];
14664  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14665  }
14666  lpicols[c]->redcost = SCIP_INVALID;
14667  lpicols[c]->validredcostlp = -1;
14668  }
14669 
14670  /* transfer solution and check feasibility */
14671  for( r = 0; r < nlpirows; ++r )
14672  {
14673  lpirows[r]->dualsol = SCIP_INVALID;
14674  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14675  lpirows[r]->validactivitylp = lpcount;
14676 
14677  /* check for feasibility of the rows */
14678  if( primalfeasible != NULL )
14679  *primalfeasible = *primalfeasible
14680  && (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPsetIsFeasGE(set, lpirows[r]->activity, lpirows[r]->lhs))
14681  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPsetIsFeasLE(set, lpirows[r]->activity, lpirows[r]->rhs));
14682  }
14683 
14684  /* free temporary memory */
14685  SCIPsetFreeBufferArray(set, &ray);
14686  SCIPsetFreeBufferArray(set, &activity);
14687  SCIPsetFreeBufferArray(set, &primsol);
14688 
14689  return SCIP_OKAY;
14690 }
14691 
14692 /** returns primal ray proving the unboundedness of the current LP */
14694  SCIP_LP* lp, /**< current LP data */
14695  SCIP_SET* set, /**< global SCIP settings */
14696  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14697  * so the size of this array should be at least number of active variables
14698  * (all entries have to be initialized to 0 before) */
14699  )
14700 {
14701  SCIP_COL** lpicols;
14702  SCIP_Real* lpiray;
14703  SCIP_VAR* var;
14704  int nlpicols;
14705  int c;
14706 
14707  assert(lp != NULL);
14708  assert(set != NULL);
14709  assert(ray != NULL);
14710  assert(lp->flushed);
14711  assert(lp->solved);
14712  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14713  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14714 
14715  /* check if the LP solver is able to provide a primal unbounded ray */
14716  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14717  {
14718  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14719  return SCIP_LPERROR;
14720  }
14721 
14722  /* get temporary memory */
14723  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14724 
14725  SCIPsetDebugMsg(set, "getting primal ray values\n");
14726 
14727  /* get primal unbounded ray */
14728  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14729 
14730  lpicols = lp->lpicols;
14731  nlpicols = lp->nlpicols;
14732 
14733  /* store the ray values of active problem variables */
14734  for( c = 0; c < nlpicols; c++ )
14735  {
14736  assert(lpicols[c] != NULL);
14737 
14738  var = lpicols[c]->var;
14739  assert(var != NULL);
14740  assert(SCIPvarGetProbindex(var) != -1);
14741  ray[SCIPvarGetProbindex(var)] = lpiray[c];
14742  }
14743 
14744  SCIPsetFreeBufferArray(set, &lpiray);
14745 
14746  return SCIP_OKAY;
14747 }
14748 
14749 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
14750  * lp/checkfarkas = TRUE.
14751  *
14752  * @note the check will not be performed if @p valid is NULL.
14753  */
14755  SCIP_LP* lp, /**< current LP data */
14756  SCIP_SET* set, /**< global SCIP settings */
14757  SCIP_STAT* stat, /**< problem statistics */
14758  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
14759  )
14760 {
14761  SCIP_COL** lpicols;
14762  SCIP_ROW** lpirows;
14763  SCIP_Real* dualfarkas;
14764  SCIP_Real* farkascoefs;
14765  SCIP_Real farkaslhs;
14766  SCIP_Real maxactivity;
14767  SCIP_Bool checkfarkas;
14768  int nlpicols;
14769  int nlpirows;
14770  int c;
14771  int r;
14772 
14773  assert(lp != NULL);
14774  assert(lp->flushed);
14775  assert(lp->solved);
14776  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
14777  assert(set != NULL);
14778  assert(stat != NULL);
14779  assert(lp->validfarkaslp <= stat->lpcount);
14780 
14781  if( valid != NULL )
14782  *valid = TRUE;
14783 
14784  /* check if the values are already calculated */
14785  if( lp->validfarkaslp == stat->lpcount )
14786  return SCIP_OKAY;
14787  lp->validfarkaslp = stat->lpcount;
14788 
14789  farkascoefs = NULL;
14790  maxactivity = 0.0;
14791  farkaslhs = 0.0;
14792 
14793  checkfarkas = (set->lp_checkfarkas && valid != NULL);
14794 
14795  /* get temporary memory */
14796  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
14797 
14798  if( checkfarkas )
14799  {
14800  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
14801  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
14802  }
14803 
14804  /* get dual Farkas infeasibility proof */
14805  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
14806 
14807  lpicols = lp->lpicols;
14808  lpirows = lp->lpirows;
14809  nlpicols = lp->nlpicols;
14810  nlpirows = lp->nlpirows;
14811 
14812  /* store infeasibility proof in rows */
14813  SCIPsetDebugMsg(set, "LP is infeasible:\n");
14814  for( r = 0; r < nlpirows; ++r )
14815  {
14816  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
14817  lpirows[r]->dualfarkas = dualfarkas[r];
14818  lpirows[r]->dualsol = SCIP_INVALID;
14819  lpirows[r]->activity = 0.0;
14820  lpirows[r]->validactivitylp = -1L;
14821  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
14822 
14823  if( checkfarkas )
14824  {
14825  assert(farkascoefs != NULL);
14826 
14827  /* the infeasibility proof would be invalid if
14828  * (i) dualfarkas[r] > 0 and lhs = -inf
14829  * (ii) dualfarkas[r] < 0 and rhs = inf
14830  * however, due to numerics we accept slightly negative / positive values
14831  */
14832  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
14833  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
14834  {
14835  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
14836  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
14837 
14838  *valid = FALSE; /*lint !e613*/
14839 
14840  goto TERMINATE;
14841  }
14842 
14843  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
14844  * within tolerances (see above) but slighty positive / negative
14845  */
14846  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
14847  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
14848  continue;
14849 
14850  /* iterate over all columns and scale with dual solution */
14851  for( c = 0; c < lpirows[r]->len; c++ )
14852  {
14853  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
14854 
14855  if( pos == -1 )
14856  continue;
14857 
14858  assert(pos >= 0 && pos < nlpicols);
14859 
14860  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
14861  }
14862 
14863  /* the row contributes with its left-hand side to the proof */
14864  if( dualfarkas[r] > 0.0 )
14865  {
14866  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
14867 
14868  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
14869  }
14870  /* the row contributes with its right-hand side to the proof */
14871  else if( dualfarkas[r] < 0.0 )
14872  {
14873  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
14874 
14875  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
14876  }
14877  }
14878  }
14879 
14880  /* set columns as invalid */
14881  for( c = 0; c < nlpicols; ++c )
14882  {
14883  lpicols[c]->primsol = SCIP_INVALID;
14884  lpicols[c]->redcost = SCIP_INVALID;
14885  lpicols[c]->validredcostlp = -1L;
14886  lpicols[c]->validfarkaslp = -1L;
14887 
14888  if( checkfarkas )
14889  {
14890  assert(farkascoefs != NULL);
14891  assert(SCIPcolGetLPPos(lpicols[c]) == c);
14892 
14893  /* skip coefficients that are too close to zero */
14894  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
14895  continue;
14896 
14897  /* calculate the maximal activity */
14898  if( farkascoefs[c] > 0.0 )
14899  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
14900  else
14901  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
14902  }
14903  }
14904 
14905  /* check whether the farkasproof is valid
14906  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
14907  * in that case, we declare the Farkas proof to be invalid.
14908  */
14909  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
14910  {
14911  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
14912 
14913  *valid = FALSE; /*lint !e613*/
14914  }
14915 
14916  TERMINATE:
14917  /* free temporary memory */
14918  if( checkfarkas )
14919  SCIPsetFreeBufferArray(set, &farkascoefs);
14920 
14921  SCIPsetFreeBufferArray(set, &dualfarkas);
14922 
14923  return SCIP_OKAY;
14924 }
14925 
14926 /** get number of iterations used in last LP solve */
14928  SCIP_LP* lp, /**< current LP data */
14929  int* iterations /**< pointer to store the iteration count */
14930  )
14931 {
14932  assert(lp != NULL);
14933 
14934  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
14935 
14936  return SCIP_OKAY;
14937 }
14938 
14939 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
14940  * resets age of non-zero columns and sharp rows
14941  */
14943  SCIP_LP* lp, /**< current LP data */
14944  SCIP_STAT* stat /**< problem statistics */
14945  )
14946 {
14947  SCIP_COL** lpicols;
14948  SCIP_ROW** lpirows;
14949  int nlpicols;
14950  int nlpirows;
14951  int c;
14952  int r;
14953 
14954  assert(lp != NULL);
14955  assert(lp->flushed);
14956  assert(lp->solved);
14957  assert(lp->nlpicols == lp->ncols);
14958  assert(lp->nlpirows == lp->nrows);
14959  assert(stat != NULL);
14960  assert(lp->validsollp == stat->lpcount);
14961 
14962  SCIPdebugMessage("updating LP ages\n");
14963 
14964  lpicols = lp->lpicols;
14965  lpirows = lp->lpirows;
14966  nlpicols = lp->nlpicols;
14967  nlpirows = lp->nlpirows;
14968 
14969  for( c = 0; c < nlpicols; ++c )
14970  {
14971  assert(lpicols[c] == lp->cols[c]);
14972  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
14973  lpicols[c]->age++;
14974  else
14975  lpicols[c]->age = 0;
14976  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
14977  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
14978  }
14979 
14980  for( r = 0; r < nlpirows; ++r )
14981  {
14982  lpirows[r]->nlpsaftercreation++;
14983  assert(lpirows[r] == lp->rows[r]);
14984 
14985  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
14986  {
14987  lpirows[r]->age++;
14988  }
14989  else
14990  {
14991  lpirows[r]->activeinlpcounter++;
14992  lpirows[r]->age = 0;
14993  }
14994  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
14995  }
14996 
14997  return SCIP_OKAY;
14998 }
14999 
15000 /* deletes the marked columns from the LP and the LP interface */
15001 static
15003  SCIP_LP* lp, /**< current LP data */
15004  SCIP_SET* set, /**< global SCIP settings */
15005  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15006  )
15007 {
15008  SCIP_COL* col;
15009  int ncols;
15010  int c;
15011 
15012  assert(lp != NULL);
15013  assert(lp->flushed);
15014  assert(lp->ncols == lp->nlpicols);
15015  assert(!lp->diving);
15016  assert(coldstat != NULL);
15017  assert(lp->nlazycols <= lp->ncols);
15018 
15019  ncols = lp->ncols;
15020 
15021  /* delete columns in LP solver */
15022  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15023 
15024  /* update LP data respectively */
15025  for( c = 0; c < ncols; ++c )
15026  {
15027  col = lp->cols[c];
15028  assert(col != NULL);
15029  assert(col == lp->lpicols[c]);
15030  assert(coldstat[c] <= c);
15031  col->lppos = coldstat[c];
15032  if( coldstat[c] == -1 )
15033  {
15034  assert(col->removable);
15035 
15036  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15037  * function vector norms
15038  */
15039  markColDeleted(col);
15040  colUpdateDelLP(col, set);
15041  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15042  col->lpdepth = -1;
15043 
15044  lp->cols[c] = NULL;
15045  lp->lpicols[c] = NULL;
15046  lp->ncols--;
15047  lp->nremovablecols--;
15048  lp->nlpicols--;
15049  }
15050  else if( coldstat[c] < c )
15051  {
15052  assert(lp->cols[coldstat[c]] == NULL);
15053  assert(lp->lpicols[coldstat[c]] == NULL);
15054  lp->cols[coldstat[c]] = col;
15055  lp->lpicols[coldstat[c]] = col;
15056  lp->cols[coldstat[c]]->lppos = coldstat[c];
15057  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15058  lp->cols[c] = NULL;
15059  lp->lpicols[c] = NULL;
15060  }
15061  }
15062 
15063  /* remove columns which are deleted from the lazy column array */
15064  c = 0;
15065  while( c < lp->nlazycols )
15066  {
15067  if( lp->lazycols[c]->lpipos < 0 )
15068  {
15069  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15070  lp->nlazycols--;
15071  }
15072  else
15073  c++;
15074  }
15075 
15076  /* mark LP to be unsolved */
15077  if( lp->ncols < ncols )
15078  {
15079  assert(lp->ncols == lp->nlpicols);
15080  assert(lp->nchgcols == 0);
15081  assert(lp->flushed);
15082 
15083  lp->lpifirstchgcol = lp->nlpicols;
15084 
15085  /* mark the current solution invalid */
15086  lp->solved = FALSE;
15087  lp->primalfeasible = FALSE;
15088  lp->primalchecked = FALSE;
15089  lp->lpobjval = SCIP_INVALID;
15091  }
15092 
15093  checkLazyColArray(lp, set);
15094  checkLinks(lp);
15095 
15096  return SCIP_OKAY;
15097 }
15098 
15099 /* deletes the marked rows from the LP and the LP interface */
15100 static
15102  SCIP_LP* lp, /**< current LP data */
15103  BMS_BLKMEM* blkmem, /**< block memory buffers */
15104  SCIP_SET* set, /**< global SCIP settings */
15105  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15106  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15107  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15108  )
15109 {
15110  SCIP_ROW* row;
15111  int nrows;
15112  int r;
15113 
15114  assert(lp != NULL);
15115  assert(lp->flushed);
15116  assert(lp->nrows == lp->nlpirows);
15117  assert(!lp->diving);
15118  assert(rowdstat != NULL);
15119 
15120  nrows = lp->nrows;
15121 
15122  /* delete rows in LP solver */
15123  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15124 
15125  /* update LP data respectively */
15126  for( r = 0; r < nrows; ++r )
15127  {
15128  row = lp->rows[r];
15129  assert(row == lp->lpirows[r]);
15130  assert(rowdstat[r] <= r);
15131  assert(row != NULL);
15132  row->lppos = rowdstat[r];
15133  if( rowdstat[r] == -1 )
15134  {
15135  if( row->removable )
15136  lp->nremovablerows--;
15137 
15138  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15139  markRowDeleted(row);
15140  rowUpdateDelLP(row);
15141  row->lpdepth = -1;
15142 
15143  /* check, if row deletion events are tracked
15144  * if so, issue ROWDELETEDLP event
15145  */
15146  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15147  {
15148  SCIP_EVENT* event;
15149 
15150  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15151  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15152  }
15153 
15154  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15155  SCIProwUnlock(lp->rows[r]);
15156  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15157  assert(lp->lpirows[r] == NULL);
15158  assert(lp->rows[r] == NULL);
15159  lp->nrows--;
15160  lp->nlpirows--;
15161  }
15162  else if( rowdstat[r] < r )
15163  {
15164  assert(lp->rows[rowdstat[r]] == NULL);
15165  assert(lp->lpirows[rowdstat[r]] == NULL);
15166  lp->rows[rowdstat[r]] = row;
15167  lp->lpirows[rowdstat[r]] = row;
15168  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15169  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15170  lp->rows[r] = NULL;
15171  lp->lpirows[r] = NULL;
15172  }
15173  }
15174 
15175  /* mark LP to be unsolved */
15176  if( lp->nrows < nrows )
15177  {
15178  assert(lp->nrows == lp->nlpirows);
15179  assert(lp->nchgrows == 0);
15180  assert(lp->flushed);
15181 
15182  lp->lpifirstchgrow = lp->nlpirows;
15183 
15184  /* mark the current solution invalid */
15185  lp->solved = FALSE;
15186  lp->dualfeasible = FALSE;
15187  lp->dualchecked = FALSE;
15188  lp->lpobjval = SCIP_INVALID;
15190  }
15191 
15192  checkLinks(lp);
15193 
15194  return SCIP_OKAY;
15195 }
15196 
15197 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15198 static
15200  SCIP_LP* lp, /**< current LP data */
15201  SCIP_SET* set, /**< global SCIP settings */
15202  SCIP_STAT* stat, /**< problem statistics */
15203  int firstcol /**< first column to check for clean up */
15204  )
15205 {
15206  SCIP_COL** cols;
15207 #ifndef NDEBUG
15208  SCIP_COL** lpicols;
15209 #endif
15210  int* coldstat;
15211  int ncols;
15212  int ndelcols;
15213  int c;
15214 
15215  assert(lp != NULL);
15216  assert(lp->flushed);
15217  assert(lp->ncols == lp->nlpicols);
15218  assert(lp->nremovablecols <= lp->ncols);
15219  assert(!lp->diving);
15220  assert(set != NULL);
15221  assert(stat != NULL);
15222 
15223  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15224  return SCIP_OKAY;
15225 
15226  ncols = lp->ncols;
15227  cols = lp->cols;
15228 #ifndef NDEBUG
15229  lpicols = lp->lpicols;
15230 #endif
15231 
15232  /* get temporary memory */
15233  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15234 
15235  /* mark obsolete columns to be deleted */
15236  ndelcols = 0;
15237  BMSclearMemoryArray(coldstat, ncols);
15238  for( c = firstcol; c < ncols; ++c )
15239  {
15240  assert(cols[c] == lpicols[c]);
15241  assert(cols[c]->lppos == c);
15242  assert(cols[c]->lpipos == c);
15243  if( cols[c]->removable
15244  && 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 */
15245  && cols[c]->age > set->lp_colagelimit
15247  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15248  {
15249  assert(cols[c]->primsol == 0.0);
15250  coldstat[c] = 1;
15251  ndelcols++;
15252  cols[c]->obsoletenode = stat->nnodes;
15253  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15254  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15255  }
15256  }
15257 
15258  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15259 
15260  /* delete the marked columns in the LP solver interface, update the LP respectively */
15261  if( ndelcols > 0 )
15262  {
15263  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15264  }
15265  assert(lp->ncols == ncols - ndelcols);
15266 
15267  /* release temporary memory */
15268  SCIPsetFreeBufferArray(set, &coldstat);
15269 
15270  return SCIP_OKAY;
15271 }
15272 
15273 /** removes all basic rows, that are too old, beginning with the given firstrow */
15274 static
15276  SCIP_LP* lp, /**< current LP data */
15277  BMS_BLKMEM* blkmem, /**< block memory buffers */
15278  SCIP_SET* set, /**< global SCIP settings */
15279  SCIP_STAT* stat, /**< problem statistics */
15280  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15281  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15282  int firstrow /**< first row to check for clean up */
15283  )
15284 {
15285  SCIP_ROW** rows;
15286 #ifndef NDEBUG
15287  SCIP_ROW** lpirows;
15288 #endif
15289  int* rowdstat;
15290  int nrows;
15291  int ndelrows;
15292  int r;
15293 
15294  assert(lp != NULL);
15295  assert(lp->flushed);
15296  assert(lp->nrows == lp->nlpirows);
15297  assert(lp->nremovablerows <= lp->nrows);
15298  assert(!lp->diving);
15299  assert(set != NULL);
15300  assert(stat != NULL);
15301 
15302  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15303  return SCIP_OKAY;
15304 
15305  nrows = lp->nrows;
15306  rows = lp->rows;
15307 #ifndef NDEBUG
15308  lpirows = lp->lpirows;
15309 #endif
15310 
15311  /* get temporary memory */
15312  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15313 
15314  /* mark obsolete rows to be deleted */
15315  ndelrows = 0;
15316  BMSclearMemoryArray(rowdstat, nrows);
15317  for( r = firstrow; r < nrows; ++r )
15318  {
15319  assert(rows[r] == lpirows[r]);
15320  assert(rows[r]->lppos == r);
15321  assert(rows[r]->lpipos == r);
15322  if( rows[r]->removable
15323  && 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 */
15324  && rows[r]->age > set->lp_rowagelimit
15326  {
15327  rowdstat[r] = 1;
15328  ndelrows++;
15329  rows[r]->obsoletenode = stat->nnodes;
15330  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15331  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15332  }
15333  }
15334 
15335  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15336 
15337  /* delete the marked rows in the LP solver interface, update the LP respectively */
15338  if( ndelrows > 0 )
15339  {
15340  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15341  }
15342  assert(lp->nrows == nrows - ndelrows);
15343 
15344  /* release temporary memory */
15345  SCIPsetFreeBufferArray(set, &rowdstat);
15346 
15347  return SCIP_OKAY;
15348 }
15349 
15350 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15352  SCIP_LP* lp, /**< current LP data */
15353  BMS_BLKMEM* blkmem, /**< block memory buffers */
15354  SCIP_SET* set, /**< global SCIP settings */
15355  SCIP_STAT* stat, /**< problem statistics */
15356  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15357  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15358  )
15359 {
15360  assert(lp != NULL);
15361  assert(lp->solved);
15362  assert(!lp->diving);
15364  assert(set != NULL);
15365 
15366  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15367  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15368 
15369  if( lp->firstnewcol < lp->ncols )
15370  {
15371  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15372  }
15373  if( lp->firstnewrow < lp->nrows )
15374  {
15375  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15376  }
15377 
15378  return SCIP_OKAY;
15379 }
15380 
15381 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15383  SCIP_LP* lp, /**< current LP data */
15384  BMS_BLKMEM* blkmem, /**< block memory buffers */
15385  SCIP_SET* set, /**< global SCIP settings */
15386  SCIP_STAT* stat, /**< problem statistics */
15387  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15388  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15389  )
15390 {
15391  assert(lp != NULL);
15392  assert(lp->solved);
15393  assert(!lp->diving);
15395  assert(set != NULL);
15396 
15397  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15398 
15399  if( 0 < lp->ncols )
15400  {
15401  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15402  }
15403  if( 0 < lp->nrows )
15404  {
15405  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15406  }
15407 
15408  return SCIP_OKAY;
15409 }
15410 
15411 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15412 static
15414  SCIP_LP* lp, /**< current LP data */
15415  SCIP_SET* set, /**< global SCIP settings */
15416  SCIP_STAT* stat, /**< problem statistics */
15417  int firstcol /**< first column to check for clean up */
15418  )
15419 {
15420  SCIP_COL** cols;
15421  SCIP_COL** lpicols;
15422  int* coldstat;
15423  int ncols;
15424  int ndelcols;
15425  int c;
15426 
15427  assert(lp != NULL);
15428  assert(lp->flushed);
15429  assert(lp->ncols == lp->nlpicols);
15430  assert(!lp->diving);
15431  assert(stat != NULL);
15432  assert(lp->validsollp == stat->lpcount);
15433  assert(0 <= firstcol && firstcol < lp->ncols);
15434 
15435  if( lp->nremovablecols == 0 || !lp->solisbasic )
15436  return SCIP_OKAY;
15437 
15438  ncols = lp->ncols;
15439  cols = lp->cols;
15440  lpicols = lp->lpicols;
15441 
15442  /* get temporary memory */
15443  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15444 
15445  /* mark unused columns to be deleted */
15446  ndelcols = 0;
15447  BMSclearMemoryArray(coldstat, ncols);
15448  for( c = firstcol; c < ncols; ++c )
15449  {
15450  assert(cols[c] == lpicols[c]);
15451  assert(cols[c]->lppos == c);
15452  assert(cols[c]->lpipos == c);
15453  if( lpicols[c]->removable
15454  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15455  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15456  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15457  {
15458  coldstat[c] = 1;
15459  ndelcols++;
15460  }
15461  }
15462 
15463  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15464 
15465  /* delete the marked columns in the LP solver interface, update the LP respectively */
15466  if( ndelcols > 0 )
15467  {
15468  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15469  }
15470  assert(lp->ncols == ncols - ndelcols);
15471 
15472  /* release temporary memory */
15473  SCIPsetFreeBufferArray(set, &coldstat);
15474 
15475  return SCIP_OKAY;
15476 }
15477 
15478 /** removes all basic rows beginning with the given firstrow */
15479 static
15481  SCIP_LP* lp, /**< current LP data */
15482  BMS_BLKMEM* blkmem, /**< block memory buffers */
15483  SCIP_SET* set, /**< global SCIP settings */
15484  SCIP_STAT* stat, /**< problem statistics */
15485  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15486  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15487  int firstrow /**< first row to check for clean up */
15488  )
15489 {
15490 #ifndef NDEBUG
15491  SCIP_ROW** rows;
15492 #endif
15493  SCIP_ROW** lpirows;
15494  int* rowdstat;
15495  int nrows;
15496  int ndelrows;
15497  int r;
15498 
15499  assert(lp != NULL);
15500  assert(lp->flushed);
15501  assert(lp->ncols == lp->nlpicols);
15502  assert(lp->nrows == lp->nlpirows);
15503  assert(!lp->diving);
15504  assert(stat != NULL);
15505  assert(lp->validsollp == stat->lpcount);
15506  assert(0 <= firstrow && firstrow < lp->nrows);
15507 
15508  if( lp->nremovablerows == 0 || !lp->solisbasic )
15509  return SCIP_OKAY;
15510 
15511 #ifndef NDEBUG
15512  rows = lp->rows;
15513 #endif
15514  nrows = lp->nrows;
15515  lpirows = lp->lpirows;
15516 
15517  /* get temporary memory */
15518  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15519 
15520  /* mark unused rows to be deleted */
15521  ndelrows = 0;
15522  BMSclearMemoryArray(rowdstat, nrows);
15523  for( r = firstrow; r < nrows; ++r )
15524  {
15525  assert(rows[r] == lpirows[r]);
15526  assert(rows[r]->lppos == r);
15527  assert(rows[r]->lpipos == r);
15528  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15529  {
15530  rowdstat[r] = 1;
15531  ndelrows++;
15532  }
15533  }
15534 
15535  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15536 
15537  /* delete the marked rows in the LP solver interface, update the LP respectively */
15538  if( ndelrows > 0 )
15539  {
15540  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15541  }
15542  assert(lp->nrows == nrows - ndelrows);
15543 
15544  /* release temporary memory */
15545  SCIPsetFreeBufferArray(set, &rowdstat);
15546 
15547  return SCIP_OKAY;
15548 }
15549 
15550 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15552  SCIP_LP* lp, /**< current LP data */
15553  BMS_BLKMEM* blkmem, /**< block memory buffers */
15554  SCIP_SET* set, /**< global SCIP settings */
15555  SCIP_STAT* stat, /**< problem statistics */
15556  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15557  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15558  SCIP_Bool root /**< are we at the root node? */
15559  )
15560 {
15561  SCIP_Bool cleanupcols;
15562  SCIP_Bool cleanuprows;
15563 
15564  assert(lp != NULL);
15565  assert(lp->solved);
15566  assert(!lp->diving);
15568  assert(set != NULL);
15569 
15570  /* check, if we want to clean up the columns and rows */
15571  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15572  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15573 
15574  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15575  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15576 
15577  if( cleanupcols && lp->firstnewcol < lp->ncols )
15578  {
15579  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15580  }
15581  if( cleanuprows && lp->firstnewrow < lp->nrows )
15582  {
15583  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15584  }
15585 
15586  return SCIP_OKAY;
15587 }
15588 
15589 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15591  SCIP_LP* lp, /**< current LP data */
15592  BMS_BLKMEM* blkmem, /**< block memory buffers */
15593  SCIP_SET* set, /**< global SCIP settings */
15594  SCIP_STAT* stat, /**< problem statistics */
15595  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15596  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15597  SCIP_Bool root /**< are we at the root node? */
15598  )
15599 {
15600  SCIP_Bool cleanupcols;
15601  SCIP_Bool cleanuprows;
15602 
15603  assert(lp != NULL);
15604  assert(lp->solved);
15605  assert(!lp->diving);
15607  assert(set != NULL);
15608 
15609  /* check, if we want to clean up the columns and rows */
15610  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15611  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15612 
15613  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15614  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15615 
15616  if( cleanupcols && 0 < lp->ncols )
15617  {
15618  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15619  }
15620  if( cleanuprows && 0 < lp->nrows )
15621  {
15622  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15623  }
15624 
15625  return SCIP_OKAY;
15626 }
15627 
15628 /** removes all redundant rows that were added at the current node */
15630  SCIP_LP* lp, /**< current LP data */
15631  BMS_BLKMEM* blkmem, /**< block memory buffers */
15632  SCIP_SET* set, /**< global SCIP settings */
15633  SCIP_STAT* stat, /**< problem statistics */
15634  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15635  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15636  )
15637 {
15638 #ifndef NDEBUG
15639  SCIP_ROW** rows;
15640 #endif
15641  SCIP_ROW** lpirows;
15642  int* rowdstat;
15643  int nrows;
15644  int ndelrows;
15645  int r;
15646 
15647  assert(lp != NULL);
15648  assert(lp->flushed);
15649  assert(lp->ncols == lp->nlpicols);
15650  assert(lp->nrows == lp->nlpirows);
15651  assert(!lp->diving);
15652  assert(stat != NULL);
15653  assert(lp->validsollp == stat->lpcount);
15654  assert(lp->firstnewrow <= lp->nrows);
15655 
15656  if( lp->firstnewrow == lp->nrows )
15657  return SCIP_OKAY;
15658 
15659 #ifndef NDEBUG
15660  rows = lp->rows;
15661 #endif
15662  nrows = lp->nrows;
15663  lpirows = lp->lpirows;
15664 
15665  /* get temporary memory */
15666  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15667 
15668  /* mark redundant rows to be deleted (only delete basic rows!) */
15669  ndelrows = 0;
15670  BMSclearMemoryArray(rowdstat, nrows);
15671  for( r = lp->firstnewrow; r < nrows; ++r )
15672  {
15673  assert(rows[r] == lpirows[r]);
15674  assert(rows[r]->lppos == r);
15675  assert(rows[r]->lpipos == r);
15676  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15677  && SCIProwIsRedundant(lpirows[r], set, stat) )
15678  {
15679  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15680  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15681  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15682  rowdstat[r] = 1;
15683  ndelrows++;
15684  }
15685  }
15686 
15687  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15688 
15689  /* delete the marked rows in the LP solver interface, update the LP respectively */
15690  if( ndelrows > 0 )
15691  {
15692  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15693  }
15694  assert(lp->nrows == nrows - ndelrows);
15695 
15696  /* release temporary memory */
15697  SCIPsetFreeBufferArray(set, &rowdstat);
15698 
15699  return SCIP_OKAY;
15700 }
15701 
15702 /** initiates LP diving */
15704  SCIP_LP* lp, /**< current LP data */
15705  BMS_BLKMEM* blkmem, /**< block memory */
15706  SCIP_SET* set, /**< global SCIP settings */
15707  SCIP_STAT* stat /**< problem statistics */
15708  )
15709 {
15710  int c;
15711  int r;
15712 
15713  assert(lp != NULL);
15714  assert(lp->flushed || !lp->solved);
15715  assert(!lp->diving);
15716  assert(!lp->probing);
15717  assert(lp->divelpistate == NULL);
15718  assert(lp->divelpwasprimfeas);
15719  assert(lp->divelpwasdualfeas);
15720  assert(lp->validsollp <= stat->lpcount);
15721  assert(blkmem != NULL);
15722  assert(set != NULL);
15723  assert(lp->ndivechgsides == 0);
15724 
15725  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15726  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15727 
15728 #ifndef NDEBUG
15729  for( c = 0; c < lp->ncols; ++c )
15730  {
15731  assert(lp->cols[c] != NULL);
15732  assert(lp->cols[c]->var != NULL);
15733  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15734  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15735  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15736  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15737  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15738  }
15739 #endif
15740 
15741  /* save current LPI state (basis information) */
15742  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
15744  lp->divelpwasdualfeas = lp->dualfeasible;
15747 
15748  /* save current LP values dependent on the solution */
15749  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
15750  assert(lp->storedsolvals != NULL);
15751  if( !set->lp_resolverestore && lp->solved )
15752  {
15753  SCIP_Bool store = TRUE;
15754 
15755  switch ( lp->lpsolstat )
15756  {
15758  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15759  assert(lp->validsollp == stat->lpcount);
15760  break;
15762  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
15763  assert(lp->validsollp == stat->lpcount);
15764  break;
15768  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
15769  assert(lp->validsollp == stat->lpcount);
15770  break;
15772  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
15773  break;
15775  case SCIP_LPSOLSTAT_ERROR:
15776  default:
15777  store = FALSE;
15778  }
15779 
15780  if ( store )
15781  {
15782  for( c = 0; c < lp->ncols; ++c )
15783  {
15784  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
15785  }
15786  for( r = 0; r < lp->nrows; ++r )
15787  {
15789  }
15790  }
15791  }
15792 
15793  /* store LPI iteration limit */
15795 
15796  /* remember the number of domain changes */
15797  lp->divenolddomchgs = stat->domchgcount;
15798 
15799  /* store current number of rows */
15800  lp->ndivingrows = lp->nrows;
15801 
15802  /* switch to diving mode */
15803  lp->diving = TRUE;
15804 
15805  return SCIP_OKAY;
15806 }
15807 
15808 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
15810  SCIP_LP* lp, /**< current LP data */
15811  BMS_BLKMEM* blkmem, /**< block memory */
15812  SCIP_SET* set, /**< global SCIP settings */
15813  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
15814  SCIP_STAT* stat, /**< problem statistics */
15815  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15816  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15817  SCIP_PROB* prob, /**< problem data */
15818  SCIP_VAR** vars, /**< array with all active variables */
15819  int nvars /**< number of active variables */
15820  )
15821 {
15822  SCIP_VAR* var;
15823  int v;
15824 
15825  assert(lp != NULL);
15826  assert(lp->diving);
15827  assert(blkmem != NULL);
15828  assert(nvars == 0 || vars != NULL);
15829 
15830  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
15831 
15832  /* reset all columns' objective values and bounds to its original values */
15833  for( v = 0; v < nvars; ++v )
15834  {
15835  var = vars[v];
15836  assert(var != NULL);
15838  {
15839  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
15840  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
15841  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
15842  }
15843  }
15844 
15845  /* remove rows which were added in diving mode */
15846  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
15847 
15848  /* undo changes to left hand sides and right hand sides */
15849  while( lp->ndivechgsides > 0 )
15850  {
15851  SCIP_Real oldside;
15852  SCIP_SIDETYPE sidetype;
15853  SCIP_ROW* row;
15854 
15855  lp->ndivechgsides--;
15856  oldside = lp->divechgsides[lp->ndivechgsides];
15857  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
15858  row = lp->divechgrows[lp->ndivechgsides];
15859 
15860  if( sidetype == SCIP_SIDETYPE_LEFT )
15861  {
15862  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
15863  }
15864  else
15865  {
15866  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
15867  }
15868  }
15869 
15870  /* restore LPI iteration limit */
15872 
15873  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
15874  * happens
15875  */
15876  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, eventqueue, lp->divelpistate,
15878  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
15879  lp->divelpwasprimfeas = TRUE;
15880  lp->divelpwasdualfeas = TRUE;
15881  lp->divelpwasprimchecked = TRUE;
15882  lp->divelpwasdualchecked = TRUE;
15883  assert(lp->divelpistate == NULL);
15884 
15885  /* switch to standard (non-diving) mode */
15886  lp->diving = FALSE;
15887  lp->divingobjchg = FALSE;
15888 
15889  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
15890  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
15891  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
15892  * the parameter resolverestore to TRUE
15893  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
15894  */
15895  assert(lp->storedsolvals != NULL);
15896  if( lp->storedsolvals->lpissolved
15897  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
15898  {
15899  SCIP_Bool lperror;
15900 
15901  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
15902  if( lperror )
15903  {
15904  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
15905  lp->resolvelperror = TRUE;
15906  }
15911  {
15912  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
15913  "LP was not resolved to a sufficient status after diving\n");
15914  lp->resolvelperror = TRUE;
15915  }
15916  }
15917  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
15918  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
15919  * re-solve as above can lead to a different LP status
15920  */
15921  else
15922  {
15923  int c;
15924  int r;
15925 
15926  /* if there are lazy bounds, remove them from the LP */
15927  if( lp->nlazycols > 0 )
15928  {
15929  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
15930  * first resolve LP?
15931  */
15932  SCIP_CALL( updateLazyBounds(lp, set) );
15933  assert(lp->diving == lp->divinglazyapplied);
15934 
15935  /* flush changes to the LP solver */
15936  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, eventqueue) );
15937  }
15938 
15939  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
15940  SCIPstatIncrement(stat, set, lpcount);
15941 
15942  /* restore LP solution values in lp data, columns and rows */
15943  if( lp->storedsolvals->lpissolved &&
15950  )
15951  {
15952  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
15953 
15954  for( c = 0; c < lp->ncols; ++c )
15955  {
15956  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
15957  }
15958  for( r = 0; r < lp->nrows; ++r )
15959  {
15960  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
15961  }
15962  }
15963  else
15964  {
15965  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
15966  }
15967  }
15968 
15969 #ifndef NDEBUG
15970  {
15971  int c;
15972  for( c = 0; c < lp->ncols; ++c )
15973  {
15974  assert(lp->cols[c] != NULL);
15975  assert(lp->cols[c]->var != NULL);
15976  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
15977  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
15978  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
15979  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
15980  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
15981  }
15982  }
15983 #endif
15984 
15985  return SCIP_OKAY;
15986 }
15987 
15988 #define DIVESTACKGROWFACT 1.5
15989 
15990 /** records a current row side such that any change will be undone after diving */
15992  SCIP_LP* lp, /**< LP data object */
15993  SCIP_ROW* row, /**< row affected by the change */
15994  SCIP_SIDETYPE sidetype /**< side type */
15995  )
15996 {
15997  assert(lp != NULL);
15998  assert(row != NULL);
15999 
16000  if( lp->ndivechgsides == lp->divechgsidessize )
16001  {
16003  }
16004  assert(lp->ndivechgsides < lp->divechgsidessize);
16005 
16006  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16007  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16008  lp->divechgrows[lp->ndivechgsides] = row;
16009  lp->ndivechgsides++;
16010 
16011  return SCIP_OKAY;
16012 }
16013 
16014 /** informs the LP that probing mode was initiated */
16016  SCIP_LP* lp /**< current LP data */
16017  )
16018 {
16019  assert(lp != NULL);
16020  assert(!lp->probing);
16021  assert(!lp->strongbranching);
16022  assert(!lp->strongbranchprobing);
16023 
16024  lp->probing = TRUE;
16025 
16026  return SCIP_OKAY;
16027 }
16028 
16029 /** informs the LP that probing mode was finished */
16031  SCIP_LP* lp /**< current LP data */
16032  )
16033 {
16034  assert(lp != NULL);
16035  assert(lp->probing);
16036  assert(!lp->strongbranching);
16037  assert(!lp->strongbranchprobing);
16038 
16039  lp->probing = FALSE;
16040 
16041  return SCIP_OKAY;
16042 }
16043 
16044 /** informs the LP that the probing mode is now used for strongbranching */
16046  SCIP_LP* lp /**< current LP data */
16047  )
16048 {
16049  assert(lp != NULL);
16050  assert(lp->probing);
16051  assert(!lp->strongbranching);
16052  assert(!lp->strongbranchprobing);
16053 
16054  lp->strongbranchprobing = TRUE;
16055 }
16056 
16057 /** informs the LP that the probing mode is not used for strongbranching anymore */
16059  SCIP_LP* lp /**< current LP data */
16060  )
16061 {
16062  assert(lp != NULL);
16063  assert(lp->probing);
16064  assert(!lp->strongbranching);
16065  assert(lp->strongbranchprobing);
16066 
16067  lp->strongbranchprobing = FALSE;
16068 }
16069 
16070 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16071  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16072  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16073  * we have only left hand sides):
16074  * min{cx | b <= Ax, lb <= x <= ub}
16075  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16076  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16077  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16078  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16079  */
16080 static
16082  SCIP_LP* lp, /**< current LP data */
16083  SCIP_SET* set, /**< global SCIP settings */
16084  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16085  SCIP_Real* bound /**< result of interval arithmetic minimization */
16086  )
16087 {
16088  SCIP_INTERVAL* yinter;
16089  SCIP_INTERVAL b;
16090  SCIP_INTERVAL ytb;
16091  SCIP_INTERVAL prod;
16092  SCIP_INTERVAL diff;
16093  SCIP_INTERVAL x;
16094  SCIP_INTERVAL minprod;
16095  SCIP_INTERVAL a;
16096  SCIP_ROW* row;
16097  SCIP_COL* col;
16098  SCIP_Real y;
16099  SCIP_Real c;
16100  int i;
16101  int j;
16102 
16103  assert(lp != NULL);
16104  assert(lp->solved);
16105  assert(set != NULL);
16106  assert(bound != NULL);
16107 
16108  /* allocate buffer for storing y in interval arithmetic */
16109  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16110 
16111  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16112  SCIPintervalSet(&ytb, 0.0);
16113  for( j = 0; j < lp->nrows; ++j )
16114  {
16115  row = lp->rows[j];
16116  assert(row != NULL);
16117 
16118  y = (usefarkas ? row->dualfarkas : row->dualsol);
16119 
16120  if( SCIPsetIsFeasPositive(set, y) )
16121  {
16122  SCIPintervalSet(&yinter[j], y);
16123  SCIPintervalSet(&b, row->lhs - row->constant);
16124  }
16125  else if( SCIPsetIsFeasNegative(set, y) )
16126  {
16127  SCIPintervalSet(&yinter[j], y);
16128  SCIPintervalSet(&b, row->rhs - row->constant);
16129  }
16130  else
16131  {
16132  SCIPintervalSet(&yinter[j], 0.0);
16133  SCIPintervalSet(&b, 0.0);
16134  }
16135 
16136  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16137  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16138  }
16139 
16140  /* calculate min{(c^T - y^TA)x} */
16141  SCIPintervalSet(&minprod, 0.0);
16142  for( j = 0; j < lp->ncols; ++j )
16143  {
16144  col = lp->cols[j];
16145  assert(col != NULL);
16146  assert(col->nunlinked == 0);
16147 
16149 
16150  c = usefarkas ? 0.0 : col->obj;
16151  SCIPintervalSet(&diff, c);
16152 
16153  for( i = 0; i < col->nlprows; ++i )
16154  {
16155  assert(col->rows[i] != NULL);
16156  assert(col->rows[i]->lppos >= 0);
16157  assert(col->linkpos[i] >= 0);
16158  SCIPintervalSet(&a, col->vals[i]);
16159  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16160  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16161  }
16162 
16163 #ifndef NDEBUG
16164  for( i = col->nlprows; i < col->len; ++i )
16165  {
16166  assert(col->rows[i] != NULL);
16167  assert(col->rows[i]->lppos == -1);
16168  assert(col->rows[i]->dualsol == 0.0);
16169  assert(col->rows[i]->dualfarkas == 0.0);
16170  assert(col->linkpos[i] >= 0);
16171  }
16172 #endif
16173 
16174  SCIPintervalSetBounds(&x, col->lb, col->ub);
16175  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16176  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16177  }
16178 
16179  /* add y^Tb */
16180  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16181 
16182  /* free buffer for storing y in interval arithmetic */
16183  SCIPsetFreeBufferArray(set, &yinter);
16184 
16185  *bound = SCIPintervalGetInf(minprod);
16186 
16187  return SCIP_OKAY;
16188 }
16189 
16190 /** gets proven lower (dual) bound of last LP solution */
16192  SCIP_LP* lp, /**< current LP data */
16193  SCIP_SET* set, /**< global SCIP settings */
16194  SCIP_Real* bound /**< pointer to store proven dual bound */
16195  )
16196 {
16197  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16198 
16199  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16200 
16201  return SCIP_OKAY;
16202 }
16203 
16204 /** gets proven dual bound of last LP solution */
16206  SCIP_LP* lp, /**< current LP data */
16207  SCIP_SET* set, /**< global SCIP settings */
16208  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16209  )
16210 {
16211  SCIP_Real bound;
16212 
16213  assert(proved != NULL);
16214 
16215  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16216 
16217  *proved = (bound > 0.0);
16218 
16219  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16220 
16221  return SCIP_OKAY;
16222 }
16223 
16224 
16225 
16226 /** writes LP to a file */
16228  SCIP_LP* lp, /**< current LP data */
16229  const char* fname /**< file name */
16230  )
16231 {
16232  assert(lp != NULL);
16233  assert(lp->flushed);
16234  assert(fname != NULL);
16235 
16236  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16237 
16238  return SCIP_OKAY;
16239 }
16240 
16241 /** writes MIP relaxation of the current B&B node to a file */
16243  SCIP_LP* lp, /**< current LP data */
16244  SCIP_SET* set, /**< global SCIP settings */
16245  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16246  const char* fname, /**< file name */
16247  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16248  * troubles with reserved symbols? */
16249  SCIP_Bool origobj, /**< should the original objective function be used? */
16250  SCIP_OBJSENSE objsense, /**< objective sense */
16251  SCIP_Real objscale, /**< objective scaling factor */
16252  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16253  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16254  )
16255 {
16256  FILE* file;
16257  int i;
16258  int j;
16259  char rowname[SCIP_MAXSTRLEN];
16260  SCIP_Real coeff;
16261 
16262  assert(lp != NULL);
16263  assert(lp->flushed);
16264  assert(fname != NULL);
16265 
16266  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16267  file = fopen(fname, "w");
16268  if( file == NULL )
16269  {
16270  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16271  SCIPprintSysError(fname);
16272  return SCIP_FILECREATEERROR;
16273  }
16274 
16275  /* print comments */
16276  if( genericnames )
16277  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16278  else
16279  {
16280  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16281  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16282  }
16283 
16284  if( origobj && objoffset != 0.0 )
16285  {
16286  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16287  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16288  }
16289 
16290  /* print objective function */
16291  /**@note the transformed problem in SCIP is always a minimization problem */
16292  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16293  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16294  else
16295  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16296 
16297  /* print objective */
16298  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16299  j = 0;
16300  for( i = 0; i < lp->ncols; ++i )
16301  {
16302  if( lp->cols[i]->obj != 0.0 )
16303  {
16304  coeff = lp->cols[i]->obj;
16305  if( origobj )
16306  {
16307  coeff *= (SCIP_Real) objsense;
16308  coeff *= objscale;
16309  }
16310 
16311  if( genericnames )
16312  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16313  else
16314  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16315 
16316  ++j;
16317  if( j % 10 == 0 )
16318  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16319  }
16320  }
16321  /* add artificial variable 'objoffset' to transfer objective offset */
16322  if( origobj && objoffset != 0.0 )
16323  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16324 
16325  /* print constraint section */
16326  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16327  for( i = 0; i < lp->nrows; i++ )
16328  {
16329  char type = 'i';
16330 
16331  /* skip removable rows if we want to write them as lazy constraints */
16332  if ( lazyconss && 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  WRITEROW:
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 WRITEROW;
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  if ( lazyconss )
16414  {
16415  /* print lazy constraint section */
16416  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16417  for( i = 0; i < lp->nrows; i++ )
16418  {
16419  char type = 'i';
16420 
16421  /* skip non-removable rows if we want to write lazy constraints */
16422  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16423  continue;
16424 
16425  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16426  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16427  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16428  * type 'i' means: lhs and rhs are both infinite */
16429  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16430  type = 'r';
16431  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16432  type = 'l';
16433  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16434  type = 'e';
16435  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16436  type = 'b';
16437 
16438  /* print name of row */
16439  if( genericnames )
16440  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16441  else
16442  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16443 
16444  WRITELAZYROW:
16445  switch( type )
16446  {
16447  case 'r':
16448  case 'l':
16449  case 'e':
16450  if( strlen(rowname) > 0 )
16451  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16452  break;
16453  case 'i':
16454  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16455  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16456  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16457  type = 'b';
16458  /*lint -fallthrough*/
16459  case 'b':
16460  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16461  break;
16462  default:
16463  assert(type == 'B');
16464  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16465  break;
16466  }
16467 
16468  /* print coefficients and variables */
16469  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16470  {
16471  if( genericnames )
16472  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16473  else
16474  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16475 
16476  if( (j+1) % 10 == 0 )
16477  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16478  }
16479 
16480  /* print right hand side */
16481  switch( type )
16482  {
16483  case 'b':
16484  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16485  type = 'B';
16486  goto WRITELAZYROW;
16487  case 'l':
16488  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16489  break;
16490  case 'B':
16491  case 'r':
16492  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16493  break;
16494  case 'e':
16495  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16496  break;
16497  default:
16498  SCIPerrorMessage("Undefined row type!\n");
16499  return SCIP_ERROR;
16500  }
16501  }
16502  }
16503 
16504  /* print variable bounds */
16505  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16506  for( i = 0; i < lp->ncols; ++i )
16507  {
16508  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16509  {
16510  /* print lower bound as far this one is not infinity */
16511  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16512  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16513 
16514  /* print variable name */
16515  if( genericnames )
16516  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16517  else
16518  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16519 
16520  /* print upper bound as far this one is not infinity */
16521  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16522  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16523  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16524  }
16525  }
16526  if( origobj && objoffset != 0.0 )
16527  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16528 
16529  /* print integer variables */
16530  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16531  j = 0;
16532  for( i = 0; i < lp->ncols; ++i )
16533  {
16534  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16535  {
16536  /* print variable name */
16537  if( genericnames )
16538  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16539  else
16540  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16541 
16542  j++;
16543  if( j % 10 == 0 )
16544  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16545  }
16546  }
16547 
16548  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16549  fclose(file);
16550 
16551  return SCIP_OKAY;
16552 }
16553 
16554 /*
16555  * simple functions implemented as defines
16556  */
16557 
16558 /* In debug mode, the following methods are implemented as function calls to ensure
16559  * type validity.
16560  * In optimized mode, the methods are implemented as defines to improve performance.
16561  * However, we want to have them in the library anyways, so we have to undef the defines.
16562  */
16563 
16564 #undef SCIPcolGetObj
16565 #undef SCIPcolGetLb
16566 #undef SCIPcolGetUb
16567 #undef SCIPcolGetBestBound
16568 #undef SCIPcolGetPrimsol
16569 #undef SCIPcolGetMinPrimsol
16570 #undef SCIPcolGetMaxPrimsol
16571 #undef SCIPcolGetBasisStatus
16572 #undef SCIPcolGetVar
16573 #undef SCIPcolGetIndex
16574 #undef SCIPcolIsIntegral
16575 #undef SCIPcolIsRemovable
16576 #undef SCIPcolGetLPPos
16577 #undef SCIPcolGetLPDepth
16578 #undef SCIPcolIsInLP
16579 #undef SCIPcolGetNNonz
16580 #undef SCIPcolGetNLPNonz
16581 #undef SCIPcolGetRows
16582 #undef SCIPcolGetVals
16583 #undef SCIPcolGetStrongbranchNode
16584 #undef SCIPcolGetNStrongbranchs
16585 #undef SCIPboundtypeOpposite
16586 #undef SCIProwGetNNonz
16587 #undef SCIProwGetNLPNonz
16588 #undef SCIProwGetCols
16589 #undef SCIProwGetVals
16590 #undef SCIProwGetConstant
16591 #undef SCIProwGetNorm
16592 #undef SCIProwGetSumNorm
16593 #undef SCIProwGetLhs
16594 #undef SCIProwGetRhs
16595 #undef SCIProwGetDualsol
16596 #undef SCIProwGetDualfarkas
16597 #undef SCIProwGetBasisStatus
16598 #undef SCIProwGetName
16599 #undef SCIProwGetIndex
16600 #undef SCIProwGetAge
16601 #undef SCIProwGetRank
16602 #undef SCIProwIsIntegral
16603 #undef SCIProwIsLocal
16604 #undef SCIProwIsModifiable
16605 #undef SCIProwIsRemovable
16606 #undef SCIProwGetOrigintype
16607 #undef SCIProwGetOriginCons
16608 #undef SCIProwGetOriginSepa
16609 #undef SCIProwIsInGlobalCutpool
16610 #undef SCIProwGetLPPos
16611 #undef SCIProwGetLPDepth
16612 #undef SCIProwIsInLP
16613 #undef SCIProwGetActiveLPCount
16614 #undef SCIProwGetNLPsAfterCreation
16615 #undef SCIProwChgRank
16616 #undef SCIPlpGetCols
16617 #undef SCIPlpGetNCols
16618 #undef SCIPlpGetRows
16619 #undef SCIPlpGetNRows
16620 #undef SCIPlpGetNewcols
16621 #undef SCIPlpGetNNewcols
16622 #undef SCIPlpGetNewrows
16623 #undef SCIPlpGetNNewrows
16624 #undef SCIPlpGetObjNorm
16625 #undef SCIPlpGetRootObjval
16626 #undef SCIPlpGetRootColumnObjval
16627 #undef SCIPlpGetRootLooseObjval
16628 #undef SCIPlpGetLPI
16629 #undef SCIPlpSetIsRelax
16630 #undef SCIPlpIsRelax
16631 #undef SCIPlpIsSolved
16632 #undef SCIPlpIsSolBasic
16633 #undef SCIPlpDiving
16634 #undef SCIPlpDivingObjChanged
16635 #undef SCIPlpMarkDivingObjChanged
16636 #undef SCIPlpUnmarkDivingObjChanged
16637 #undef SCIPlpDivingRowsChanged
16638 
16639 /** gets objective value of column */
16641  SCIP_COL* col /**< LP column */
16642  )
16643 {
16644  assert(col != NULL);
16645 
16646  return col->obj;
16647 }
16648 
16649 /** gets lower bound of column */
16651  SCIP_COL* col /**< LP column */
16652  )
16653 {
16654  assert(col != NULL);
16655 
16656  return col->lb;
16657 }
16658 
16659 /** gets upper bound of column */
16661  SCIP_COL* col /**< LP column */
16662  )
16663 {
16664  assert(col != NULL);
16665 
16666  return col->ub;
16667 }
16668 
16669 /** gets best bound of column with respect to the objective function */
16671  SCIP_COL* col /**< LP column */
16672  )
16673 {
16674  assert(col != NULL);
16675 
16676  if( col->obj >= 0.0 )
16677  return col->lb;
16678  else
16679  return col->ub;
16680 }
16681 
16682 /** gets the primal LP solution of a column */
16684  SCIP_COL* col /**< LP column */
16685  )
16686 {
16687  assert(col != NULL);
16688 
16689  if( col->lppos >= 0 )
16690  return col->primsol;
16691  else
16692  return 0.0;
16693 }
16694 
16695 /** gets the minimal LP solution value, this column ever assumed */
16697  SCIP_COL* col /**< LP column */
16698  )
16699 {
16700  assert(col != NULL);
16701 
16702  return col->minprimsol;
16703 }
16704 
16705 /** gets the maximal LP solution value, this column ever assumed */
16707  SCIP_COL* col /**< LP column */
16708  )
16709 {
16710  assert(col != NULL);
16711 
16712  return col->maxprimsol;
16713 }
16714 
16715 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16716  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16717  */
16719  SCIP_COL* col /**< LP column */
16720  )
16721 {
16722  assert(col != NULL);
16723  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
16724 
16725  return (SCIP_BASESTAT)col->basisstatus;
16726 }
16727 
16728 /** gets variable this column represents */
16730  SCIP_COL* col /**< LP column */
16731  )
16732 {
16733  assert(col != NULL);
16734 
16735  return col->var;
16736 }
16737 
16738 /** gets unique index of col */
16740  SCIP_COL* col /**< LP col */
16741  )
16742 {
16743  assert(col != NULL);
16744 
16745  return col->index;
16746 }
16747 
16748 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
16750  SCIP_COL* col /**< LP column */
16751  )
16752 {
16753  assert(col != NULL);
16754  assert(SCIPvarIsIntegral(col->var) == col->integral);
16755 
16756  return col->integral;
16757 }
16758 
16759 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
16761  SCIP_COL* col /**< LP column */
16762  )
16763 {
16764  assert(col != NULL);
16765 
16766  return col->removable;
16767 }
16768 
16769 /** gets position of column in current LP, or -1 if it is not in LP */
16771  SCIP_COL* col /**< LP column */
16772  )
16773 {
16774  assert(col != NULL);
16775  assert((col->lppos == -1) == (col->lpdepth == -1));
16776 
16777  return col->lppos;
16778 }
16779 
16780 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
16782  SCIP_COL* col /**< LP column */
16783  )
16784 {
16785  assert(col != NULL);
16786  assert((col->lppos == -1) == (col->lpdepth == -1));
16787 
16788  return col->lpdepth;
16789 }
16790 
16791 /** returns TRUE iff column is member of current LP */
16793  SCIP_COL* col /**< LP column */
16794  )
16795 {
16796  assert(col != NULL);
16797  assert((col->lppos == -1) == (col->lpdepth == -1));
16798 
16799  return (col->lppos >= 0);
16800 }
16801 
16802 /** get number of nonzero entries in column vector */
16804  SCIP_COL* col /**< LP column */
16805  )
16806 {
16807  assert(col != NULL);
16808 
16809  return col->len;
16810 }
16811 
16812 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
16813  *
16814  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
16815  * 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
16816  */
16818  SCIP_COL* col /**< LP column */
16819  )
16820 {
16821  assert(col != NULL);
16822  assert(col->nunlinked == 0);
16823 
16824  return col->nlprows;
16825 }
16826 
16827 /** gets array with rows of nonzero entries */
16829  SCIP_COL* col /**< LP column */
16830  )
16831 {
16832  assert(col != NULL);
16833 
16834  return col->rows;
16835 }
16836 
16837 /** gets array with coefficients of nonzero entries */
16839  SCIP_COL* col /**< LP column */
16840  )
16841 {
16842  assert(col != NULL);
16843 
16844  return col->vals;
16845 }
16846 
16847 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
16848  * given column, or -1 if strong branching was never applied to the column in current run
16849  */
16851  SCIP_COL* col /**< LP column */
16852  )
16853 {
16854  assert(col != NULL);
16855 
16856  return col->sbnode;
16857 }
16858 
16859 /** gets number of times, strong branching was applied in current run on the given column */
16861  SCIP_COL* col /**< LP column */
16862  )
16863 {
16864  assert(col != NULL);
16865 
16866  return col->nsbcalls;
16867 }
16868 
16869 /** gets opposite bound type of given bound type */
16871  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
16872  )
16873 {
16874  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
16875 
16877 }
16878 
16879 /** get number of nonzero entries in row vector */
16881  SCIP_ROW* row /**< LP row */
16882  )
16883 {
16884  assert(row != NULL);
16885 
16886  return row->len;
16887 }
16888 
16889 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
16890  *
16891  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
16892  * 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
16893  */
16895  SCIP_ROW* row /**< LP row */
16896  )
16897 {
16898  assert(row != NULL);
16899  assert(row->nunlinked == 0);
16900 
16901  return row->nlpcols;
16902 }
16903 
16904 /** gets array with columns of nonzero entries */
16906  SCIP_ROW* row /**< LP row */
16907  )
16908 {
16909  assert(row != NULL);
16910 
16911  return row->cols;
16912 }
16913 
16914 /** gets array with coefficients of nonzero entries */
16916  SCIP_ROW* row /**< LP row */
16917  )
16918 {
16919  assert(row != NULL);
16920 
16921  return row->vals;
16922 }
16923 
16924 /** gets constant shift of row */
16926  SCIP_ROW* row /**< LP row */
16927  )
16928 {
16929  assert(row != NULL);
16930 
16931  return row->constant;
16932 }
16933 
16934 /** gets Euclidean norm of row vector */
16936  SCIP_ROW* row /**< LP row */
16937  )
16938 {
16939  assert(row != NULL);
16940 
16941  checkRowSqrnorm(row);
16942 
16943  return sqrt(row->sqrnorm);
16944 }
16945 
16946 /** gets sum norm of row vector (sum of absolute values of coefficients) */
16948  SCIP_ROW* row /**< LP row */
16949  )
16950 {
16951  assert(row != NULL);
16952 
16953  checkRowSumnorm(row);
16954 
16955  return row->sumnorm;
16956 }
16957 
16958 /** returns the left hand side of the row */
16960  SCIP_ROW* row /**< LP row */
16961  )
16962 {
16963  assert(row != NULL);
16964 
16965  return row->lhs;
16966 }
16967 
16968 /** returns the right hand side of the row */
16970  SCIP_ROW* row /**< LP row */
16971  )
16972 {
16973  assert(row != NULL);
16974 
16975  return row->rhs;
16976 }
16977 
16978 /** gets the dual LP solution of a row */
16980  SCIP_ROW* row /**< LP row */
16981  )
16982 {
16983  assert(row != NULL);
16984 
16985  if( row->lppos >= 0 )
16986  return row->dualsol;
16987  else
16988  return 0.0;
16989 }
16990 
16991 /** gets the dual Farkas coefficient of a row in an infeasible LP */
16993  SCIP_ROW* row /**< LP row */
16994  )
16995 {
16996  assert(row != NULL);
16997 
16998  if( row->lppos >= 0 )
16999  return row->dualfarkas;
17000  else
17001  return 0.0;
17002 }
17003 
17004 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17005  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17006  */
17008  SCIP_ROW* row /**< LP row */
17009  )
17010 {
17011  assert(row != NULL);
17012  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17013 
17014  return (SCIP_BASESTAT)row->basisstatus;
17015 }
17016 
17017 /** returns the name of the row */
17018 const char* SCIProwGetName(
17019  SCIP_ROW* row /**< LP row */
17020  )
17021 {
17022  assert(row != NULL);
17023 
17024  return row->name;
17025 }
17026 
17027 /** gets unique index of row */
17029  SCIP_ROW* row /**< LP row */
17030  )
17031 {
17032  assert(row != NULL);
17033 
17034  return row->index;
17035 }
17036 
17037 /** gets age of row */
17039  SCIP_ROW* row /**< LP row */
17040  )
17041 {
17042  assert(row != NULL);
17043 
17044  return row->age;
17045 }
17046 
17047 /** gets rank of row */
17049  SCIP_ROW* row /**< LP row */
17050  )
17051 {
17052  assert(row != NULL);
17053 
17054  return row->rank;
17055 }
17056 
17057 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17059  SCIP_ROW* row /**< LP row */
17060  )
17061 {
17062  assert(row != NULL);
17063 
17064  return row->integral;
17065 }
17066 
17067 /** returns TRUE iff row is only valid locally */
17069  SCIP_ROW* row /**< LP row */
17070  )
17071 {
17072  assert(row != NULL);
17073 
17074  return row->local;
17075 }
17076 
17077 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17079  SCIP_ROW* row /**< LP row */
17080  )
17081 {
17082  assert(row != NULL);
17083 
17084  return row->modifiable;
17085 }
17086 
17087 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17089  SCIP_ROW* row /**< LP row */
17090  )
17091 {
17092  assert(row != NULL);
17093 
17094  return row->removable;
17095 }
17096 
17097 /** returns type of origin that created the row */
17099  SCIP_ROW* row /**< LP row */
17100  )
17101 {
17102  assert( row != NULL );
17103 
17104  return (SCIP_ROWORIGINTYPE) row->origintype;
17105 }
17106 
17107 /** returns origin constraint handler that created the row (NULL if not available) */
17109  SCIP_ROW* row /**< LP row */
17110  )
17111 {
17112  assert( row != NULL );
17113 
17115  {
17116  assert( row->origin != NULL );
17117  return (SCIP_CONSHDLR*) row->origin;
17118  }
17119  return NULL;
17120 }
17121 
17122 /** returns origin separator that created the row (NULL if not available) */
17124  SCIP_ROW* row /**< LP row */
17125  )
17126 {
17127  assert( row != NULL );
17128 
17130  {
17131  assert( row->origin != NULL );
17132  return (SCIP_SEPA*) row->origin;
17133  }
17134  return NULL;
17135 }
17136 
17137 /** returns TRUE iff row is member of the global cut pool */
17139  SCIP_ROW* row /**< LP row */
17140  )
17141 {
17142  assert(row != NULL);
17143 
17144  return row->inglobalcutpool;
17145 }
17146 
17147 /** gets position of row in current LP, or -1 if it is not in LP */
17149  SCIP_ROW* row /**< LP row */
17150  )
17151 {
17152  assert(row != NULL);
17153  assert((row->lppos == -1) == (row->lpdepth == -1));
17154 
17155  return row->lppos;
17156 }
17157 
17158 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17160  SCIP_ROW* row /**< LP row */
17161  )
17162 {
17163  assert(row != NULL);
17164  assert((row->lppos == -1) == (row->lpdepth == -1));
17165 
17166  return row->lpdepth;
17167 }
17168 
17169 /** returns TRUE iff row is member of current LP */
17171  SCIP_ROW* row /**< LP row */
17172  )
17173 {
17174  assert(row != NULL);
17175  assert((row->lppos == -1) == (row->lpdepth == -1));
17176 
17177  return (row->lppos >= 0);
17178 }
17179 
17180 /** changes the rank of LP row */
17182  SCIP_ROW* row, /**< LP row */
17183  int rank /**< new value for rank */
17184  )
17185 {
17186  assert(row != NULL);
17187 
17188  row->rank = rank;
17189 }
17190 
17191 /** returns the number of times that this row has been sharp in an optimal LP solution */
17193  SCIP_ROW* row /**< row */
17194  )
17195 {
17196  assert(row != NULL);
17197 
17198  return row->activeinlpcounter;
17199 }
17200 
17201 /** returns the number of LPs since this row has been created */
17203  SCIP_ROW* row /**< row */
17204  )
17205 {
17206  assert(row != NULL);
17207 
17208  return row->nlpsaftercreation;
17209 }
17210 
17211 /** gets array with columns of the LP */
17213  SCIP_LP* lp /**< current LP data */
17214  )
17215 {
17216  assert(lp != NULL);
17217 
17218  return lp->cols;
17219 }
17220 
17221 /** gets current number of columns in LP */
17223  SCIP_LP* lp /**< current LP data */
17224  )
17225 {
17226  assert(lp != NULL);
17227 
17228  return lp->ncols;
17229 }
17230 
17231 /** gets array with rows of the LP */
17233  SCIP_LP* lp /**< current LP data */
17234  )
17235 {
17236  assert(lp != NULL);
17237 
17238  return lp->rows;
17239 }
17240 
17241 /** gets current number of rows in LP */
17243  SCIP_LP* lp /**< current LP data */
17244  )
17245 {
17246  assert(lp != NULL);
17247 
17248  return lp->nrows;
17249 }
17250 
17251 /** gets array with newly added columns after the last mark */
17253  SCIP_LP* lp /**< current LP data */
17254  )
17255 {
17256  assert(lp != NULL);
17257  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17258 
17259  return &(lp->cols[lp->firstnewcol]);
17260 }
17261 
17262 /** gets number of newly added columns after the last mark */
17264  SCIP_LP* lp /**< current LP data */
17265  )
17266 {
17267  assert(lp != NULL);
17268  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17269 
17270  return lp->ncols - lp->firstnewcol;
17271 }
17272 
17273 /** gets array with newly added rows after the last mark */
17275  SCIP_LP* lp /**< current LP data */
17276  )
17277 {
17278  assert(lp != NULL);
17279  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17280 
17281  return &(lp->rows[lp->firstnewrow]);
17282 }
17283 
17284 /** gets number of newly added rows after the last mark */
17286  SCIP_LP* lp /**< current LP data */
17287  )
17288 {
17289  assert(lp != NULL);
17290  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17291 
17292  return lp->nrows - lp->firstnewrow;
17293 }
17294 
17295 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17297  SCIP_SET* set, /**< global SCIP settings */
17298  SCIP_LP* lp /**< LP data */
17299  )
17300 {
17301  if( lp->objsqrnormunreliable )
17302  {
17303  SCIP_COL** cols;
17304  int c;
17305 
17306  cols = lp->cols;
17307  assert(cols != NULL || lp->ncols == 0);
17308 
17309  lp->objsqrnorm = 0.0;
17310 
17311  for( c = lp->ncols - 1; c >= 0; --c )
17312  {
17313  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17314  }
17315  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17316 
17317  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17318  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17319 
17321  }
17322  return;
17323 }
17324 
17325 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17326  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17328  SCIP_LP* lp /**< LP data */
17329  )
17330 {
17331  assert(lp != NULL);
17332  assert(!lp->objsqrnormunreliable);
17333  assert(lp->objsqrnorm >= 0.0);
17334 
17335  return SQRT(lp->objsqrnorm);
17336 }
17337 
17338 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17340  SCIP_LP* lp, /**< LP data */
17341  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17342  )
17343 {
17344  assert(lp != NULL);
17345 
17346  lp->rootlpisrelax = isrelax;
17347 }
17348 
17349 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17351  SCIP_LP* lp /**< LP data */
17352  )
17353 {
17354  assert(lp != NULL);
17355 
17356  return lp->rootlpisrelax;
17357 }
17358 
17359 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17361  SCIP_LP* lp /**< LP data */
17362  )
17363 {
17364  assert(lp != NULL);
17365 
17366  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17367 }
17368 
17369 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17370  * returns SCIP_INVALID if the root node LP was not (yet) solved
17371  */
17373  SCIP_LP* lp /**< LP data */
17374  )
17375 {
17376  assert(lp != NULL);
17377 
17378  return lp->rootlpobjval;
17379 }
17380 
17381 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17382  * returns SCIP_INVALID if the root node LP was not (yet) solved
17383  */
17385  SCIP_LP* lp /**< LP data */
17386  )
17387 {
17388  assert(lp != NULL);
17389 
17390  return lp->rootlooseobjval;
17391 }
17392 
17393 /** gets the LP solver interface */
17395  SCIP_LP* lp /**< current LP data */
17396  )
17397 {
17398  assert(lp != NULL);
17399 
17400  return lp->lpi;
17401 }
17402 
17403 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17405  SCIP_LP* lp, /**< LP data */
17406  SCIP_Bool relax /**< is the current lp a relaxation? */
17407  )
17408 {
17409  assert(lp != NULL);
17410 
17411  lp->isrelax = relax;
17412 }
17413 
17414 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17415  * solution value a valid local lower bound?
17416  */
17418  SCIP_LP* lp /**< LP data */
17419  )
17420 {
17421  assert(lp != NULL);
17422 
17423  return lp->isrelax;
17424 }
17425 
17426 /** returns whether the current LP is flushed and solved */
17428  SCIP_LP* lp /**< current LP data */
17429  )
17430 {
17431  assert(lp != NULL);
17432 
17433  return lp->flushed && lp->solved;
17434 }
17435 
17436 /** return whether the current LP solution passed the primal feasibility check */
17438  SCIP_LP* lp /**< current LP data */
17439  )
17440 {
17441  assert(lp != NULL);
17442 
17443  return (lp->primalchecked && lp->primalfeasible);
17444 }
17445 
17446 /** return whether the current LP solution passed the dual feasibility check */
17448  SCIP_LP* lp /**< current LP data */
17449  )
17450 {
17451  assert(lp != NULL);
17452 
17453  return (lp->dualchecked && lp->dualfeasible);
17454 }
17455 
17456 /** returns whether the current LP solution is a basic solution */
17458  SCIP_LP* lp /**< current LP data */
17459  )
17460 {
17461  assert(lp != NULL);
17462 
17463  return lp->solisbasic;
17464 }
17465 
17466 /** returns whether the LP is in diving mode */
17468  SCIP_LP* lp /**< current LP data */
17469  )
17470 {
17471  assert(lp != NULL);
17472 
17473  return lp->diving;
17474 }
17475 
17476 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17478  SCIP_LP* lp /**< current LP data */
17479  )
17480 {
17481  assert(lp != NULL);
17482 
17483  return lp->divingobjchg;
17484 }
17485 
17486 /** marks the diving LP to have a changed objective function */
17488  SCIP_LP* lp /**< current LP data */
17489  )
17490 {
17491  assert(lp != NULL);
17492  assert(lp->diving || lp->probing);
17493 
17494  lp->divingobjchg = TRUE;
17495 }
17496 
17497 /** marks the diving LP to not have a changed objective function anymore */
17499  SCIP_LP* lp /**< current LP data */
17500  )
17501 {
17502  assert(lp != NULL);
17503  assert(lp->diving || lp->probing);
17504 
17505  lp->divingobjchg = FALSE;
17506 }
17507 
17508 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17510  SCIP_LP* lp /**< current LP data */
17511  )
17512 {
17513  assert(lp != NULL);
17514  assert(lp->diving || lp->ndivechgsides == 0);
17515 
17516  return (lp->ndivechgsides > 0);
17517 }
17518 
17519 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17520 static
17522  SCIP_LPI* lpi, /**< auxiliary LP interface */
17523  SCIP_SET* set, /**< global SCIP settings */
17524  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17525  SCIP_LP* lp, /**< LP data */
17526  SCIP_PROB* prob, /**< problem data */
17527  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17528  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17529  SCIP_Real timelimit, /**< time limit for LP solver */
17530  int iterlimit, /**< iteration limit for LP solver */
17531  SCIP_Real* point, /**< array to store relative interior point on exit */
17532  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17533  )
17534 {
17535  SCIP_RETCODE retcode;
17536  SCIP_Real* primal;
17537  SCIP_Real* obj;
17538  SCIP_Real* lb;
17539  SCIP_Real* ub;
17540  SCIP_Real* matvals;
17541  SCIP_Real* matlhs;
17542  SCIP_Real* matrhs;
17543  SCIP_Real objval;
17544  SCIP_Real alpha;
17545  int* matinds;
17546  int* matbeg;
17547 #ifndef NDEBUG
17548  int nslacks;
17549 #endif
17550  int nnewcols;
17551  int ntotnonz = 0;
17552  int ntotrows = 0;
17553  int matrowidx;
17554  int matidx;
17555  int cnt;
17556  int j;
17557  int i;
17558 
17559  assert(lpi != NULL);
17560 
17562  if( retcode != SCIP_OKAY )
17563  {
17564  /* stop execution on error, since result is likely to be unsuable */
17565  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17566  return SCIP_LPERROR;
17567  }
17568 
17570  if( retcode != SCIP_OKAY )
17571  {
17572  /* stop execution on error, since result is likely to be unsuable */
17573  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17574  return SCIP_LPERROR;
17575  }
17576 
17577  /* get storage */
17578  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17579  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17580  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17581  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17582 
17583  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17584  for( j = 0; j < lp->ncols; ++j )
17585  {
17586  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17587  obj[j] = 0.0;
17588  lb[j] = -SCIPlpiInfinity(lpi);
17589  ub[j] = SCIPlpiInfinity(lpi);
17590  /* note: we could also use the original bounds - free variables seem to be faster. */
17591  }
17592 
17593  /* add artificial alpha variable */
17594  nnewcols = lp->ncols;
17595  obj[nnewcols] = 0.0;
17596  lb[nnewcols] = 1.0;
17597  ub[nnewcols] = SCIPlpiInfinity(lpi);
17598  ++nnewcols;
17599 
17600  /* create slacks for rows */
17601  for( i = 0; i < lp->nrows; ++i )
17602  {
17603  SCIP_ROW* row;
17604 
17605  row = lp->rows[i];
17606  assert( row != NULL );
17607 
17608  if( SCIProwIsModifiable(row) )
17609  continue;
17610 
17611  /* make sure row is sorted */
17612  rowSortLP(row);
17613  assert( row->lpcolssorted );
17614 
17615  /* check whether we have an equation */
17616  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17617  {
17618  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17619  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17620  ntotnonz += row->nlpcols + 1;
17621  ++ntotrows;
17622  }
17623  else
17624  {
17625  /* otherwise add slacks for each side if necessary */
17626  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17627  {
17628  if ( relaxrows )
17629  {
17630  lb[nnewcols] = 0.0;
17631  ub[nnewcols] = 1.0;
17632  obj[nnewcols++] = 1.0;
17633  ntotnonz += row->nlpcols + 2;
17634  }
17635  else
17636  ntotnonz += row->nlpcols + 1;
17637  ++ntotrows;
17638  }
17639  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17640  {
17641  if ( relaxrows )
17642  {
17643  lb[nnewcols] = 0.0;
17644  ub[nnewcols] = 1.0;
17645  obj[nnewcols++] = 1.0;
17646  ntotnonz += row->nlpcols + 2;
17647  }
17648  else
17649  ntotnonz += row->nlpcols + 1;
17650  ++ntotrows;
17651  }
17652  }
17653  }
17654 
17655  /* create slacks for objective cutoff row */
17656  if( inclobjcutoff && relaxrows )
17657  {
17658  /* add slacks for right hand side */
17659  lb[nnewcols] = 0.0;
17660  ub[nnewcols] = 1.0;
17661  obj[nnewcols++] = 1.0;
17662  ntotnonz += lp->ncols + 2;
17663  ++ntotrows;
17664  }
17665 
17666  /* create slacks for bounds */
17667  for( j = 0; j < lp->ncols; ++j )
17668  {
17669  SCIP_COL* col;
17670 
17671  col = lp->cols[j];
17672  assert( col != NULL );
17673 
17674  /* no slacks for fixed variables */
17675  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17676  {
17677  ++ntotrows;
17678  ntotnonz += 2;
17679  }
17680  else
17681  {
17682  /* add slacks for each bound if necessary */
17683  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
17684  {
17685  lb[nnewcols] = 0.0;
17686  ub[nnewcols] = 1.0;
17687  obj[nnewcols++] = 1.0;
17688  ntotnonz += 3;
17689  ++ntotrows;
17690  }
17691  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
17692  {
17693  lb[nnewcols] = 0.0;
17694  ub[nnewcols] = 1.0;
17695  obj[nnewcols++] = 1.0;
17696  ntotnonz += 3;
17697  ++ntotrows;
17698  }
17699  }
17700  }
17701 #ifndef NDEBUG
17702  nslacks = nnewcols - lp->ncols - 1;
17703  assert( nslacks >= 0 );
17704  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
17705 #endif
17706 
17707  /* add columns */
17708  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
17709 
17710  /* free storage */
17711  SCIPsetFreeBufferArray(set, &obj);
17712  SCIPsetFreeBufferArray(set, &ub);
17713  SCIPsetFreeBufferArray(set, &lb);
17714 
17715  /* prepare storage for rows */
17716  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
17717  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
17718  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
17719  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
17720  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
17721 
17722  /* create rows arising from original rows */
17723  cnt = 0;
17724  matrowidx = 0;
17725  matidx = 0;
17726  for( i = 0; i < lp->nrows; ++i )
17727  {
17728  SCIP_ROW* row;
17729  SCIP_COL** rowcols;
17730  SCIP_Real* rowvals;
17731  SCIP_Real lhs;
17732  SCIP_Real rhs;
17733  int nnonz;
17734 
17735  row = lp->rows[i];
17736  assert( row != NULL );
17737 
17738  if( SCIProwIsModifiable(row) )
17739  continue;
17740  assert( row->lpcolssorted );
17741 
17742  /* get row data */
17743  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
17744  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
17745  nnonz = row->nlpcols;
17746  assert( nnonz <= lp->ncols );
17747  rowcols = row->cols;
17748  rowvals = row->vals;
17749 
17750  /* if we have an equation */
17751  if( SCIPsetIsEQ(set, lhs, rhs) )
17752  {
17753  /* set up indices */
17754  matbeg[matrowidx] = matidx;
17755  for( j = 0; j < nnonz; ++j )
17756  {
17757  assert( rowcols[j] != NULL );
17758  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17759  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17760  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17761  matinds[matidx] = rowcols[j]->lppos;
17762  matvals[matidx++] = rowvals[j];
17763  assert( matidx <= ntotnonz );
17764  }
17765 
17766  /* add artificial variable */
17767  if ( ! SCIPsetIsZero(set, rhs) )
17768  {
17769  matinds[matidx] = lp->ncols;
17770  matvals[matidx++] = -rhs;
17771  assert( matidx <= ntotnonz );
17772  }
17773 
17774  matlhs[matrowidx] = 0.0;
17775  matrhs[matrowidx++] = 0.0;
17776  assert( matrowidx <= ntotrows );
17777  }
17778  else
17779  {
17780  SCIP_Real abslhs = REALABS(lhs);
17781  SCIP_Real absrhs = REALABS(rhs);
17782 
17783  assert(!SCIPsetIsEQ(set, lhs, rhs));
17784 
17785  /* treat lhs */
17786  if( !SCIPsetIsInfinity(set, abslhs) )
17787  {
17788  /* set up indices */
17789  matbeg[matrowidx] = matidx;
17790  for( j = 0; j < nnonz; ++j )
17791  {
17792  assert( rowcols[j] != NULL );
17793  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17794  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17795  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17796  matinds[matidx] = rowcols[j]->lppos;
17797  matvals[matidx++] = rowvals[j];
17798  assert( matidx <= ntotnonz );
17799  }
17800 
17801  /* add artificial variable */
17802  if ( ! SCIPsetIsZero(set, lhs) )
17803  {
17804  matinds[matidx] = lp->ncols;
17805  matvals[matidx++] = -lhs;
17806  assert( matidx <= ntotnonz );
17807  }
17808 
17809  if( relaxrows )
17810  {
17811  /* add slack variable */
17812  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
17813  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17814  assert( matidx <= ntotnonz );
17815  ++cnt;
17816  }
17817 
17818  matlhs[matrowidx] = 0.0;
17819  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
17820  assert( matrowidx <= ntotrows );
17821  }
17822 
17823  /* treat rhs */
17824  if( !SCIPsetIsInfinity(set, absrhs) )
17825  {
17826  /* set up indices */
17827  matbeg[matrowidx] = matidx;
17828  for( j = 0; j < nnonz; ++j )
17829  {
17830  assert( rowcols[j] != NULL );
17831  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
17832  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
17833  assert( ! SCIPsetIsZero(set, rowvals[j]) );
17834  matinds[matidx] = rowcols[j]->lppos;
17835  matvals[matidx++] = rowvals[j];
17836  assert( matidx <= ntotnonz );
17837  }
17838 
17839  /* add artificial variable */
17840  if ( ! SCIPsetIsZero(set, rhs) )
17841  {
17842  matinds[matidx] = lp->ncols;
17843  matvals[matidx++] = -rhs;
17844  assert( matidx <= ntotnonz );
17845  }
17846 
17847  if( relaxrows )
17848  {
17849  /* add slack variable */
17850  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
17851  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
17852  ++cnt;
17853  }
17854 
17855  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
17856  matrhs[matrowidx++] = 0.0;
17857  assert( matrowidx <= ntotrows );
17858  }
17859  }
17860  }
17861 
17862  /* create row arising from objective cutoff */
17863  if( inclobjcutoff )
17864  {
17865  SCIP_Real rhs;
17866 
17867  /* get row data */
17868  assert(lp->looseobjvalinf == 0);
17869  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
17870 
17871  /* set up indices and coefficients */
17872  matbeg[matrowidx] = matidx;
17873  for( j = 0; j < lp->ncols; ++j )
17874  {
17875  assert( lp->cols[j] != NULL );
17876  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
17877  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
17878 
17879  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
17880  {
17881  matinds[matidx] = lp->cols[j]->lppos;
17882  matvals[matidx++] = lp->cols[j]->obj;
17883  assert( matidx <= ntotnonz );
17884  }
17885  }
17886 
17887  /* treat rhs */
17888 
17889  /* add artificial variable */
17890  if ( ! SCIPsetIsZero(set, rhs) )
17891  {
17892  matinds[matidx] = lp->ncols;
17893  matvals[matidx++] = -rhs;
17894  assert( matidx <= ntotnonz );
17895  }
17896 
17897  if( relaxrows )
17898  {
17899  SCIP_Real absrhs = REALABS(rhs);
17900 
17901  /* add slack variable */
17902  matvals[matidx] = MAX(1.0, absrhs);
17903  matinds[matidx++] = lp->ncols + 1 + cnt;
17904  assert( matidx <= ntotnonz );
17905  ++cnt;
17906  }
17907  matlhs[matrowidx] = -SCIPsetInfinity(set);
17908  matrhs[matrowidx++] = 0.0;
17909  assert( matrowidx <= ntotrows );
17910  }
17911 
17912  /* create rows arising from bounds */
17913  for( j = 0; j < lp->ncols; ++j )
17914  {
17915  SCIP_COL* col;
17916  SCIP_Real abscollb;
17917  SCIP_Real abscolub;
17918 
17919  col = lp->cols[j];
17920  assert( col != NULL );
17921  assert( col->lppos == j );
17922 
17923  /* fixed variable */
17924  if( SCIPsetIsEQ(set, col->lb, col->ub) )
17925  {
17926  /* set up index of column */
17927  matbeg[matrowidx] = matidx;
17928 
17929  matinds[matidx] = j;
17930  matvals[matidx++] = 1.0;
17931  assert( matidx <= ntotnonz );
17932 
17933  /* add artificial variable */
17934  if ( ! SCIPsetIsZero(set, col->ub) )
17935  {
17936  matinds[matidx] = lp->ncols;
17937  matvals[matidx++] = -col->ub;
17938  assert( matidx <= ntotnonz );
17939  }
17940 
17941  matlhs[matrowidx] = 0.0;
17942  matrhs[matrowidx++] = 0.0;
17943  assert( matrowidx <= ntotrows );
17944 
17945  continue;
17946  }
17947 
17948  abscollb = REALABS(col->lb);
17949  abscolub = REALABS(col->ub);
17950 
17951  /* lower bound */
17952  if ( ! SCIPsetIsInfinity(set, abscollb) )
17953  {
17954  /* set up index of column */
17955  matbeg[matrowidx] = matidx;
17956 
17957  matinds[matidx] = j;
17958  matvals[matidx++] = 1.0;
17959  assert( matidx <= ntotnonz );
17960 
17961  /* add artificial variable */
17962  if ( ! SCIPsetIsZero(set, col->lb) )
17963  {
17964  matinds[matidx] = lp->ncols;
17965  matvals[matidx++] = -col->lb;
17966  assert( matidx <= ntotnonz );
17967  }
17968 
17969  /* add slack variable */
17970  matvals[matidx] = -MAX(1.0, abscollb);
17971  matinds[matidx++] = lp->ncols + 1 + cnt;
17972  assert( matidx <= ntotnonz );
17973  ++cnt;
17974 
17975  matlhs[matrowidx] = 0.0;
17976  matrhs[matrowidx++] = SCIPsetInfinity(set);
17977  assert( matrowidx <= ntotrows );
17978  }
17979 
17980  /* upper bound */
17981  if ( ! SCIPsetIsInfinity(set, abscolub) )
17982  {
17983  /* set up index of column */
17984  matbeg[matrowidx] = matidx;
17985 
17986  matinds[matidx] = j;
17987  matvals[matidx++] = 1.0;
17988  assert( matidx <= ntotnonz );
17989 
17990  /* add artificial variable */
17991  if ( ! SCIPsetIsZero(set, col->ub) )
17992  {
17993  matinds[matidx] = lp->ncols;
17994  matvals[matidx++] = -col->ub;
17995  assert( matidx <= ntotnonz );
17996  }
17997 
17998  /* add slack variable */
17999  matvals[matidx] = MAX(1.0, abscolub);
18000  matinds[matidx++] = lp->ncols + 1 + cnt;
18001  assert( matidx <= ntotnonz );
18002  ++cnt;
18003 
18004  matlhs[matrowidx] = -SCIPsetInfinity(set);
18005  matrhs[matrowidx++] = 0.0;
18006  assert( matrowidx <= ntotrows );
18007  }
18008  }
18009  assert( cnt == nslacks );
18010  assert( matrowidx == ntotrows );
18011 
18012  /* add rows */
18013  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18014 
18015  SCIPsetFreeBufferArray(set, &matrhs);
18016  SCIPsetFreeBufferArray(set, &matlhs);
18017  SCIPsetFreeBufferArray(set, &matbeg);
18018  SCIPsetFreeBufferArray(set, &matvals);
18019  SCIPsetFreeBufferArray(set, &matinds);
18020 
18021 #ifdef SCIP_OUTPUT
18022  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18023 #endif
18024 
18025 #ifndef NDEBUG
18026  {
18027  int ncols;
18028  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18029  assert( ncols == nnewcols );
18030  }
18031 #endif
18032 
18033  /* set time limit */
18034  if( SCIPsetIsInfinity(set, timelimit) )
18035  timelimit = SCIPlpiInfinity(lpi);
18036  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18037 
18038  /* check, if parameter is unknown */
18039  if( retcode == SCIP_PARAMETERUNKNOWN )
18040  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18041  else if ( retcode != SCIP_OKAY )
18042  return retcode;
18043 
18044  /* set iteration limit */
18045  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18046 
18047  /* check, if parameter is unknown */
18048  if( retcode == SCIP_PARAMETERUNKNOWN )
18049  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18050  else if ( retcode != SCIP_OKAY )
18051  return retcode;
18052 
18053  /* solve and store point */
18054  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18055  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18056 
18057 #ifndef NDEBUG
18058  if ( SCIPlpiIsIterlimExc(lpi) )
18059  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18060  if ( SCIPlpiIsTimelimExc(lpi) )
18061  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18062 #endif
18063 
18064  if( SCIPlpiIsOptimal(lpi) )
18065  {
18066  /* get primal solution */
18067  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18068  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18069  alpha = primal[lp->ncols];
18070  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18071 
18072  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18073 
18074  /* construct relative interior point */
18075  for( j = 0; j < lp->ncols; ++j )
18076  point[j] = primal[j]/alpha;
18077 
18078 #ifdef SCIP_DEBUG
18079  /* check whether the point is a relative interior point */
18080  cnt = 0;
18081  if( relaxrows )
18082  {
18083  for( i = 0; i < lp->nrows; ++i )
18084  {
18085  SCIP_ROW* row;
18086  SCIP_COL** rowcols;
18087  SCIP_Real* rowvals;
18088  SCIP_Real lhs;
18089  SCIP_Real rhs;
18090  SCIP_Real sum;
18091  int nnonz;
18092 
18093  row = lp->rows[i];
18094  assert( row != NULL );
18095 
18096  /* get row data */
18097  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18098  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18099  nnonz = row->nlpcols;
18100  assert( nnonz <= lp->ncols );
18101  rowcols = row->cols;
18102  rowvals = row->vals;
18103 
18104  sum = 0.0;
18105  for( j = 0; j < nnonz; ++j )
18106  sum += rowvals[j] * primal[rowcols[j]->lppos];
18107  sum /= alpha;
18108 
18109  /* if we have an equation */
18110  if( SCIPsetIsEQ(set, lhs, rhs) )
18111  {
18112  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18113  }
18114  else
18115  {
18116  /* treat lhs */
18117  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18118  {
18119  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18120  ++cnt;
18121  }
18122  /* treat rhs */
18123  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18124  {
18125  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18126  ++cnt;
18127  }
18128  }
18129  }
18130  if( inclobjcutoff )
18131  {
18132  SCIP_Real sum;
18133 #ifndef NDEBUG
18134  SCIP_Real rhs;
18135 
18136  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18137 #endif
18138  sum = 0.0;
18139  for( j = 0; j < lp->ncols; ++j )
18140  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18141  sum /= alpha;
18142 
18143  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18144  ++cnt;
18145  }
18146  }
18147  /* check bounds */
18148  for( j = 0; j < lp->ncols; ++j )
18149  {
18150  SCIP_COL* col;
18151 #ifndef NDEBUG
18152  SCIP_Real val;
18153 #endif
18154 
18155  col = lp->cols[j];
18156  assert( col != NULL );
18157 #ifndef NDEBUG
18158  val = primal[col->lppos] / alpha;
18159 #endif
18160  /* if the variable is not fixed */
18161  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18162  {
18163  /* treat lb */
18164  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18165  {
18166  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18167  ++cnt;
18168  }
18169  /* treat rhs */
18170  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18171  {
18172  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18173  ++cnt;
18174  }
18175  }
18176  }
18177 #endif
18178 
18179  /* free */
18180  SCIPsetFreeBufferArray(set, &primal);
18181 
18182  *success = TRUE;
18183  }
18184 
18185  return SCIP_OKAY;
18186 }
18187 
18188 /** compute relative interior point
18189  *
18190  * We use the approach of@par
18191  * R. Freund, R. Roundy, M. J. Todd@par
18192  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18193  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18194  *
18195  * to compute a relative interior point for the current LP.
18196  *
18197  * Assume the original LP looks as follows:
18198  * \f[
18199  * \begin{array}{rrl}
18200  * \min & c^T x &\\
18201  * & A x & \geq a\\
18202  * & B x & \leq b\\
18203  * & D x & = d.
18204  * \end{array}
18205  * \f]
18206  * Note that bounds should be included in the system.
18207  *
18208  * To find an interior point the following LP does the job:
18209  * \f[
18210  * \begin{array}{rrl}
18211  * \max & 1^T y &\\
18212  * & A x - y - \alpha a & \geq 0\\
18213  * & B x + y - \alpha b & \leq 0\\
18214  * & D x - \alpha d & = 0\\
18215  * & 0 \leq y & \leq 1\\
18216  * & \alpha & \geq 1.
18217  * \end{array}
18218  * \f]
18219  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18220  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18221  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18222  */
18224  SCIP_SET* set, /**< global SCIP settings */
18225  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18226  SCIP_LP* lp, /**< LP data */
18227  SCIP_PROB* prob, /**< problem data */
18228  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18229  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18230  SCIP_Real timelimit, /**< time limit for LP solver */
18231  int iterlimit, /**< iteration limit for LP solver */
18232  SCIP_Real* point, /**< array to store relative interior point on exit */
18233  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18234  )
18235 {
18236  SCIP_LPI* lpi;
18237  SCIP_RETCODE retcode;
18238 
18239  assert(set != NULL);
18240  assert(lp != NULL);
18241  assert(point != NULL);
18242  assert(success != NULL);
18243 
18244  *success = FALSE;
18245 
18246  /* check time and iteration limits */
18247  if ( timelimit <= 0.0 || iterlimit <= 0 )
18248  return SCIP_OKAY;
18249 
18250  /* exit if there are no columns */
18251  assert(lp->nrows >= 0);
18252  assert(lp->ncols >= 0);
18253  if( lp->ncols == 0 )
18254  return SCIP_OKAY;
18255 
18256  /* disable objective cutoff if we have none */
18257  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18258  inclobjcutoff = FALSE;
18259 
18260  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18261 
18262  /* if there are no rows, we return the zero point */
18263  if( lp->nrows == 0 && !inclobjcutoff )
18264  {
18265  /* create zero point */
18266  BMSclearMemoryArray(point, lp->ncols);
18267  *success = TRUE;
18268 
18269  return SCIP_OKAY;
18270  }
18271 
18272  /* create auxiliary LP */
18273  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18274 
18275  /* catch return code and ensure that lpi is freed, anyway */
18276  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18277 
18278  SCIP_CALL( SCIPlpiFree(&lpi) );
18279 
18280  /* return error, unless we obtained an LP error */
18281  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18282  {
18283  SCIP_CALL( retcode );
18284  }
18285 
18286  return SCIP_OKAY;
18287 }
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:17088
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:17521
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:16191
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:12983
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:456
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:13517
#define NULL
Definition: def.h:246
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:17509
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:17285
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:13820
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:17467
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:137
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:17404
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:17038
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1384
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17123
#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:16058
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:15413
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:18223
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:17492
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:15382
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:17339
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:17344
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:267
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:16718
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:17296
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:13394
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:16838
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:16850
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:16880
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
SCIP_Real objsumnorm
Definition: struct_lp.h:281
#define SQR(x)
Definition: def.h:198
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:17400
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:15002
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:14927
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:11807
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17018
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:16910
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:17192
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13062
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:14754
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13711
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13999
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:16894
#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:9881
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:13684
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16959
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:72
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:16227
#define EPSEQ(x, y, eps)
Definition: def.h:182
#define EPSISINT(x, eps)
Definition: def.h:194
int pseudoobjvalinf
Definition: struct_lp.h:325
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17457
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:13752
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:16749
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:16660
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:10561
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:17007
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16640
SCIP_Bool dualchecked
Definition: struct_lp.h:356
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10253
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:16205
#define TRUE
Definition: def.h:71
#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:17372
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16045
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:454
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:17037
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:15988
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:16781
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:15351
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:112
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:15809
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:12215
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:12133
SCIP_Real pseudoobjval
Definition: struct_lp.h:269
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17232
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:13435
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13094
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:15590
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:14942
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:17098
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:143
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:134
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16030
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:16979
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:12895
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:13912
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:17350
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:15991
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
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
#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:17222
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12106
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11373
#define SCIP_DEFAULT_EPSILON
Definition: def.h:163
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:17170
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:8963
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4181
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:17360
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:17354
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:15551
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:17263
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13779
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:16947
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:450
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:14044
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:15703
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16683
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:16015
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:16242
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:17437
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16870
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:14122
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17447
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:16828
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:237
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9525
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17212
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17068
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:15480
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:16650
#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:16730
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:17058
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:14434
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:17108
SCIP_Bool isrelax
Definition: struct_lp.h:359
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17327
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:181
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:358
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:17482
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:17242
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:17487
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:16969
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:17394
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12911
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:17078
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:16905
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:11838
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:16739
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:453
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:178
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:16915
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:17384
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:69
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12994
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:442
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:10162
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15101
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:16670
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:17274
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:17731
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:455
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17477
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3694
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3308
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:216
SCIP_Bool updateintegrality
Definition: struct_lp.h:350
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17202
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:16760
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:17192
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:16992
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17058
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:13405
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:15629
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:12195
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:17048
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:13222
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:150
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16696
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:158
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:13353
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:12950
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16081
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:13124
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:149
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:16925
#define SQRT(x)
Definition: def.h:199
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:15199
SCIP_VAR ** b
Definition: circlepacking.c:56
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:12970
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:16803
#define MAX(x, y)
Definition: def.h:215
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
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3295
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:16729
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:17181
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:13630
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6318
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:135
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:15275
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:164
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:13865
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:16860
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16849
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
struct SCIP_LPi SCIP_LPI
Definition: type_lpi.h:96
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17148
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:157
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:17427
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:3905
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:108
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14101
#define SCIP_INVALID
Definition: def.h:177
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:116
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:17417
SCIP_CLOCK * duallptime
Definition: struct_stat.h:149
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:142
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17456
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:17159
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14693
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:17028
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:17410
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:440
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:119
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:13977
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:13164
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:426
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:13841
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:337
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:17252
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16706
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:14140
#define SCIP_ALLOC(x)
Definition: def.h:369
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:12939
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6302
#define SCIPABORT()
Definition: def.h:330
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:16817
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:16770
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16921
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:17202
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:8690
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:16935
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17498
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:446
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:16792
unsigned int local
Definition: struct_lp.h:249
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
#define ABS(x)
Definition: def.h:211
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:12017
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:4060
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:17138
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:752