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