Scippy

SCIP

Solving Constraint Integer Programs

lp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lp.c
17  * @ingroup OTHER_CFILES
18  * @brief LP management methods and data structures
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Marc Pfetsch
22  * @author Kati Wolter
23  * @author Gerald Gamrath
24  *
25  * In LP management, we have to differ between the current LP and the SCIP_LP
26  * stored in the LP solver. All LP methods affect the current LP only.
27  * Before solving the current LP with the LP solver or setting an LP state,
28  * the LP solvers data has to be updated to the current LP with a call to
29  * lpFlush().
30  */
31 
32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33 
34 
35 #include "lpi/lpi.h"
36 #include "scip/clock.h"
37 #include "scip/cons.h"
38 #include "scip/event.h"
39 #include "scip/intervalarith.h"
40 #include "scip/lp.h"
41 #include "scip/misc.h"
42 #include "scip/prob.h"
43 #include "scip/pub_lp.h"
44 #include "scip/pub_message.h"
45 #include "scip/pub_misc.h"
46 #include "scip/pub_misc_sort.h"
47 #include "scip/pub_var.h"
48 #include "scip/set.h"
49 #include "scip/sol.h"
50 #include "scip/solve.h"
51 #include "scip/stat.h"
52 #include "scip/struct_event.h"
53 #include "scip/struct_lp.h"
54 #include "scip/struct_prob.h"
55 #include "scip/struct_set.h"
56 #include "scip/struct_stat.h"
57 #include "scip/struct_var.h"
58 #include "scip/var.h"
59 #include <string.h>
60 
61 
62 /* activate this to use the row activities as given by the LPI instead of recalculating
63  * using the LP solver activity is potentially faster, but may not be consistent with the SCIP_ROW calculations
64  * see also #2594 for more details on possible trouble
65  */
66 /* #define SCIP_USE_LPSOLVER_ACTIVITY */
67 
68 /*
69  * debug messages
70  */
71 
72 #ifdef SCIP_DEBUG
73 /** method is to print in row in case SCIP_DEBUG is defined */
74 static
75 void debugRowPrint(
76  SCIP_SET* set, /**< global SCIP settings */
77  SCIP_ROW* row /**< LP row */
78  )
79 {
80  int i;
81 
82  assert(row != NULL);
83 
84  /* print row name */
85  if( row->name != NULL && row->name[0] != '\0' )
86  {
87  SCIPsetDebugMsgPrint(set, "%s: ", row->name);
88  }
89 
90  /* print left hand side */
91  SCIPsetDebugMsgPrint(set, "%.15g <= ", row->lhs);
92 
93  /* print coefficients */
94  if( row->len == 0 )
95  {
96  SCIPsetDebugMsgPrint(set, "0 ");
97  }
98  for( i = 0; i < row->len; ++i )
99  {
100  assert(row->cols[i] != NULL);
101  assert(row->cols[i]->var != NULL);
102  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
103  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
104  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
105  }
106 
107  /* print constant */
109  {
110  SCIPsetDebugMsgPrint(set, "%+.15g ", row->constant);
111  }
112 
113  /* print right hand side */
114  SCIPsetDebugMsgPrint(set, "<= %.15g\n", row->rhs);
115 }
116 #else
117 #define debugRowPrint(x,y) /**/
118 #endif
119 
120 #ifdef SCIP_DEBUG
121 /** method to output column if SCIP_DEBUG is define */
122 static
123 void debugColPrint(
124  SCIP_SET* set, /**< global SCIP settings */
125  SCIP_COL* col /**< LP column */
126  )
127 {
128  int r;
129 
130  assert(col != NULL);
131  assert(col->var != NULL);
132 
133  /* print bounds */
134  SCIPsetDebugMsgPrint(set, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
135 
136  /* print coefficients */
137  if( col->len == 0 )
138  {
139  SCIPsetDebugMsgPrint(set, "<empty>");
140  }
141  for( r = 0; r < col->len; ++r )
142  {
143  assert(col->rows[r] != NULL);
144  assert(col->rows[r]->name != NULL);
145  SCIPsetDebugMsgPrint(set, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
146  }
147  SCIPsetDebugMsgPrint(set, "\n");
148 }
149 #else
150 #define debugColPrint(x,y) /**/
151 #endif
152 
153 /*
154  * memory growing methods for dynamically allocated arrays
155  */
156 
157 /** ensures, that chgcols array can store at least num entries */
158 static
160  SCIP_LP* lp, /**< current LP data */
161  SCIP_SET* set, /**< global SCIP settings */
162  int num /**< minimum number of entries to store */
163  )
164 {
165  assert(lp->nchgcols <= lp->chgcolssize);
166 
167  if( num > lp->chgcolssize )
168  {
169  int newsize;
170 
171  newsize = SCIPsetCalcMemGrowSize(set, num);
172  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgcols, newsize) );
173  lp->chgcolssize = newsize;
174  }
175  assert(num <= lp->chgcolssize);
176 
177  return SCIP_OKAY;
178 }
179 
180 /** ensures, that chgrows array can store at least num entries */
181 static
183  SCIP_LP* lp, /**< current LP data */
184  SCIP_SET* set, /**< global SCIP settings */
185  int num /**< minimum number of entries to store */
186  )
187 {
188  assert(lp->nchgrows <= lp->chgrowssize);
189 
190  if( num > lp->chgrowssize )
191  {
192  int newsize;
193 
194  newsize = SCIPsetCalcMemGrowSize(set, num);
195  SCIP_ALLOC( BMSreallocMemoryArray(&lp->chgrows, newsize) );
196  lp->chgrowssize = newsize;
197  }
198  assert(num <= lp->chgrowssize);
199 
200  return SCIP_OKAY;
201 }
202 
203 /** ensures, that lpicols array can store at least num entries */
204 static
206  SCIP_LP* lp, /**< current LP data */
207  SCIP_SET* set, /**< global SCIP settings */
208  int num /**< minimum number of entries to store */
209  )
210 {
211  assert(lp->nlpicols <= lp->lpicolssize);
212 
213  if( num > lp->lpicolssize )
214  {
215  int newsize;
216 
217  newsize = SCIPsetCalcMemGrowSize(set, num);
218  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpicols, newsize) );
219  lp->lpicolssize = newsize;
220  }
221  assert(num <= lp->lpicolssize);
222 
223  return SCIP_OKAY;
224 }
225 
226 /** ensures, that lpirows array can store at least num entries */
227 static
229  SCIP_LP* lp, /**< current LP data */
230  SCIP_SET* set, /**< global SCIP settings */
231  int num /**< minimum number of entries to store */
232  )
233 {
234  assert(lp->nlpirows <= lp->lpirowssize);
235 
236  if( num > lp->lpirowssize )
237  {
238  int newsize;
239 
240  newsize = SCIPsetCalcMemGrowSize(set, num);
241  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lpirows, newsize) );
242  lp->lpirowssize = newsize;
243  }
244  assert(num <= lp->lpirowssize);
245 
246  return SCIP_OKAY;
247 }
248 
249 /** ensures, that cols array can store at least num entries */
250 static
252  SCIP_LP* lp, /**< current LP data */
253  SCIP_SET* set, /**< global SCIP settings */
254  int num /**< minimum number of entries to store */
255  )
256 {
257  assert(lp->ncols <= lp->colssize);
258 
259  if( num > lp->colssize )
260  {
261  int newsize;
262 
263  newsize = SCIPsetCalcMemGrowSize(set, num);
264  SCIP_ALLOC( BMSreallocMemoryArray(&lp->cols, newsize) );
265  lp->colssize = newsize;
266  }
267  assert(num <= lp->colssize);
268 
269  return SCIP_OKAY;
270 }
271 
272 /** ensures, that soldirection array can store at least num entries */
273 static
275  SCIP_LP* lp, /**< current LP data */
276  int num /**< minimum number of entries to store */
277  )
278 {
279  if( num > lp->soldirectionsize )
280  {
283 
284  lp->soldirectionsize = num;
285  }
286 
287  assert(num <= lp->soldirectionsize);
288 
289  return SCIP_OKAY;
290 }
291 
292 /** ensures, that lazy cols array can store at least num entries */
293 static
295  SCIP_LP* lp, /**< current LP data */
296  SCIP_SET* set, /**< global SCIP settings */
297  int num /**< minimum number of entries to store */
298  )
299 {
300  assert(lp->nlazycols <= lp->lazycolssize);
301 
302  if( num > lp->lazycolssize )
303  {
304  int newsize;
305 
306  newsize = SCIPsetCalcMemGrowSize(set, num);
307  SCIP_ALLOC( BMSreallocMemoryArray(&lp->lazycols, newsize) );
308  lp->lazycolssize = newsize;
309  }
310  assert(num <= lp->lazycolssize);
311 
312  return SCIP_OKAY;
313 }
314 
315 /** ensures, that rows array can store at least num entries */
316 static
318  SCIP_LP* lp, /**< current LP data */
319  SCIP_SET* set, /**< global SCIP settings */
320  int num /**< minimum number of entries to store */
321  )
322 {
323  assert(lp->nrows <= lp->rowssize);
324 
325  if( num > lp->rowssize )
326  {
327  int newsize;
328 
329  newsize = SCIPsetCalcMemGrowSize(set, num);
330  SCIP_ALLOC( BMSreallocMemoryArray(&lp->rows, newsize) );
331  lp->rowssize = newsize;
332  }
333  assert(num <= lp->rowssize);
334 
335  return SCIP_OKAY;
336 }
337 
338 /** ensures, that row array of column can store at least num entries */
339 static
341  SCIP_COL* col, /**< LP column */
342  BMS_BLKMEM* blkmem, /**< block memory */
343  SCIP_SET* set, /**< global SCIP settings */
344  int num /**< minimum number of entries to store */
345  )
346 {
347  assert(col != NULL);
348  assert(col->len <= col->size);
349 
350  if( num > col->size )
351  {
352  int newsize;
353 
354  newsize = SCIPsetCalcMemGrowSize(set, num);
355  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->rows, col->size, newsize) );
356  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->vals, col->size, newsize) );
357  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &col->linkpos, col->size, newsize) );
358  col->size = newsize;
359  }
360  assert(num <= col->size);
361 
362  return SCIP_OKAY;
363 }
364 
365 /** save current LP values dependent on the solution */
366 static
368  SCIP_LP* lp, /**< LP data */
369  SCIP_STAT* stat, /**< problem statistics */
370  BMS_BLKMEM* blkmem /**< block memory */
371  )
372 {
373  SCIP_LPSOLVALS* storedsolvals;
374 
375  assert(lp != NULL);
376  assert(stat != NULL);
377  assert(blkmem != NULL);
378 
379  /* allocate memory for storage */
380  if( lp->storedsolvals == NULL )
381  {
383  }
384  storedsolvals = lp->storedsolvals;
385 
386  /* store values */
387  storedsolvals->lpsolstat = lp->lpsolstat;
388  storedsolvals->lpobjval = lp->lpobjval;
389  storedsolvals->primalfeasible = lp->primalfeasible;
390  storedsolvals->primalchecked = lp->primalchecked;
391  storedsolvals->dualfeasible = lp->dualfeasible;
392  storedsolvals->dualchecked = lp->dualchecked;
393  storedsolvals->solisbasic = lp->solisbasic;
394  storedsolvals->lpissolved = lp->solved;
395 
396  return SCIP_OKAY;
397 }
398 
399 /** restore LP solution values in column */
400 static
402  SCIP_LP* lp, /**< LP data */
403  BMS_BLKMEM* blkmem, /**< block memory */
404  SCIP_Longint validlp /**< number of lp for which restored values are valid */
405  )
406 {
407  SCIP_LPSOLVALS* storedsolvals;
408 
409  assert(lp != NULL);
410  assert(blkmem != NULL);
411 
412  /* if stored values are available, restore them */
413  storedsolvals = lp->storedsolvals;
414  if( storedsolvals != NULL )
415  {
416  lp->solved = storedsolvals->lpissolved;
417  lp->validsollp = validlp;
418 
419  lp->lpsolstat = storedsolvals->lpsolstat;
420  lp->lpobjval = storedsolvals->lpobjval;
421  lp->primalfeasible = storedsolvals->primalfeasible;
422  lp->primalchecked = storedsolvals->primalchecked;
423  lp->dualfeasible = storedsolvals->dualfeasible;
424  lp->dualchecked = storedsolvals->dualchecked;
425  lp->solisbasic = storedsolvals->solisbasic;
426 
427  /* solution values are stored only for LPs solved to optimality or unboundedness */
428  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL ||
434  lp->validsollp == -1);
435  }
436  /* no values available, mark LP as unsolved */
437  else
438  {
439  lp->solved = FALSE;
440  lp->validsollp = -1;
441 
443  lp->lpobjval = SCIP_INVALID;
444  lp->primalfeasible = FALSE;
445  lp->primalchecked = FALSE;
446  lp->dualfeasible = FALSE;
447  lp->dualchecked = FALSE;
448  lp->solisbasic = FALSE;
449  lp->validfarkaslp = -1;
450  }
451 
452  lp->validdegeneracylp = -1;
453 
454  /* intentionally keep storage space allocated */
455 
456  return SCIP_OKAY;
457 }
458 
459 /** save current LP solution values stored in each column */
460 static
462  SCIP_COL* col, /**< LP column */
463  BMS_BLKMEM* blkmem /**< block memory */
464  )
465 {
466  SCIP_COLSOLVALS* storedsolvals;
467 
468  assert(col != NULL);
469  assert(blkmem != NULL);
470 
471  /* allocate memory for storage */
472  if( col->storedsolvals == NULL )
473  {
474  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &col->storedsolvals) );
475  }
476  storedsolvals = col->storedsolvals;
477 
478  /* store values */
479  storedsolvals->primsol = col->primsol;
480  storedsolvals->redcost = col->redcost;
481  storedsolvals->basisstatus = col->basisstatus; /*lint !e641 !e732*/
482 
483  return SCIP_OKAY;
484 }
485 
486 /** restore LP solution values in column */
487 static
489  SCIP_COL* col, /**< LP column */
490  BMS_BLKMEM* blkmem, /**< block memory */
491  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
492  SCIP_Bool freebuffer /**< should buffer for LP solution values be freed? */
493  )
494 {
495  SCIP_COLSOLVALS* storedsolvals;
496 
497  assert(col != NULL);
498  assert(blkmem != NULL);
499 
500  /* if stored values are available, restore them */
501  storedsolvals = col->storedsolvals;
502  if( storedsolvals != NULL )
503  {
504  col->primsol = storedsolvals->primsol;
505  col->redcost = storedsolvals->redcost;
506  col->validredcostlp = validlp;
507  col->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
508 
509  /* we do not save the farkas coefficient, since it can be recomputed; thus, we invalidate it here */
510  col->validfarkaslp = -1;
511  }
512  /* if the column was created after performing the storage (possibly during probing), we treat it as implicitly zero;
513  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
514  */
515  else
516  {
517  col->primsol = 0.0;
518  col->validredcostlp = -1;
519  col->validfarkaslp = -1;
520  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
521  }
522 
523  /* free memory */
524  if( freebuffer )
525  {
526  BMSfreeBlockMemoryNull(blkmem, &col->storedsolvals);
527  assert(col->storedsolvals == NULL);
528  }
529 
530  return SCIP_OKAY;
531 }
532 
533 /** save current LP solution values stored in each column */
534 static
536  SCIP_ROW* row, /**< LP row */
537  BMS_BLKMEM* blkmem, /**< block memory */
538  SCIP_Bool infeasible /**< is the solution infeasible? */
539  )
540 {
541  SCIP_ROWSOLVALS* storedsolvals;
542 
543  assert(row != NULL);
544  assert(blkmem != NULL);
545 
546  /* allocate memory for storage */
547  if( row->storedsolvals == NULL )
548  {
549  SCIP_ALLOC( BMSallocBlockMemory(blkmem, &row->storedsolvals) );
550  }
551  storedsolvals = row->storedsolvals;
552 
553  /* store values */
554  if ( infeasible )
555  {
556  storedsolvals->dualsol = row->dualfarkas;
557  storedsolvals->activity = SCIP_INVALID;
558  storedsolvals->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
559  }
560  else
561  {
562  storedsolvals->dualsol = row->dualsol;
563  storedsolvals->activity = row->activity;
564  storedsolvals->basisstatus = row->basisstatus; /*lint !e641 !e732*/
565  }
566 
567  return SCIP_OKAY;
568 }
569 
570 /** restore LP solution values in row */
571 static
573  SCIP_ROW* row, /**< LP column */
574  BMS_BLKMEM* blkmem, /**< block memory */
575  SCIP_Longint validlp, /**< number of lp for which restored values are valid */
576  SCIP_Bool freebuffer, /**< should buffer for LP solution values be freed? */
577  SCIP_Bool infeasible /**< is the solution infeasible? */
578  )
579 {
580  SCIP_ROWSOLVALS* storedsolvals;
581 
582  assert(row != NULL);
583  assert(blkmem != NULL);
584 
585  /* if stored values are available, restore them */
586  storedsolvals = row->storedsolvals;
587  if( storedsolvals != NULL )
588  {
589  if ( infeasible )
590  row->dualfarkas = storedsolvals->dualsol;
591  else
592  row->dualsol = storedsolvals->dualsol;
593  row->activity = storedsolvals->activity;
594  row->validactivitylp = validlp;
595  row->basisstatus = storedsolvals->basisstatus; /*lint !e641 !e732*/
596  }
597  /* if the row was created after performing the storage (possibly during probing), we treat it as basic;
598  * we make sure to invalidate the reduced cost and farkas coefficient, which are not available
599  */
600  else
601  {
602  row->dualsol = 0.0;
603  row->dualfarkas = 0.0;
604  row->activity = SCIP_INVALID;
605  row->validactivitylp = -1;
606  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
607  }
608 
609  /* free memory */
610  if( freebuffer )
611  {
612  BMSfreeBlockMemoryNull(blkmem, &row->storedsolvals);
613  assert(row->storedsolvals == NULL);
614  }
615 
616  return SCIP_OKAY;
617 }
618 
619 /** ensures, that column array of row can store at least num entries */
621  SCIP_ROW* row, /**< LP row */
622  BMS_BLKMEM* blkmem, /**< block memory */
623  SCIP_SET* set, /**< global SCIP settings */
624  int num /**< minimum number of entries to store */
625  )
626 {
627  assert(row != NULL);
628  assert(row->len <= row->size);
629 
630  if( num > row->size )
631  {
632  int newsize;
633 
634  newsize = SCIPsetCalcMemGrowSize(set, num);
635  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols, row->size, newsize) );
636  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->cols_index, row->size, newsize) );
637  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->vals, row->size, newsize) );
638  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &row->linkpos, row->size, newsize) );
639  row->size = newsize;
640  }
641  assert(num <= row->size);
642 
643  return SCIP_OKAY;
644 }
645 
646 
647 #ifdef SCIP_MORE_DEBUG /* enable this to check the sortings within rows (for debugging, very slow!) */
648 static SCIP_Bool msgdisp_checkrow = FALSE;
649 
650 static
651 void checkRow(
652  SCIP_ROW* row
653  )
654 {
655  int i;
656 
657  if( !msgdisp_checkrow )
658  {
659  printf("LP ROW CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
660  msgdisp_checkrow = TRUE;
661  }
662 
663  /* validate sorting of LP part of row */
664  if( row->lpcolssorted && row->nlpcols > 0)
665  {
666  assert(row->cols_index[0] == row->cols[0]->index);
667  for( i = 1; i < row->nlpcols; ++i )
668  {
669  assert(row->cols_index[i] == row->cols[i]->index);
670  assert(row->cols_index[i] >= row->cols_index[i-1]);
671  }
672  }
673 
674  /* validate sorting of non-LP part of row */
675  if( row->nonlpcolssorted && row->len > row->nlpcols )
676  {
677  assert(row->cols_index[row->nlpcols] == row->cols[row->nlpcols]->index);
678  for( i = row->nlpcols + 1; i < row->len; ++i )
679  {
680  assert(row->cols_index[i] == row->cols[i]->index);
681  assert(row->cols_index[i] >= row->cols_index[i-1]);
682  }
683  }
684 }
685 #else
686 #define checkRow(row) /**/
687 #endif
688 
689 #ifdef SCIP_MORE_DEBUG /* enable this to check norms of rows (for debugging, very slow!) */
690 static
691 void checkRowSqrnorm(
692  SCIP_ROW* row
693  )
694 {
695  SCIP_COL** cols;
696  SCIP_Real sqrnorm;
697  int c;
698 
699  cols = row->cols;
700  assert(cols != NULL || row->len == 0);
701 
702  sqrnorm = 0.0;
703 
704  for( c = row->len - 1; c >= 0; --c )
705  {
706  if( cols[c]->lppos >= 0 )
707  sqrnorm += SQR(row->vals[c]);
708  }
709 
710  assert(ABS(sqrnorm - row->sqrnorm) < 1e-06 * MAX(1.0,sqrnorm));
711 }
712 
713 static
714 void checkRowSumnorm(
715  SCIP_ROW* row
716  )
717 {
718  SCIP_COL** cols;
719  SCIP_Real sumnorm;
720  int c;
721 
722  cols = row->cols;
723  assert(cols != NULL || row->len == 0);
724 
725  sumnorm = 0.0;
726 
727  for( c = row->len - 1; c >= 0; --c )
728  {
729  if( cols[c]->lppos >= 0 )
730  sumnorm += REALABS(row->vals[c]);
731  }
732 
733  assert(ABS(sumnorm - row->sumnorm) < 1e-06 * MAX(1.0,sumnorm));
734 }
735 
736 static
737 void checkRowObjprod(
738  SCIP_ROW* row
739  )
740 {
741  SCIP_COL** cols;
742  SCIP_Real objprod;
743  int c;
744 
745  cols = row->cols;
746  assert(cols != NULL || row->len == 0);
747 
748  objprod = 0.0;
749 
750  for( c = row->len - 1; c >= 0; --c )
751  {
752  if( cols[c]->lppos >= 0 )
753  objprod += row->vals[c] * cols[c]->unchangedobj;
754  }
755 
756  assert(ABS(objprod - row->objprod) < 1e-06 * MAX(1.0,objprod));
757 }
758 #else
759 #define checkRowSqrnorm(row) /**/
760 #define checkRowSumnorm(row) /**/
761 #define checkRowObjprod(row) /**/
762 #endif
763 
764 /*
765  * Local methods for pseudo and loose objective values
766  */
767 
768 /* recompute the loose objective value from scratch, if it was marked to be unreliable before */
769 static
771  SCIP_LP* lp, /**< current LP data */
772  SCIP_SET* set, /**< global SCIP settings */
773  SCIP_PROB* prob /**< problem data */
774  )
775 {
776  SCIP_VAR** vars;
777  SCIP_Real obj;
778  int nvars;
779  int v;
780 
781  assert(lp != NULL);
782  assert(set != NULL);
783  assert(prob != NULL);
784  assert(!lp->looseobjvalid);
785 
786  vars = prob->vars;
787  nvars = prob->nvars;
788  lp->looseobjval = 0.0;
789 
790  /* iterate over all variables in the problem */
791  for( v = 0; v < nvars; ++v )
792  {
793  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_LOOSE )
794  {
795  obj = SCIPvarGetObj(vars[v]);
796 
797  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
798  if( SCIPsetIsPositive(set, obj) && !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
799  lp->looseobjval += obj * SCIPvarGetLbLocal(vars[v]);
800  else if( SCIPsetIsNegative(set, obj) && !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
801  lp->looseobjval += obj * SCIPvarGetUbLocal(vars[v]);
802  }
803  }
804 
805  /* the recomputed value is reliable */
806  lp->rellooseobjval = lp->looseobjval;
807  lp->looseobjvalid = TRUE;
808 }
809 
810 /* recompute the pseudo solution value from scratch, if it was marked to be unreliable before */
811 static
813  SCIP_LP* lp, /**< current LP data */
814  SCIP_SET* set, /**< global SCIP settings */
815  SCIP_PROB* prob /**< problem data */
816  )
817 {
818  SCIP_VAR** vars;
819  int nvars;
820  int v;
821 
822  assert(lp != NULL);
823  assert(set != NULL);
824  assert(prob != NULL);
825  assert(!lp->pseudoobjvalid);
826 
827  vars = prob->vars;
828  nvars = prob->nvars;
829  lp->pseudoobjval = 0.0;
830 
831  /* iterate over all variables in the problem */
832  for( v = 0; v < nvars; ++v )
833  {
834  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
835  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
836  !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
837  {
838  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbLocal(vars[v]);
839  }
840  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
841  !SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
842  {
843  lp->pseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbLocal(vars[v]);
844  }
845  }
846 
847  /* the recomputed value is reliable */
848  lp->relpseudoobjval = lp->pseudoobjval;
849  lp->pseudoobjvalid = TRUE;
850 }
851 
852 /* recompute the global pseudo solution value from scratch, if it was marked to be unreliable before */
853 static
855  SCIP_LP* lp, /**< current LP data */
856  SCIP_SET* set, /**< global SCIP settings */
857  SCIP_PROB* prob /**< problem data */
858  )
859 {
860  SCIP_VAR** vars;
861  int nvars;
862  int v;
863 
864  assert(lp != NULL);
865  assert(set != NULL);
866  assert(prob != NULL);
867  assert(!lp->glbpseudoobjvalid);
868 
869  vars = prob->vars;
870  nvars = prob->nvars;
871  lp->glbpseudoobjval = 0.0;
872 
873  /* iterate over all variables in the problem */
874  for( v = 0; v < nvars; ++v )
875  {
876  /* we are only interested in variables with a finite impact, because the infinity counters should be correct */
877  if( SCIPsetIsPositive(set, SCIPvarGetObj(vars[v])) &&
878  !SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
879  {
880  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetLbGlobal(vars[v]);
881  }
882  else if( SCIPsetIsNegative(set, SCIPvarGetObj(vars[v])) &&
883  !SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
884  {
885  lp->glbpseudoobjval += SCIPvarGetObj(vars[v]) * SCIPvarGetUbGlobal(vars[v]);
886  }
887  }
888 
889  /* the recomputed value is reliable */
891  lp->glbpseudoobjvalid = TRUE;
892 }
893 
894 /** gets finite part of objective value of current LP that results from LOOSE variables only */
895 static
897  SCIP_LP* lp, /**< current LP data */
898  SCIP_SET* set, /**< global SCIP settings */
899  SCIP_PROB* prob /**< problem data */
900  )
901 {
902  assert(lp != NULL);
903  assert(set != NULL);
904  assert(prob != NULL);
905  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
906  assert(lp->flushed);
907  assert(lp->looseobjvalinf == 0);
908 
909  /* recalculate the loose objective value, if needed */
910  if( !lp->looseobjvalid )
911  recomputeLooseObjectiveValue(lp, set, prob);
912 
913  return lp->looseobjval;
914 }
915 
916 /** gets finite part of pseudo objective value of current LP */
917 static
919  SCIP_LP* lp, /**< current LP data */
920  SCIP_SET* set, /**< global SCIP settings */
921  SCIP_PROB* prob /**< problem data */
922  )
923 {
924  assert(lp != NULL);
925  assert(set != NULL);
926  assert(prob != NULL);
927 
928  /* recalculate the pseudo objective value, if needed */
929  if( !lp->pseudoobjvalid )
930  recomputePseudoObjectiveValue(lp, set, prob);
931 
932  return lp->pseudoobjval;
933 }
934 
935 /*
936  * Sorting and searching rows and columns
937  */
938 
939 
940 /** comparison method for sorting rows by non-decreasing index */
942 {
943  assert(elem1 != NULL);
944  assert(elem2 != NULL);
945 
946  if( ((SCIP_ROW*)elem1)->index < ((SCIP_ROW*)elem2)->index )
947  return -1;
948  else if( ((SCIP_ROW*)elem1)->index > ((SCIP_ROW*)elem2)->index )
949  return +1;
950  else
951  {
952  assert(SCIProwGetIndex((SCIP_ROW*)(elem1)) == SCIProwGetIndex(((SCIP_ROW*)elem2)));
953  return 0;
954  }
955 }
956 
957 
958 /** sorts column entries of linked rows currently in the LP such that lower row indices precede higher ones */
959 static
961  SCIP_COL* col /**< column to be sorted */
962  )
963 {
964  int i;
965 
966  assert(col != NULL);
967 
968  /* check, if column is already sorted in the LP part */
969  if( col->lprowssorted )
970  return;
971 
972  /* sort coefficients */
973  SCIPsortPtrRealInt((void**)col->rows, col->vals, col->linkpos, SCIProwComp, col->nlprows );
974 
975  /* update links */
976  for( i = 0; i < col->nlprows; ++i )
977  {
978  if( col->linkpos[i] >= 0 )
979  {
980  assert(col->rows[i]->cols[col->linkpos[i]] == col);
981  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
982  col->rows[i]->linkpos[col->linkpos[i]] = i;
983  }
984  }
985 
986  col->lprowssorted = TRUE;
987 }
988 
989 /** sorts column entries of unlinked rows or rows currently not in the LP such that lower row indices precede higher
990  * ones
991  */
992 static
994  SCIP_COL* col /**< column to be sorted */
995  )
996 {
997  int i;
998 
999  assert(col != NULL);
1000 
1001  /* check, if column is already sorted in the non-LP part */
1002  if( col->nonlprowssorted )
1003  return;
1004 
1005  /* sort coefficients */
1006  SCIPsortPtrRealInt((void**)(&(col->rows[col->nlprows])), &(col->vals[col->nlprows]), &(col->linkpos[col->nlprows]), SCIProwComp, col->len - col->nlprows);
1007 
1008  /* update links */
1009  for( i = col->nlprows; i < col->len; ++i )
1010  {
1011  if( col->linkpos[i] >= 0 )
1012  {
1013  assert(col->rows[i]->cols[col->linkpos[i]] == col);
1014  assert(col->rows[i]->linkpos[col->linkpos[i]] >= 0);
1015  col->rows[i]->linkpos[col->linkpos[i]] = i;
1016  }
1017  }
1018 
1019  col->nonlprowssorted = TRUE;
1020 }
1021 
1022 /** sorts row entries of linked columns currently in the LP such that lower column indices precede higher ones */
1023 static
1025  SCIP_ROW* row /**< row to be sorted */
1026  )
1027 {
1028  int i;
1029 
1030  assert(row != NULL);
1031 
1032  /* check, if row is already sorted in the LP part, or if the sorting should be delayed */
1033  if( row->lpcolssorted || row->delaysort )
1034  return;
1035 
1036  /* sort coefficients */
1037  SCIPsortIntPtrIntReal(row->cols_index, (void**)row->cols, row->linkpos, row->vals, row->nlpcols);
1038 
1039  /* update links */
1040  for( i = 0; i < row->nlpcols; ++i )
1041  {
1042  if( row->linkpos[i] >= 0 )
1043  {
1044  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1045  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1046  row->cols[i]->linkpos[row->linkpos[i]] = i;
1047  }
1048  }
1049 
1050  row->lpcolssorted = TRUE;
1051 }
1052 
1053 /** sorts row entries of unlinked columns or columns currently not in the LP such that lower column indices precede
1054  * higher ones
1055  */
1056 static
1058  SCIP_ROW* row /**< row to be sorted */
1059  )
1060 {
1061  int i;
1062 
1063  assert(row != NULL);
1064 
1065  checkRow(row);
1066 
1067  /* check, if row is already sorted in the non-LP part, or if the sorting should be delayed */
1068  if( row->nonlpcolssorted || row->delaysort )
1069  return;
1070 
1071  /* sort coefficients */
1072  SCIPsortIntPtrIntReal(&(row->cols_index[row->nlpcols]), (void**)(&(row->cols[row->nlpcols])), &(row->linkpos[row->nlpcols]), &(row->vals[row->nlpcols]), row->len - row->nlpcols);
1073 
1074  /* update links */
1075  for( i = row->nlpcols; i < row->len; ++i )
1076  {
1077  if( row->linkpos[i] >= 0 )
1078  {
1079  assert(row->cols[i]->rows[row->linkpos[i]] == row);
1080  assert(row->cols[i]->linkpos[row->linkpos[i]] >= 0);
1081  row->cols[i]->linkpos[row->linkpos[i]] = i;
1082  }
1083  }
1084 
1085  checkRow(row);
1086 
1087  row->nonlpcolssorted = TRUE;
1088 }
1089 
1090 /** searches coefficient in part of the column, returns position in col vector or -1 if not found */
1091 static
1093  SCIP_COL* col, /**< column to be searched in */
1094  const SCIP_ROW* row, /**< coefficient to be searched for */
1095  int minpos, /**< first position of search range */
1096  int maxpos /**< last position of search range */
1097  )
1098 {
1099  int pos;
1100  int idx;
1101  int searchidx;
1102 
1103  assert(col != NULL);
1104  assert(row != NULL);
1105 
1106  /* binary search */
1107  searchidx = row->index;
1108  while(minpos <= maxpos)
1109  {
1110  pos = (minpos + maxpos)/2;
1111  assert(0 <= pos && pos < col->len);
1112  assert(col->rows[pos] != NULL);
1113  assert((pos < col->nlprows) == (col->rows[pos]->lppos >= 0 && col->linkpos[pos] >= 0));
1114  idx = col->rows[pos]->index;
1115  if( searchidx == idx )
1116  return pos;
1117  else if( searchidx < idx )
1118  maxpos = pos-1;
1119  else
1120  minpos = pos+1;
1121  }
1122 
1123  return -1;
1124 }
1125 
1126 /** searches coefficient in column, returns position in col vector or -1 if not found */
1127 static
1129  SCIP_COL* col, /**< column to be searched in */
1130  const SCIP_ROW* row /**< coefficient to be searched for */
1131  )
1132 {
1133  int pos;
1134 
1135  assert(col != NULL);
1136  assert(row != NULL);
1137 
1138  pos = -1;
1139 
1140  /* search in the linked LP rows */
1141  if( row->lppos >= 0 )
1142  {
1143  /* column has to be sorted, such that binary search works */
1144  colSortLP(col);
1145  assert(col->lprowssorted);
1146 
1147  pos = colSearchCoefPart(col, row, 0, col->nlprows-1);
1148  if( pos >= 0 )
1149  return pos;
1150  }
1151 
1152  /* search in the non-LP/unlinked rows */
1153  if( row->lppos == -1 || col->nunlinked > 0 )
1154  {
1155  /* column has to be sorted, such that binary search works */
1156  colSortNonLP(col);
1157  assert(col->nonlprowssorted);
1158 
1159  pos = colSearchCoefPart(col, row, col->nlprows, col->len-1);
1160  }
1161 
1162  return pos;
1163 }
1164 
1165 /** searches coefficient in part of the row, returns position in col vector or -1 if not found */
1166 static
1168  SCIP_ROW* row, /**< row to be searched in */
1169  const SCIP_COL* col, /**< coefficient to be searched for */
1170  int minpos, /**< first position of search range */
1171  int maxpos /**< last position of search range */
1172  )
1173 {
1174  int pos;
1175  int idx;
1176  int searchidx;
1177 
1178  assert(row != NULL);
1179  assert(col != NULL);
1180 
1181  /* binary search */
1182  searchidx = col->index;
1183  while(minpos <= maxpos)
1184  {
1185  pos = (minpos + maxpos)/2;
1186  assert(0 <= pos && pos < row->len);
1187  assert(row->cols[pos] != NULL);
1188  assert((pos < row->nlpcols) == (row->cols[pos]->lppos >= 0 && row->linkpos[pos] >= 0));
1189  assert(row->cols_index[pos] == row->cols[pos]->index);
1190  idx = row->cols_index[pos];
1191  if( searchidx == idx )
1192  return pos;
1193  else if( searchidx < idx )
1194  maxpos = pos-1;
1195  else
1196  minpos = pos+1;
1197  }
1198 
1199  return -1;
1200 }
1201 
1202 /** searches coefficient in row, returns position in row vector or -1 if not found;
1203  * if the sorting of the row is delayed, returns -1
1204  */
1205 static
1207  SCIP_ROW* row, /**< row to be searched in */
1208  const SCIP_COL* col /**< coefficient to be searched for */
1209  )
1210 {
1211  int pos;
1212 
1213  assert(row != NULL);
1214  assert(col != NULL);
1215 
1216  if( row->delaysort )
1217  return -1;
1218 
1219  pos = -1;
1220 
1221  /* search in the linked LP columns */
1222  if( col->lppos >= 0 )
1223  {
1224  /* row has to be sorted, such that binary search works */
1225  rowSortLP(row);
1226  assert(row->lpcolssorted);
1227 
1228  pos = rowSearchCoefPart(row, col, 0, row->nlpcols-1);
1229  }
1230 
1231  /* search in the non-LP/unlinked columns */
1232  if( pos == -1 && (col->lppos == -1 || row->nunlinked > 0) )
1233  {
1234  /* row has to be sorted, such that binary search works */
1235  rowSortNonLP(row);
1236  assert(row->nonlpcolssorted);
1237 
1238  pos = rowSearchCoefPart(row, col, row->nlpcols, row->len-1);
1239  }
1240 
1241 #ifndef NDEBUG
1242  /* validate result */
1243  assert(-1 <= pos && pos < row->len);
1244  if( pos >= 0 )
1245  assert(row->cols[pos] == col);
1246  else
1247  {
1248  int i;
1249  for( i = 0; i < row->len; ++i )
1250  assert(row->cols[i] != col);
1251  }
1252 #endif
1253 
1254  return pos;
1255 }
1256 
1257 /** moves a coefficient in a column to a different place, and updates all corresponding data structures */
1258 static
1260  SCIP_COL* col, /**< LP column */
1261  int oldpos, /**< old position of coefficient */
1262  int newpos /**< new position of coefficient */
1263  )
1264 {
1265  assert(col != NULL);
1266  assert(0 <= oldpos && oldpos < col->len);
1267  assert(0 <= newpos && newpos < col->len);
1268  assert(col->rows[oldpos] != NULL);
1269 
1270  if( oldpos == newpos )
1271  return;
1272 
1273  col->rows[newpos] = col->rows[oldpos];
1274  col->vals[newpos] = col->vals[oldpos];
1275  col->linkpos[newpos] = col->linkpos[oldpos];
1276 
1277  /* update link position in row */
1278  if( col->linkpos[newpos] >= 0 )
1279  {
1280  assert(col->rows[newpos]->cols[col->linkpos[newpos]] == col);
1281  assert(col->rows[newpos]->linkpos[col->linkpos[newpos]] == oldpos);
1282 
1283  col->rows[newpos]->linkpos[col->linkpos[newpos]] = newpos;
1284  }
1285 
1286  /* update sorted flags */
1287  if( col->rows[newpos]->lppos >= 0 && col->linkpos[newpos] >= 0 )
1288  col->lprowssorted = FALSE;
1289  else
1290  col->nonlprowssorted = FALSE;
1291 }
1292 
1293 /** swaps two coefficients in a column, and updates all corresponding data structures */
1294 static
1296  SCIP_COL* col, /**< LP column */
1297  int pos1, /**< position of first coefficient */
1298  int pos2 /**< position of second coefficient */
1299  )
1300 {
1301  SCIP_ROW* tmprow;
1302  SCIP_Real tmpval;
1303  int tmplinkpos;
1304 
1305  assert(col != NULL);
1306  assert(0 <= pos1 && pos1 < col->len);
1307  assert(0 <= pos2 && pos2 < col->len);
1308  assert(col->rows[pos1] != NULL);
1309 
1310  if( pos1 == pos2 )
1311  return;
1312 
1313  /* swap coefficients */
1314  tmprow = col->rows[pos2];
1315  tmpval = col->vals[pos2];
1316  tmplinkpos = col->linkpos[pos2];
1317 
1318  col->rows[pos2] = col->rows[pos1];
1319  col->vals[pos2] = col->vals[pos1];
1320  col->linkpos[pos2] = col->linkpos[pos1];
1321 
1322  col->rows[pos1] = tmprow;
1323  col->vals[pos1] = tmpval;
1324  col->linkpos[pos1] = tmplinkpos;
1325 
1326  /* update link position in rows */
1327  if( col->linkpos[pos1] >= 0 )
1328  {
1329  assert(col->rows[pos1]->cols[col->linkpos[pos1]] == col);
1330  assert(col->rows[pos1]->linkpos[col->linkpos[pos1]] == pos2);
1331 
1332  col->rows[pos1]->linkpos[col->linkpos[pos1]] = pos1;
1333  }
1334  if( col->linkpos[pos2] >= 0 )
1335  {
1336  assert(col->rows[pos2]->cols[col->linkpos[pos2]] == col);
1337  assert(col->rows[pos2]->linkpos[col->linkpos[pos2]] == pos1);
1338 
1339  col->rows[pos2]->linkpos[col->linkpos[pos2]] = pos2;
1340  }
1341 
1342  /* update sorted flags */
1343  if( col->rows[pos1]->lppos >= 0 && col->linkpos[pos1] >= 0 )
1344  col->lprowssorted = FALSE;
1345  else
1346  col->nonlprowssorted = FALSE;
1347  if( col->rows[pos2]->lppos >= 0 && col->linkpos[pos2] >= 0 )
1348  col->lprowssorted = FALSE;
1349  else
1350  col->nonlprowssorted = FALSE;
1351 }
1352 
1353 /** moves a coefficient in a row to a different place, and updates all corresponding data structures */
1354 static
1356  SCIP_ROW* row, /**< LP row */
1357  int oldpos, /**< old position of coefficient */
1358  int newpos /**< new position of coefficient */
1359  )
1360 {
1361  assert(row != NULL);
1362  assert(0 <= oldpos && oldpos < row->len);
1363  assert(0 <= newpos && newpos < row->len);
1364  assert(row->cols[oldpos] != NULL);
1365 
1366  if( oldpos == newpos )
1367  return;
1368 
1369  row->cols[newpos] = row->cols[oldpos];
1370  row->cols_index[newpos] = row->cols_index[oldpos];
1371  row->vals[newpos] = row->vals[oldpos];
1372  row->linkpos[newpos] = row->linkpos[oldpos];
1373 
1374  /* update link position in column */
1375  if( row->linkpos[newpos] >= 0 )
1376  {
1377  assert(row->cols[newpos]->rows[row->linkpos[newpos]] == row);
1378  assert(row->cols[newpos]->linkpos[row->linkpos[newpos]] == oldpos);
1379 
1380  row->cols[newpos]->linkpos[row->linkpos[newpos]] = newpos;
1381  }
1382 
1383  /* update sorted flags */
1384  if( row->cols[newpos]->lppos >= 0 && row->linkpos[newpos] >= 0 )
1385  row->lpcolssorted = FALSE;
1386  else
1387  row->nonlpcolssorted = FALSE;
1388 }
1389 
1390 /** swaps two coefficients in a row, and updates all corresponding data structures */
1391 static
1393  SCIP_ROW* row, /**< LP row */
1394  int pos1, /**< position of first coefficient */
1395  int pos2 /**< position of second coefficient */
1396  )
1397 {
1398  SCIP_COL* tmpcol;
1399  SCIP_Real tmpval;
1400  int tmpindex;
1401  int tmplinkpos;
1402 
1403  assert(row != NULL);
1404  assert(0 <= pos1 && pos1 < row->len);
1405  assert(0 <= pos2 && pos2 < row->len);
1406  assert(row->cols[pos1] != NULL);
1407  assert(row->cols[pos1]->index == row->cols_index[pos1]);
1408 
1409  if( pos1 == pos2 )
1410  return;
1411 
1412  /* swap coefficients */
1413  tmpcol = row->cols[pos2];
1414  tmpindex = row->cols_index[pos2];
1415  tmpval = row->vals[pos2];
1416  tmplinkpos = row->linkpos[pos2];
1417 
1418  row->cols[pos2] = row->cols[pos1];
1419  row->cols_index[pos2] = row->cols_index[pos1];
1420  row->vals[pos2] = row->vals[pos1];
1421  row->linkpos[pos2] = row->linkpos[pos1];
1422 
1423  row->cols[pos1] = tmpcol;
1424  row->cols_index[pos1] = tmpindex;
1425  row->vals[pos1] = tmpval;
1426  row->linkpos[pos1] = tmplinkpos;
1427 
1428  /* update link position in columns */
1429  if( row->linkpos[pos1] >= 0 )
1430  {
1431  assert(row->cols[pos1]->rows[row->linkpos[pos1]] == row);
1432  assert(row->cols[pos1]->linkpos[row->linkpos[pos1]] == pos2);
1433 
1434  row->cols[pos1]->linkpos[row->linkpos[pos1]] = pos1;
1435  }
1436  if( row->linkpos[pos2] >= 0 )
1437  {
1438  assert(row->cols[pos2]->rows[row->linkpos[pos2]] == row);
1439  assert(row->cols[pos2]->linkpos[row->linkpos[pos2]] == pos1);
1440 
1441  row->cols[pos2]->linkpos[row->linkpos[pos2]] = pos2;
1442  }
1443 
1444  /* update sorted flags */
1445  if( row->cols[pos1]->lppos >= 0 && row->linkpos[pos1] >= 0 )
1446  row->lpcolssorted = FALSE;
1447  else
1448  row->nonlpcolssorted = FALSE;
1449  if( row->cols[pos2]->lppos >= 0 && row->linkpos[pos2] >= 0 )
1450  row->lpcolssorted = FALSE;
1451  else
1452  row->nonlpcolssorted = FALSE;
1453 }
1454 
1455 /** issues a ROWCOEFCHANGED event on the given row */
1456 static
1458  SCIP_ROW* row, /**< row which coefficient has changed */
1459  BMS_BLKMEM* blkmem, /**< block memory */
1460  SCIP_SET* set, /**< global SCIP settings */
1461  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1462  SCIP_COL* col, /**< the column which coefficient has changed */
1463  SCIP_Real oldval, /**< old value of the coefficient */
1464  SCIP_Real newval /**< new value of the coefficient */
1465  )
1466 {
1467  assert(row != NULL);
1468  assert(row->eventfilter != NULL);
1469  assert(col != NULL);
1470 
1471  /* check, if the row is being tracked for coefficient changes
1472  * if so, issue ROWCOEFCHANGED event
1473  */
1474  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCOEFCHANGED) != 0) )
1475  {
1476  SCIP_EVENT* event;
1477 
1478  SCIP_CALL( SCIPeventCreateRowCoefChanged(&event, blkmem, row, col, oldval, newval) );
1479  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1480  }
1481 
1482  return SCIP_OKAY;
1483 }
1484 
1485 /** issues a ROWCONSTCHANGED event on the given row */
1486 static
1488  SCIP_ROW* row, /**< row which coefficient has changed */
1489  BMS_BLKMEM* blkmem, /**< block memory */
1490  SCIP_SET* set, /**< global SCIP settings */
1491  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1492  SCIP_Real oldval, /**< old value of the constant */
1493  SCIP_Real newval /**< new value of the constant */
1494  )
1495 {
1496  assert(row != NULL);
1497  assert(row->eventfilter != NULL);
1498 
1499  /* check, if the row is being tracked for coefficient changes
1500  * if so, issue ROWCONSTCHANGED event
1501  */
1502  if( (row->eventfilter->len > 0 && (row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWCONSTCHANGED)) )
1503  {
1504  SCIP_EVENT* event;
1505 
1506  SCIP_CALL( SCIPeventCreateRowConstChanged(&event, blkmem, row, oldval, newval) );
1507  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1508  }
1509 
1510  return SCIP_OKAY;
1511 }
1512 
1513 /** issues a ROWSIDECHANGED event on the given row */
1514 static
1516  SCIP_ROW* row, /**< row which coefficient has changed */
1517  BMS_BLKMEM* blkmem, /**< block memory */
1518  SCIP_SET* set, /**< global SCIP settings */
1519  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1520  SCIP_SIDETYPE side, /**< the side that has changed */
1521  SCIP_Real oldval, /**< old value of side */
1522  SCIP_Real newval /**< new value of side */
1523  )
1524 {
1525  assert(row != NULL);
1526  assert(row->eventfilter != NULL);
1527 
1528  /* check, if the row is being tracked for coefficient changes
1529  * if so, issue ROWSIDECHANGED event
1530  */
1531  if( (row->eventfilter->len > 0 && !(row->eventfilter->eventmask & SCIP_EVENTTYPE_ROWSIDECHANGED)) )
1532  {
1533  SCIP_EVENT* event;
1534 
1535  SCIP_CALL( SCIPeventCreateRowSideChanged(&event, blkmem, row, side, oldval, newval) );
1536  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, row->eventfilter, &event) );
1537  }
1538 
1539  return SCIP_OKAY;
1540 }
1541 
1542 #ifdef SCIP_MORE_DEBUG /* enable this to check links between columns and rows in LP data structure (for debugging, very slow!) */
1543 
1544 #ifdef NDEBUG
1545 #define ASSERT(x) do { if( !(x) ) abort(); } while( FALSE )
1546 #else
1547 #define ASSERT(x) assert(x)
1548 #endif
1549 
1550 static SCIP_Bool msgdisp_checklinks = FALSE;
1551 
1552 
1553 static
1554 void checkLinks(
1555  SCIP_LP* lp /**< current LP data */
1556  )
1557 {
1558  SCIP_COL* col;
1559  SCIP_ROW* row;
1560  int i;
1561  int j;
1562 
1563  ASSERT(lp != NULL);
1564 
1565  if( !msgdisp_checklinks )
1566  {
1567  printf("LP LINK CHECKING ACTIVATED! THIS IS VERY SLOW!\n");
1568  msgdisp_checklinks = TRUE;
1569  }
1570 
1571  for( i = 0; i < lp->ncols; ++i )
1572  {
1573  col = lp->cols[i];
1574  ASSERT(col != NULL);
1575  ASSERT(!lp->flushed || col->lppos >= 0 || col->primsol == 0.0);
1576  ASSERT(!lp->flushed || col->lppos >= 0 || col->farkascoef == 0.0);
1577  ASSERT(col->nlprows <= col->len);
1578  ASSERT(col->lppos == -1 || col->lppos >= lp->lpifirstchgcol || col->nunlinked == 0);
1579 
1580  for( j = 0; j < col->len; ++j )
1581  {
1582  row = col->rows[j];
1583  ASSERT(row != NULL);
1584  ASSERT(!lp->flushed || col->lppos == -1 || col->linkpos[j] >= 0);
1585  ASSERT(col->linkpos[j] == -1 || row->cols[col->linkpos[j]] == col);
1586  ASSERT(col->linkpos[j] == -1 || EPSEQ(row->vals[col->linkpos[j]], col->vals[j], 1e-6));
1587  ASSERT((j < col->nlprows) == (col->linkpos[j] >= 0 && row->lppos >= 0));
1588  }
1589  }
1590 
1591  for( i = 0; i < lp->nrows; ++i )
1592  {
1593  row = lp->rows[i];
1594  ASSERT(row != NULL);
1595  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualsol == 0.0);
1596  ASSERT(!lp->flushed || row->lppos >= 0 || row->dualfarkas == 0.0);
1597  ASSERT(row->nlpcols <= row->len);
1598  ASSERT(row->lppos == -1 || row->lppos >= lp->lpifirstchgrow || row->nunlinked == 0);
1599 
1600  for( j = 0; j < row->len; ++j )
1601  {
1602  col = row->cols[j];
1603  ASSERT(col != NULL);
1604  ASSERT(!lp->flushed || row->lppos == -1 || row->linkpos[j] >= 0);
1605  ASSERT(row->linkpos[j] == -1 || col->rows[row->linkpos[j]] == row);
1606  ASSERT(row->linkpos[j] == -1 || EPSEQ(col->vals[row->linkpos[j]], row->vals[j], 1e-6));
1607  ASSERT((j < row->nlpcols) == (row->linkpos[j] >= 0 && col->lppos >= 0));
1608  }
1609  }
1610 }
1611 
1612 #undef ASSERT
1613 
1614 #else
1615 #define checkLinks(lp) /**/
1616 #endif
1617 
1618 /*
1619  * Changing announcements
1620  */
1621 
1622 /** announces, that the given coefficient in the constraint matrix changed */
1623 static
1625  SCIP_ROW* row, /**< LP row */
1626  SCIP_COL* col, /**< LP col */
1627  SCIP_LP* lp /**< current LP data */
1628  )
1629 {
1630  assert(row != NULL);
1631  assert(col != NULL);
1632  assert(lp != NULL);
1633 
1634  if( row->lpipos >= 0 && col->lpipos >= 0 )
1635  {
1636  assert(row->lpipos < lp->nlpirows);
1637  assert(col->lpipos < lp->nlpicols);
1638 
1639  /* we have to remember the change only in the row or in the column,
1640  * because the readdition of one vector would change the other automatically.
1641  */
1642  if( row->lpipos >= lp->lpifirstchgrow )
1643  row->coefchanged = TRUE;
1644  else if( col->lpipos >= lp->lpifirstchgcol )
1645  col->coefchanged = TRUE;
1646  else if( lp->lpifirstchgrow - row->lpipos <= lp->lpifirstchgcol - col->lpipos )
1647  {
1648  row->coefchanged = TRUE;
1649  lp->lpifirstchgrow = row->lpipos;
1650  }
1651  else
1652  {
1653  col->coefchanged = TRUE;
1654  lp->lpifirstchgcol = col->lpipos;
1655  }
1656 
1657  /* mark the current LP unflushed */
1658  lp->flushed = FALSE;
1659  }
1660 
1662  row->minactivity = SCIP_INVALID;
1663  row->maxactivity = SCIP_INVALID;
1664  row->validpsactivitydomchg = -1;
1665  row->validactivitybdsdomchg = -1;
1666 }
1667 
1668 
1669 
1670 /*
1671  * local column changing methods
1672  */
1673 
1674 /* forward declaration for colAddCoef() */
1675 static
1677  SCIP_ROW* row, /**< LP row */
1678  BMS_BLKMEM* blkmem, /**< block memory */
1679  SCIP_SET* set, /**< global SCIP settings */
1680  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1681  SCIP_LP* lp, /**< current LP data */
1682  SCIP_COL* col, /**< LP column */
1683  SCIP_Real val, /**< value of coefficient */
1684  int linkpos /**< position of row in the column's row array, or -1 */
1685  );
1686 
1687 /** adds a previously non existing coefficient to an LP column */
1688 static
1690  SCIP_COL* col, /**< LP column */
1691  BMS_BLKMEM* blkmem, /**< block memory */
1692  SCIP_SET* set, /**< global SCIP settings */
1693  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1694  SCIP_LP* lp, /**< current LP data */
1695  SCIP_ROW* row, /**< LP row */
1696  SCIP_Real val, /**< value of coefficient */
1697  int linkpos /**< position of column in the row's col array, or -1 */
1698  )
1699 {
1700  int pos;
1701 
1702  assert(blkmem != NULL);
1703  assert(col != NULL);
1704  assert(col->nlprows <= col->len);
1705  assert(col->var != NULL);
1706  assert(row != NULL);
1707  assert(!SCIPsetIsZero(set, val));
1708  /*assert(colSearchCoef(col, row) == -1);*/ /* this assert would lead to slight differences in the solution process */
1709 
1710  SCIP_CALL( colEnsureSize(col, blkmem, set, col->len+1) );
1711  assert(col->rows != NULL);
1712  assert(col->vals != NULL);
1713  assert(col->linkpos != NULL);
1714 
1715  pos = col->len;
1716  col->len++;
1717 
1718  /* if the row is in current LP and is linked to the column, we have to insert it at the end of the linked LP rows
1719  * part of the column's arrays
1720  */
1721  if( row->lppos >= 0 && linkpos >= 0 )
1722  {
1723  /* move the first non-LP/not linked row to the end */
1724  if( col->nlprows < pos )
1725  {
1726  colMoveCoef(col, col->nlprows, pos);
1727  pos = col->nlprows;
1728  }
1729  col->nlprows++;
1730  }
1731 
1732  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1733  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1734 
1735  /* insert the row at the correct position and update the links */
1736  col->rows[pos] = row;
1737  col->vals[pos] = val;
1738  col->linkpos[pos] = linkpos;
1739  if( linkpos == -1 )
1740  {
1741  col->nunlinked++;
1742 
1743  /* if the column is in current LP, we have to link it to the row, because otherwise, the primal information
1744  * of the row is not complete
1745  */
1746  if( col->lppos >= 0 )
1747  {
1748  /* this call might swap the current row with the first non-LP/not linked row, s.t. insertion position
1749  * has to be updated
1750  */
1751  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, pos) );
1752  if( row->lppos >= 0 )
1753  pos = col->nlprows-1;
1754  linkpos = col->linkpos[pos];
1755 
1756  assert(0 <= linkpos && linkpos < row->len);
1757  assert(row->cols[linkpos] == col);
1758  assert(col->rows[pos] == row);
1759  assert(col->rows[pos]->cols[col->linkpos[pos]] == col);
1760  assert(col->rows[pos]->linkpos[col->linkpos[pos]] == pos);
1761  }
1762  }
1763  else
1764  {
1765  assert(row->linkpos[linkpos] == -1);
1766  assert(row->nunlinked > 0);
1767  row->linkpos[linkpos] = pos;
1768  row->nunlinked--;
1769 
1770  /* if the column is in current LP, now both conditions, row->cols[linkpos]->lppos >= 0 and row->linkpos[linkpos] >= 0
1771  * hold, so we have to move the column to the linked LP-cols part of the row's cols array
1772  */
1773  if( col->lppos >= 0 )
1774  {
1775  row->nlpcols++;
1776  rowSwapCoefs(row, linkpos, row->nlpcols-1);
1777 
1778  /* if no swap was necessary, mark nonlpcols to be unsorted */
1779  if( linkpos == row->nlpcols-1 )
1780  row->lpcolssorted = FALSE;
1781  }
1782  }
1783 
1784  /* update the sorted flags */
1785  if( row->lppos >= 0 && linkpos >= 0 )
1786  {
1787  assert(col->nlprows >= 1);
1788  assert(col->rows[col->nlprows-1] == row);
1789  if( col->nlprows > 1 )
1790  col->lprowssorted = col->lprowssorted && (col->rows[col->nlprows-2]->index < row->index);
1791  }
1792  else
1793  {
1794  assert(col->len - col->nlprows >= 1);
1795  assert(col->rows[col->len-1] == row);
1796  if( col->len - col->nlprows > 1 )
1797  col->nonlprowssorted = col->nonlprowssorted && (col->rows[col->len-2]->index < row->index);
1798  }
1799 
1800  coefChanged(row, col, lp);
1801 
1802  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to column <%s> (nunlinked=%d)\n",
1803  val, row->name, pos, col->nlprows, col->len, SCIPvarGetName(col->var), col->nunlinked);
1804 
1805  return SCIP_OKAY;
1806 }
1807 
1808 /** deletes coefficient at given position from column */
1809 static
1811  SCIP_COL* col, /**< column to be changed */
1812  SCIP_SET* set, /**< global SCIP settings */
1813  SCIP_LP* lp, /**< current LP data */
1814  int pos /**< position in column vector to delete */
1815  )
1816 {
1817  SCIP_ROW* row;
1818 
1819  assert(col != NULL);
1820  assert(col->var != NULL);
1821  assert(set != NULL);
1822  assert(0 <= pos && pos < col->len);
1823  assert(col->rows[pos] != NULL);
1824  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1825  assert((pos < col->nlprows) == (col->linkpos[pos] >= 0 && col->rows[pos]->lppos >= 0));
1826 
1827  row = col->rows[pos];
1828  assert((row->lppos >= 0) == (pos < col->nlprows));
1829 
1830  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from column <%s>\n",
1831  col->vals[pos], row->name, pos, SCIPvarGetName(col->var));*/
1832 
1833  if( col->linkpos[pos] == -1 )
1834  col->nunlinked--;
1835 
1836  /* if row is a linked LP row, move last linked LP coefficient to position of empty slot (deleted coefficient) */
1837  if( pos < col->nlprows )
1838  {
1839  colMoveCoef(col, col->nlprows-1, pos);
1840  col->nlprows--;
1841  pos = col->nlprows;
1842  }
1843 
1844  /* move last coefficient to position of empty slot */
1845  colMoveCoef(col, col->len-1, pos);
1846  col->len--;
1847 
1848  coefChanged(row, col, lp);
1849 
1850  return SCIP_OKAY;
1851 }
1852 
1853 /** changes a coefficient at given position of an LP column */
1854 static
1856  SCIP_COL* col, /**< LP column */
1857  SCIP_SET* set, /**< global SCIP settings */
1858  SCIP_LP* lp, /**< current LP data */
1859  int pos, /**< position in column vector to change */
1860  SCIP_Real val /**< value of coefficient */
1861  )
1862 {
1863  assert(col != NULL);
1864  assert(col->var != NULL);
1865  assert(0 <= pos && pos < col->len);
1866  assert(col->rows[pos] != NULL);
1867  assert(col->linkpos[pos] == -1 || col->rows[pos]->cols[col->linkpos[pos]] == col);
1868 
1869  /*debugMsg(scip, "changing coefficient %g * <%s> at position %d of column <%s> to %g\n",
1870  col->vals[pos], col->rows[pos]->name, pos, SCIPvarGetName(col->var), val);*/
1871 
1872  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
1873  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
1874 
1875  if( SCIPsetIsZero(set, val) )
1876  {
1877  /* delete existing coefficient */
1878  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
1879  }
1880  else if( !SCIPsetIsEQ(set, col->vals[pos], val) )
1881  {
1882  /* change existing coefficient */
1883  col->vals[pos] = val;
1884  coefChanged(col->rows[pos], col, lp);
1885  }
1886 
1887  return SCIP_OKAY;
1888 }
1889 
1890 
1891 
1892 
1893 /*
1894  * local row changing methods
1895  */
1896 
1897 /** update row norms after addition of coefficient */
1898 static
1900  SCIP_ROW* row, /**< LP row */
1901  SCIP_SET* set, /**< global SCIP settings */
1902  SCIP_COL* col, /**< column of added coefficient */
1903  SCIP_Real val, /**< value of added coefficient */
1904  SCIP_Bool updateidxvals /**< update min/max idx and min/max val? */
1905  )
1906 {
1907  SCIP_Real absval;
1908 
1909  assert(row != NULL);
1910  assert(row->nummaxval >= 0);
1911  assert(row->numminval >= 0);
1912  assert(set != NULL);
1913  assert(col != NULL);
1914 
1915  absval = REALABS(val);
1916  assert(!SCIPsetIsZero(set, absval));
1917 
1918  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
1919  if( col->lppos >= 0 )
1920  {
1921  /* update squared Euclidean norm and sum norm */
1922  row->sqrnorm += SQR(absval);
1923  row->sumnorm += absval;
1924 
1925  /* update objective function scalar product */
1926  row->objprod += val * col->unchangedobj;
1927  }
1928 
1929  if( updateidxvals )
1930  {
1931  /* update min/maxidx */
1932  row->minidx = MIN(row->minidx, col->index);
1933  row->maxidx = MAX(row->maxidx, col->index);
1934 
1935  /* update maximal and minimal non-zero value */
1936  if( row->nummaxval > 0 )
1937  {
1938  if( SCIPsetIsGT(set, absval, row->maxval) )
1939  {
1940  row->maxval = absval;
1941  row->nummaxval = 1;
1942  }
1943  else if( SCIPsetIsGE(set, absval, row->maxval) )
1944  {
1945  /* make sure the maxval is always exactly the same */
1946  row->maxval = MAX(absval, row->maxval);
1947  row->nummaxval++;
1948  }
1949  }
1950  if( row->numminval > 0 )
1951  {
1952  if( SCIPsetIsLT(set, absval, row->minval) )
1953  {
1954  row->minval = absval;
1955  row->numminval = 1;
1956  }
1957  else if( SCIPsetIsLE(set, absval, row->minval) )
1958  {
1959  /* make sure the minval is always exactly the same */
1960  row->minval = MIN(absval, row->minval);
1961  row->numminval++;
1962  }
1963  }
1964  }
1965  else
1966  {
1967  assert(row->minidx <= col->index);
1968  assert(row->maxidx >= col->index);
1969  assert(row->numminval <= 0 || absval >= row->minval);
1970  assert(row->nummaxval <= 0 || absval <= row->maxval);
1971  }
1972 }
1973 
1974 /** update row norms after deletion of coefficient */
1975 static
1977  SCIP_ROW* row, /**< LP row */
1978  SCIP_SET* set, /**< global SCIP settings */
1979  SCIP_COL* col, /**< column of deleted coefficient */
1980  SCIP_Real val, /**< value of deleted coefficient */
1981  SCIP_Bool forcenormupdate, /**< should the norms be updated even if lppos of column is -1? */
1982  SCIP_Bool updateindex, /**< should the minimal/maximal column index of row be updated? */
1983  SCIP_Bool updateval /**< should the minimal/maximal value of row be updated? */
1984  )
1985 {
1986  SCIP_Real absval;
1987 
1988  assert(row != NULL);
1989  assert(row->nummaxval >= 0);
1990  assert(row->numminval >= 0);
1991  assert(set != NULL);
1992  assert(col != NULL);
1993 
1994  absval = REALABS(val);
1995  assert(!SCIPsetIsZero(set, absval));
1996  assert(row->nummaxval == 0 || row->maxval >= absval);
1997  assert(row->numminval == 0 || row->minval <= absval);
1998 
1999  /* update min/maxidx validity */
2000  if( updateindex && (col->index == row->minidx || col->index == row->maxidx) )
2001  row->validminmaxidx = FALSE;
2002 
2003  /* Euclidean norm, sum norm, and objective function scalar product only take LP columns into account */
2004  if( forcenormupdate || col->lppos >= 0 )
2005  {
2006  /* update squared Euclidean norm and sum norm */
2007  row->sqrnorm -= SQR(absval);
2008  row->sqrnorm = MAX(row->sqrnorm, 0.0);
2009  row->sumnorm -= absval;
2010  row->sumnorm = MAX(row->sumnorm, 0.0);
2011 
2012  /* update objective function scalar product */
2013  row->objprod -= val * col->unchangedobj;
2014  }
2015 
2016  if( updateval )
2017  {
2018  /* update maximal and minimal non-zero value */
2019  if( row->nummaxval > 0 )
2020  {
2021  if( SCIPsetIsGE(set, absval, row->maxval) )
2022  row->nummaxval--;
2023  }
2024  if( row->numminval > 0 )
2025  {
2026  if( SCIPsetIsLE(set, absval, row->minval) )
2027  row->numminval--;
2028  }
2029  }
2030 }
2031 
2032 /** adds a previously non existing coefficient to an LP row */
2033 static
2035  SCIP_ROW* row, /**< LP row */
2036  BMS_BLKMEM* blkmem, /**< block memory */
2037  SCIP_SET* set, /**< global SCIP settings */
2038  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2039  SCIP_LP* lp, /**< current LP data */
2040  SCIP_COL* col, /**< LP column */
2041  SCIP_Real val, /**< value of coefficient */
2042  int linkpos /**< position of row in the column's row array, or -1 */
2043  )
2044 {
2045  int pos;
2046 
2047  assert(row != NULL);
2048  assert(row->nlpcols <= row->len);
2049  assert(blkmem != NULL);
2050  assert(col != NULL);
2051  assert(col->var != NULL);
2052  assert(col->var_probindex == SCIPvarGetProbindex(col->var));
2053  assert(!SCIPsetIsZero(set, val));
2054  /*assert(rowSearchCoef(row, col) == -1);*/ /* this assert would lead to slight differences in the solution process */
2055 
2056  if( row->nlocks > 0 )
2057  {
2058  SCIPerrorMessage("cannot add a coefficient to the locked unmodifiable row <%s>\n", row->name);
2059  return SCIP_INVALIDDATA;
2060  }
2061 
2062  SCIP_CALL( SCIProwEnsureSize(row, blkmem, set, row->len+1) );
2063  assert(row->cols != NULL);
2064  assert(row->vals != NULL);
2065 
2066  pos = row->len;
2067  row->len++;
2068 
2069  /* if the column is in current LP and is linked to the row, we have to insert it at the end of the linked LP columns
2070  * part of the row's arrays
2071  */
2072  if( col->lppos >= 0 && linkpos >= 0 )
2073  {
2074  /* move the first non-LP/not linked column to the end */
2075  if( row->nlpcols < pos )
2076  {
2077  rowMoveCoef(row, row->nlpcols, pos);
2078  pos = row->nlpcols;
2079  }
2080  row->nlpcols++;
2081  }
2082 
2083  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2084  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2085 
2086  /* insert the column at the correct position and update the links */
2087  row->cols[pos] = col;
2088  row->cols_index[pos] = col->index;
2089  row->vals[pos] = val;
2090  row->linkpos[pos] = linkpos;
2091  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2092  if( linkpos == -1 )
2093  {
2094  row->nunlinked++;
2095 
2096  /* if the row is in current LP, we have to link it to the column, because otherwise, the dual information
2097  * of the column is not complete
2098  */
2099  if( row->lppos >= 0 )
2100  {
2101  /* this call might swap the current column with the first non-LP/not linked column, s.t. insertion position
2102  * has to be updated
2103  */
2104  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, pos) );
2105  if( col->lppos >= 0 )
2106  pos = row->nlpcols-1;
2107  linkpos = row->linkpos[pos];
2108 
2109  assert(0 <= linkpos && linkpos < col->len);
2110  assert(col->rows[linkpos] == row);
2111  assert(row->cols[pos] == col);
2112  assert(row->cols[pos]->rows[row->linkpos[pos]] == row);
2113  assert(row->cols[pos]->linkpos[row->linkpos[pos]] == pos);
2114  }
2115  }
2116  else
2117  {
2118  assert(col->linkpos[linkpos] == -1);
2119  assert(col->nunlinked > 0);
2120  col->linkpos[linkpos] = pos;
2121  col->nunlinked--;
2122 
2123  /* if the row is in current LP, now both conditions, col->rows[linkpos]->lppos >= 0 and col->linkpos[linkpos] >= 0
2124  * hold, so we have to move the row to the linked LP-rows part of the column's rows array
2125  */
2126  if( row->lppos >= 0 )
2127  {
2128  col->nlprows++;
2129  colSwapCoefs(col, linkpos, col->nlprows-1);
2130 
2131  /* if no swap was necessary, mark lprows to be unsorted */
2132  if( linkpos == col->nlprows-1 )
2133  col->lprowssorted = FALSE;
2134  }
2135  }
2136 
2137  /* update the sorted flags */
2138  if( col->lppos >= 0 && linkpos >= 0 )
2139  {
2140  assert(row->nlpcols >= 1);
2141  assert(row->cols[row->nlpcols-1] == col);
2142  if( row->nlpcols > 1 )
2143  {
2144  assert(row->cols_index[row->nlpcols-2] == row->cols[row->nlpcols-2]->index);
2145  row->lpcolssorted = row->lpcolssorted && (row->cols_index[row->nlpcols-2] < col->index);
2146  }
2147  }
2148  else
2149  {
2150  assert(row->len - row->nlpcols >= 1);
2151  assert(row->cols[row->len-1] == col);
2152  if( row->len - row->nlpcols > 1 )
2153  {
2154  assert(row->cols_index[row->len-2] == row->cols[row->len-2]->index);
2155  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[row->len-2] < col->index);
2156  }
2157  }
2158 
2159  /* update row norm */
2160  rowAddNorms(row, set, col, val, TRUE);
2161 
2162  coefChanged(row, col, lp);
2163 
2164  SCIPsetDebugMsg(set, "added coefficient %g * <%s> at position %d (%d/%d) to row <%s> (nunlinked=%d)\n",
2165  val, SCIPvarGetName(col->var), pos, row->nlpcols, row->len, row->name, row->nunlinked);
2166 
2167  /* issue row coefficient changed event */
2168  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, 0.0, val) );
2169 
2170  return SCIP_OKAY;
2171 }
2172 
2173 /** deletes coefficient at given position from row */
2174 static
2176  SCIP_ROW* row, /**< row to be changed */
2177  BMS_BLKMEM* blkmem, /**< block memory */
2178  SCIP_SET* set, /**< global SCIP settings */
2179  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2180  SCIP_LP* lp, /**< current LP data */
2181  int pos /**< position in row vector to delete */
2182  )
2183 {
2184  SCIP_COL* col;
2185  SCIP_Real val;
2186 
2187  assert(row != NULL);
2188  assert(set != NULL);
2189  assert(0 <= pos && pos < row->len);
2190  assert(row->cols[pos] != NULL);
2191  assert((pos < row->nlpcols) == (row->linkpos[pos] >= 0 && row->cols[pos]->lppos >= 0));
2192 
2193  col = row->cols[pos];
2194  val = row->vals[pos];
2195  assert((pos < row->nlpcols) == (col->lppos >= 0 && row->linkpos[pos] >= 0));
2196 
2197  /*SCIPsetDebugMsg(set, "deleting coefficient %g * <%s> at position %d from row <%s>\n",
2198  val, SCIPvarGetName(col->var), pos, row->name);*/
2199 
2200  if( row->nlocks > 0 )
2201  {
2202  SCIPerrorMessage("cannot delete a coefficient from the locked unmodifiable row <%s>\n", row->name);
2203  return SCIP_INVALIDDATA;
2204  }
2205 
2206  if( row->linkpos[pos] == -1 )
2207  row->nunlinked--;
2208 
2209  /* if column is a linked LP column, move last linked LP coefficient to position of empty slot (deleted coefficient) */
2210  if( pos < row->nlpcols )
2211  {
2212  rowMoveCoef(row, row->nlpcols-1, pos);
2213  assert(!row->lpcolssorted);
2214  row->nlpcols--;
2215  pos = row->nlpcols;
2216  }
2217 
2218  /* move last coefficient to position of empty slot */
2219  rowMoveCoef(row, row->len-1, pos);
2220  row->len--;
2221 
2222  /* update norms */
2223  rowDelNorms(row, set, col, val, FALSE, TRUE, TRUE);
2224 
2225  coefChanged(row, col, lp);
2226 
2227  /* issue row coefficient changed event */
2228  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, val, 0.0) );
2229 
2230  return SCIP_OKAY;
2231 }
2232 
2233 /** changes a coefficient at given position of an LP row */
2234 static
2236  SCIP_ROW* row, /**< LP row */
2237  BMS_BLKMEM* blkmem, /**< block memory */
2238  SCIP_SET* set, /**< global SCIP settings */
2239  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2240  SCIP_LP* lp, /**< current LP data */
2241  int pos, /**< position in row vector to change */
2242  SCIP_Real val /**< value of coefficient */
2243  )
2244 {
2245  SCIP_COL* col;
2246 
2247  assert(row != NULL);
2248  assert(0 <= pos && pos < row->len);
2249 
2250  /*SCIPsetDebugMsg(set, "changing coefficient %g * <%s> at position %d of row <%s> to %g\n",
2251  row->vals[pos], SCIPvarGetName(row->cols[pos]->var), pos, row->name, val);*/
2252 
2253  if( row->nlocks > 0 )
2254  {
2255  SCIPerrorMessage("cannot change a coefficient of the locked unmodifiable row <%s>\n", row->name);
2256  return SCIP_INVALIDDATA;
2257  }
2258 
2259  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
2260  val = SCIPsetIsIntegral(set, val) ? SCIPsetRound(set, val) : val;
2261  col = row->cols[pos];
2262  assert(row->cols[pos] != NULL);
2263 
2264  if( SCIPsetIsZero(set, val) )
2265  {
2266  /* delete existing coefficient */
2267  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
2268  }
2269  else if( !SCIPsetIsEQ(set, row->vals[pos], val) )
2270  {
2271  SCIP_Real oldval;
2272 
2273  oldval = row->vals[pos];
2274 
2275  /* change existing coefficient */
2276  rowDelNorms(row, set, col, row->vals[pos], FALSE, FALSE, TRUE);
2277  row->vals[pos] = val;
2278  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
2279  rowAddNorms(row, set, col, row->vals[pos], TRUE);
2280  coefChanged(row, col, lp);
2281 
2282  /* issue row coefficient changed event */
2283  SCIP_CALL( rowEventCoefChanged(row, blkmem, set, eventqueue, col, oldval, val) );
2284  }
2285 
2286  return SCIP_OKAY;
2287 }
2288 
2289 /** notifies LP row, that its sides were changed */
2290 static
2292  SCIP_ROW* row, /**< LP row */
2293  SCIP_SET* set, /**< global SCIP settings */
2294  SCIP_LP* lp, /**< current LP data */
2295  SCIP_SIDETYPE sidetype /**< type of side: left or right hand side */
2296  )
2297 {
2298  assert(row != NULL);
2299  assert(lp != NULL);
2300 
2301  if( row->lpipos >= 0 )
2302  {
2303  /* insert row in the chgrows list (if not already there) */
2304  if( !row->lhschanged && !row->rhschanged )
2305  {
2306  SCIP_CALL( ensureChgrowsSize(lp, set, lp->nchgrows+1) );
2307  lp->chgrows[lp->nchgrows] = row;
2308  lp->nchgrows++;
2309  }
2310 
2311  /* mark side change in the row */
2312  switch( sidetype )
2313  {
2314  case SCIP_SIDETYPE_LEFT:
2315  row->lhschanged = TRUE;
2316  break;
2317  case SCIP_SIDETYPE_RIGHT:
2318  row->rhschanged = TRUE;
2319  break;
2320  default:
2321  SCIPerrorMessage("unknown row side type\n");
2322  SCIPABORT();
2323  return SCIP_INVALIDDATA; /*lint !e527*/
2324  }
2325 
2326  /* mark the current LP unflushed */
2327  lp->flushed = FALSE;
2328 
2329  assert(lp->nchgrows > 0);
2330  }
2331 
2332  return SCIP_OKAY;
2333 }
2334 
2335 
2336 
2337 
2338 /*
2339  * double linked coefficient matrix methods
2340  */
2341 
2342 /** insert column coefficients in corresponding rows */
2343 static
2345  SCIP_COL* col, /**< column data */
2346  BMS_BLKMEM* blkmem, /**< block memory */
2347  SCIP_SET* set, /**< global SCIP settings */
2348  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2349  SCIP_LP* lp /**< current LP data */
2350  )
2351 {
2352  int i;
2353 
2354  assert(col != NULL);
2355  assert(col->var != NULL);
2356  assert(blkmem != NULL);
2357  assert(set != NULL);
2358  assert(lp != NULL);
2359 
2360  if( col->nunlinked > 0 )
2361  {
2362  SCIPsetDebugMsg(set, "linking column <%s>\n", SCIPvarGetName(col->var));
2363 
2364  /* unlinked rows can only be in the non-LP/unlinked rows part of the rows array */
2365  for( i = col->nlprows; i < col->len; ++i )
2366  {
2367  assert(!SCIPsetIsZero(set, col->vals[i]));
2368  if( col->linkpos[i] == -1 )
2369  {
2370  /* this call might swap the current row with the first non-LP/not linked row, but this is of no harm */
2371  SCIP_CALL( rowAddCoef(col->rows[i], blkmem, set, eventqueue, lp, col, col->vals[i], i) );
2372  }
2373  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2374  assert(col->rows[i]->linkpos[col->linkpos[i]] == i);
2375  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->cols[col->linkpos[col->nlprows-1]] == col);
2376  assert(col->nlprows == 0 || col->rows[col->nlprows-1]->linkpos[col->linkpos[col->nlprows-1]] == col->nlprows-1);
2377  }
2378  }
2379  assert(col->nunlinked == 0);
2380 
2381  checkLinks(lp);
2382 
2383  return SCIP_OKAY;
2384 }
2385 
2386 /** removes column coefficients from corresponding rows */
2387 static
2389  SCIP_COL* col, /**< column data */
2390  BMS_BLKMEM* blkmem, /**< block memory */
2391  SCIP_SET* set, /**< global SCIP settings */
2392  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2393  SCIP_LP* lp /**< current LP data */
2394  )
2395 {
2396  int i;
2397 
2398  assert(col != NULL);
2399  assert(col->var != NULL);
2400  assert(blkmem != NULL);
2401  assert(set != NULL);
2402  assert(lp != NULL);
2403 
2404  if( col->nunlinked < col->len )
2405  {
2406  SCIPsetDebugMsg(set, "unlinking column <%s>\n", SCIPvarGetName(col->var));
2407  for( i = 0; i < col->len; ++i )
2408  {
2409  if( col->linkpos[i] >= 0 )
2410  {
2411  assert(col->rows[i]->cols[col->linkpos[i]] == col);
2412  SCIP_CALL( rowDelCoefPos(col->rows[i], blkmem, set, eventqueue, lp, col->linkpos[i]) );
2413  col->linkpos[i] = -1;
2414  col->nunlinked++;
2415  }
2416  }
2417  }
2418  assert(col->nunlinked == col->len);
2419 
2420  checkLinks(lp);
2421 
2422  return SCIP_OKAY;
2423 }
2424 
2425 /** insert row coefficients in corresponding columns */
2426 static
2428  SCIP_ROW* row, /**< row data */
2429  BMS_BLKMEM* blkmem, /**< block memory */
2430  SCIP_SET* set, /**< global SCIP settings */
2431  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2432  SCIP_LP* lp /**< current LP data */
2433  )
2434 {
2435  int i;
2436 
2437  assert(row != NULL);
2438  assert(blkmem != NULL);
2439  assert(set != NULL);
2440  assert(lp != NULL);
2441 
2442  if( row->nunlinked > 0 )
2443  {
2444  SCIPsetDebugMsg(set, "linking row <%s>\n", row->name);
2445 
2446  /* unlinked columns can only be in the non-LP/unlinked columns part of the cols array */
2447  for( i = row->nlpcols; i < row->len; ++i )
2448  {
2449  assert(!SCIPsetIsZero(set, row->vals[i]));
2450  if( row->linkpos[i] == -1 )
2451  {
2452  /* this call might swap the current column with the first non-LP/not linked column, but this is of no harm */
2453  SCIP_CALL( colAddCoef(row->cols[i], blkmem, set, eventqueue, lp, row, row->vals[i], i) );
2454  }
2455  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2456  assert(row->cols[i]->linkpos[row->linkpos[i]] == i);
2457  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->rows[row->linkpos[row->nlpcols-1]] == row);
2458  assert(row->nlpcols == 0 || row->cols[row->nlpcols-1]->linkpos[row->linkpos[row->nlpcols-1]] == row->nlpcols-1);
2459  }
2460  }
2461  assert(row->nunlinked == 0);
2462 
2463  checkLinks(lp);
2464 
2465  return SCIP_OKAY;
2466 }
2467 
2468 /** removes row coefficients from corresponding columns */
2469 static
2471  SCIP_ROW* row, /**< row data */
2472  SCIP_SET* set, /**< global SCIP settings */
2473  SCIP_LP* lp /**< current LP data */
2474  )
2475 {
2476  int i;
2477 
2478  assert(row != NULL);
2479  assert(set != NULL);
2480  assert(lp != NULL);
2481 
2482  if( row->nunlinked < row->len )
2483  {
2484  SCIPsetDebugMsg(set, "unlinking row <%s>\n", row->name);
2485  for( i = 0; i < row->len; ++i )
2486  {
2487  if( row->linkpos[i] >= 0 )
2488  {
2489  assert(row->cols[i]->rows[row->linkpos[i]] == row);
2490  SCIP_CALL( colDelCoefPos(row->cols[i], set, lp, row->linkpos[i]) );
2491  row->nunlinked++;
2492  }
2493  }
2494  }
2495  assert(row->nunlinked == row->len);
2496 
2497  return SCIP_OKAY;
2498 }
2499 
2500 
2501 
2502 
2503 /*
2504  * local LP parameter methods
2505  */
2506 
2507 /** sets parameter of type int in LP solver, ignoring unknown parameters */
2508 static
2510  SCIP_LP* lp, /**< current LP data */
2511  SCIP_LPPARAM lpparam, /**< LP parameter */
2512  int value, /**< value to set parameter to */
2513  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2514  )
2515 {
2516  SCIP_RETCODE retcode;
2517 
2518  assert(lp != NULL);
2519  assert(success != NULL);
2520 
2521  retcode = SCIPlpiSetIntpar(lp->lpi, lpparam, value);
2522 
2523  /* check, if parameter is unknown */
2524  if( retcode == SCIP_PARAMETERUNKNOWN )
2525  {
2526  *success = FALSE;
2527  return SCIP_OKAY;
2528  }
2529  *success = TRUE;
2530 
2531  return retcode;
2532 }
2533 
2534 /** sets parameter of type SCIP_Bool in LP solver, ignoring unknown parameters */
2535 static
2537  SCIP_LP* lp, /**< current LP data */
2538  SCIP_LPPARAM lpparam, /**< LP parameter */
2539  SCIP_Bool value, /**< value to set parameter to */
2540  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2541  )
2542 {
2543  return lpSetIntpar(lp, lpparam, (int)value, success);
2544 }
2545 
2546 /** sets parameter of type SCIP_Real in LP solver, ignoring unknown parameters */
2547 static
2549  SCIP_LP* lp, /**< current LP data */
2550  SCIP_LPPARAM lpparam, /**< LP parameter */
2551  SCIP_Real value, /**< value to set parameter to */
2552  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2553  )
2554 {
2555  SCIP_RETCODE retcode;
2556 
2557  assert(lp != NULL);
2558  assert(success != NULL);
2559 
2560  retcode = SCIPlpiSetRealpar(lp->lpi, lpparam, value);
2561 
2562  /* check, if parameter is unknown */
2563  if( retcode == SCIP_PARAMETERUNKNOWN )
2564  {
2565  *success = FALSE;
2566  return SCIP_OKAY;
2567  }
2568  *success = TRUE;
2569 
2570  return retcode;
2571 }
2572 
2573 #ifndef NDEBUG
2574 /** checks, that parameter of type int in LP solver has the given value, ignoring unknown parameters */
2575 static
2577  SCIP_LP* lp, /**< current LP data */
2578  SCIP_LPPARAM lpparam, /**< LP parameter */
2579  int value /**< value parameter should have */
2580  )
2581 {
2582  SCIP_RETCODE retcode;
2583  int lpivalue;
2584 
2585  assert(lp != NULL);
2586 
2587  retcode = SCIPlpiGetIntpar(lp->lpi, lpparam, &lpivalue);
2588 
2589  /* ignore unknown parameter error */
2590  if( retcode == SCIP_PARAMETERUNKNOWN )
2591  return SCIP_OKAY;
2592 
2593  /* check value */
2594  assert(lpivalue == value);
2595 
2596  return retcode;
2597 }
2598 
2599 /** checks, that parameter of type SCIP_Bool in LP solver has the given value, ignoring unknown parameters */
2600 static
2602  SCIP_LP* lp, /**< current LP data */
2603  SCIP_LPPARAM lpparam, /**< LP parameter */
2604  SCIP_Bool value /**< value parameter should have */
2605  )
2606 {
2607  return lpCheckIntpar(lp, lpparam, (int)value);
2608 }
2609 
2610 /** checks, that parameter of type SCIP_Real in LP solver has the given value, ignoring unknown parameters */
2611 static
2613  SCIP_LP* lp, /**< current LP data */
2614  SCIP_LPPARAM lpparam, /**< LP parameter */
2615  SCIP_Real value /**< value parameter should have */
2616  )
2617 {
2618  SCIP_RETCODE retcode;
2619  SCIP_Real lpivalue;
2620 
2621  assert(lp != NULL);
2622 
2623  retcode = SCIPlpiGetRealpar(lp->lpi, lpparam, &lpivalue);
2624 
2625  /* ignore unknown parameter error */
2626  if( retcode == SCIP_PARAMETERUNKNOWN )
2627  return SCIP_OKAY;
2628 
2629  /* check value */
2630  assert(lpivalue == value); /*lint !e777*/
2631 
2632  return retcode;
2633 }
2634 #else
2635 #define lpCheckIntpar(lp, lpparam, value) SCIP_OKAY
2636 #define lpCheckBoolpar(lp, lpparam, value) SCIP_OKAY
2637 #define lpCheckRealpar(lp, lpparam, value) SCIP_OKAY
2638 #endif
2639 
2640 /** should the objective limit of the LP solver be disabled */
2641 #define lpCutoffDisabled(set,prob) (set->lp_disablecutoff == 1 || ((set->nactivepricers > 0 || !SCIPprobAllColsInLP(prob, set, lp)) && 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_PROB* prob, /**< problem data */
2652  SCIP_Real objlim, /**< new objective limit */
2653  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2654  )
2655 {
2656  assert(lp != NULL);
2657  assert(set != NULL);
2658  assert(success != NULL);
2659 
2660  *success = FALSE;
2661 
2662  /* We disabled the objective limit in the LP solver or we want so solve exactly and thus cannot rely on the LP
2663  * solver's objective limit handling, so we make sure that the objective limit is inactive (infinity). */
2664  if( lpCutoffDisabled(set, prob) || set->misc_exactsolve )
2665  objlim = SCIPlpiInfinity(lp->lpi);
2666 
2667  /* convert SCIP infinity value to lp-solver infinity value if necessary */
2668  if( SCIPsetIsInfinity(set, objlim) )
2669  objlim = SCIPlpiInfinity(lp->lpi);
2670 
2672 
2673  if( objlim != lp->lpiobjlim ) /*lint !e777*/
2674  {
2675  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_OBJLIM, objlim, success) );
2676  if( *success )
2677  {
2678  SCIP_Real actualobjlim;
2679 
2680  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2681  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_OBJLIM, &actualobjlim) );
2682  if( actualobjlim != lp->lpiobjlim ) /*lint !e777*/
2683  {
2684  /* mark the current solution invalid */
2685  lp->solved = FALSE;
2686  lp->primalfeasible = FALSE;
2687  lp->primalchecked = FALSE;
2688  lp->lpobjval = SCIP_INVALID;
2690  }
2691  lp->lpiobjlim = actualobjlim;
2692  }
2693  }
2694 
2695  return SCIP_OKAY;
2696 }
2697 
2698 /** sets the feasibility tolerance of the LP solver */
2699 static
2701  SCIP_LP* lp, /**< current LP data */
2702  SCIP_Real feastol, /**< new feasibility tolerance */
2703  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2704  )
2705 {
2706  assert(lp != NULL);
2707  assert(feastol >= 0.0);
2708  assert(success != NULL);
2709 
2711 
2712  if( feastol != lp->lpifeastol ) /*lint !e777*/
2713  {
2714  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_FEASTOL, feastol, success) );
2715  if( *success )
2716  {
2717  SCIP_Real actualfeastol;
2718 
2719  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2720  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_FEASTOL, &actualfeastol) );
2721  if( lp->nrows > 0 && actualfeastol < lp->lpifeastol )
2722  {
2723  /* mark the current solution invalid */
2724  lp->solved = FALSE;
2725  lp->primalfeasible = FALSE;
2726  lp->primalchecked = FALSE;
2727  lp->lpobjval = SCIP_INVALID;
2729  }
2730  else
2731  *success = FALSE;
2732  lp->lpifeastol = actualfeastol;
2733  }
2734  }
2735  else
2736  *success = FALSE;
2737 
2738  return SCIP_OKAY;
2739 }
2740 
2741 /** sets the reduced costs feasibility tolerance of the LP solver */
2742 static
2744  SCIP_LP* lp, /**< current LP data */
2745  SCIP_Real dualfeastol, /**< new reduced costs feasibility tolerance */
2746  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2747  )
2748 {
2749  assert(lp != NULL);
2750  assert(dualfeastol >= 0.0);
2751  assert(success != NULL);
2752 
2754 
2755  if( dualfeastol != lp->lpidualfeastol ) /*lint !e777*/
2756  {
2757  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_DUALFEASTOL, dualfeastol, success) );
2758  if( *success )
2759  {
2760  SCIP_Real actualdualfeastol;
2761 
2762  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2763  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_DUALFEASTOL, &actualdualfeastol) );
2764  if( lp->nrows > 0 && actualdualfeastol < lp->lpidualfeastol )
2765  {
2766  /* mark the current solution invalid */
2767  lp->solved = FALSE;
2768  lp->dualfeasible = FALSE;
2769  lp->dualchecked = FALSE;
2770  lp->lpobjval = SCIP_INVALID;
2772  }
2773  else
2774  *success = FALSE;
2775  lp->lpidualfeastol = actualdualfeastol;
2776  }
2777  }
2778  else
2779  *success = FALSE;
2780 
2781  return SCIP_OKAY;
2782 }
2783 
2784 /** sets the convergence tolerance used in barrier algorithm of the LP solver */
2785 static
2787  SCIP_LP* lp, /**< current LP data */
2788  SCIP_Real barrierconvtol, /**< new convergence tolerance used in barrier algorithm */
2789  SCIP_Bool* success /**< pointer to store whether the parameter was actually changed */
2790  )
2791 {
2792  assert(lp != NULL);
2793  assert(barrierconvtol >= 0.0);
2794  assert(success != NULL);
2795 
2797 
2798  if( barrierconvtol != lp->lpibarrierconvtol ) /*lint !e777*/
2799  {
2800  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_BARRIERCONVTOL, barrierconvtol, success) );
2801  if( *success )
2802  {
2803  SCIP_Real actualbarrierconvtol;
2804 
2805  /* check whether the parameter was actually changed or already was at the boundary of the LP solver's parameter range */
2806  SCIP_CALL( SCIPlpiGetRealpar(lp->lpi, SCIP_LPPAR_BARRIERCONVTOL, &actualbarrierconvtol) );
2807  if( lp->nrows > 0 && actualbarrierconvtol < lp->lpibarrierconvtol
2809  {
2810  /* mark the current solution invalid */
2811  lp->solved = FALSE;
2812  lp->dualfeasible = FALSE;
2813  lp->dualchecked = FALSE;
2814  lp->lpobjval = SCIP_INVALID;
2816  }
2817  else
2818  *success = FALSE;
2819  lp->lpibarrierconvtol = actualbarrierconvtol;
2820  }
2821  }
2822  else
2823  *success = FALSE;
2824 
2825  return SCIP_OKAY;
2826 }
2827 
2828 /** sets the FROMSCRATCH setting of the LP solver */
2829 static
2831  SCIP_LP* lp, /**< current LP data */
2832  SCIP_Bool fromscratch, /**< new FROMSCRATCH setting */
2833  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2834  )
2835 {
2836  assert(lp != NULL);
2837  assert(success != NULL);
2838 
2840 
2841  if( fromscratch != lp->lpifromscratch )
2842  {
2843  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_FROMSCRATCH, fromscratch, success) );
2844  if( *success )
2845  lp->lpifromscratch = fromscratch;
2846  }
2847  else
2848  *success = FALSE;
2849 
2850  return SCIP_OKAY;
2851 }
2852 
2853 /** sets the FASTMIP setting of the LP solver */
2854 static
2856  SCIP_LP* lp, /**< current LP data */
2857  int fastmip, /**< new FASTMIP setting */
2858  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2859  )
2860 {
2861  assert(lp != NULL);
2862  assert(success != NULL);
2863  assert(0 <= fastmip && fastmip <= 1);
2864 
2866 
2867  if( fastmip != lp->lpifastmip )
2868  {
2869  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_FASTMIP, fastmip, success) );
2870  if( *success )
2871  {
2872  lp->lpifastmip = fastmip;
2873  lp->solved = FALSE;
2874  /* We might only set lp->solved to false if fastmip is turned off, since the latter should be the more
2875  * demanding setting; however, in the current code, this should have not effect. */
2876  }
2877  }
2878  else
2879  *success = FALSE;
2880 
2881  return SCIP_OKAY;
2882 }
2883 
2884 /** sets the SCALING setting of the LP solver */
2885 static
2887  SCIP_LP* lp, /**< current LP data */
2888  int scaling, /**< new SCALING setting */
2889  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2890  )
2891 {
2892  assert(lp != NULL);
2893  assert(success != NULL);
2894 
2896 
2897  if( scaling != lp->lpiscaling )
2898  {
2899  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_SCALING, scaling, success) );
2900  if( *success )
2901  lp->lpiscaling = scaling;
2902  }
2903  else
2904  *success = FALSE;
2905 
2906  return SCIP_OKAY;
2907 }
2908 
2909 /** sets the number of THREADS of the LP solver */
2910 static
2912  SCIP_LP* lp, /**< current LP data */
2913  int threads, /**< new number of threads used to solve the LP */
2914  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2915  )
2916 {
2917  assert(lp != NULL);
2918  assert(success != NULL);
2919 
2921 
2922  if( threads != lp->lpithreads )
2923  {
2924  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_THREADS, threads, success) );
2925  if( *success )
2926  lp->lpithreads = threads;
2927  }
2928  else
2929  *success = FALSE;
2930 
2931  return SCIP_OKAY;
2932 }
2933 
2934 /** sets the PRESOLVING setting of the LP solver */
2935 static
2937  SCIP_LP* lp, /**< current LP data */
2938  SCIP_Bool presolving, /**< new PRESOLVING setting */
2939  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2940  )
2941 {
2942  assert(lp != NULL);
2943  assert(success != NULL);
2944 
2946 
2947  if( presolving != lp->lpipresolving )
2948  {
2949  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_PRESOLVING, presolving, success) );
2950  if( *success )
2951  lp->lpipresolving = presolving;
2952  }
2953  else
2954  *success = FALSE;
2955 
2956  return SCIP_OKAY;
2957 }
2958 
2959 /** sets the ROWREPSWITCH setting of the LP solver */
2960 static
2962  SCIP_LP* lp, /**< current LP data */
2963  SCIP_Real rowrepswitch, /**< new ROWREPSWITCH value */
2964  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
2965  )
2966 {
2967  assert(lp != NULL);
2968  assert(success != NULL);
2969 
2971 
2972  if( rowrepswitch != lp->lpirowrepswitch ) /*lint !e777*/
2973  {
2974  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_ROWREPSWITCH, rowrepswitch, success) );
2975  if( *success )
2976  lp->lpirowrepswitch = rowrepswitch;
2977  }
2978  else
2979  *success = FALSE;
2980 
2981  return SCIP_OKAY;
2982 }
2983 
2984 /** sets the iteration limit of the LP solver */
2985 static
2987  SCIP_LP* lp, /**< current LP data */
2988  int itlim /**< maximal number of LP iterations to perform, or -1 for no limit */
2989  )
2990 {
2991  SCIP_Bool success;
2992 
2993  assert(lp != NULL);
2994  assert(itlim >= -1);
2995 
2996  if( itlim == -1 )
2997  itlim = INT_MAX;
2998 
3000 
3001  if( itlim != lp->lpiitlim )
3002  {
3003  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_LPITLIM, itlim, &success) );
3004  if( success )
3005  {
3006  if( itlim > lp->lpiitlim )
3007  {
3008  /* mark the current solution invalid */
3009  lp->solved = FALSE;
3010  lp->lpobjval = SCIP_INVALID;
3012  }
3013  lp->lpiitlim = itlim;
3014  }
3015  }
3016 
3017  return SCIP_OKAY;
3018 }
3019 
3020 /** sets the pricing strategy of the LP solver */
3021 static
3023  SCIP_LP* lp, /**< current LP data */
3024  SCIP_PRICING pricing /**< pricing strategy */
3025  )
3026 {
3027  SCIP_Bool success;
3028 
3029  assert(lp != NULL);
3030 
3032 
3033  if( pricing != lp->lpipricing )
3034  {
3035  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_PRICING, (int)pricing, &success) );
3036  if( success )
3037  lp->lpipricing = pricing;
3038  }
3039 
3040  return SCIP_OKAY;
3041 }
3042 
3043 /** sets the pricing strategy of the LP solver (given the character representation of the strategy) */
3044 static
3046  SCIP_LP* lp, /**< current LP data */
3047  char pricingchar /**< character representing the pricing strategy */
3048  )
3049 {
3051 
3052  switch( pricingchar )
3053  {
3054  case 'l':
3055  pricing = SCIP_PRICING_LPIDEFAULT;
3056  break;
3057  case 'a':
3058  pricing = SCIP_PRICING_AUTO;
3059  break;
3060  case 'f':
3061  pricing = SCIP_PRICING_FULL;
3062  break;
3063  case 'p':
3064  pricing = SCIP_PRICING_PARTIAL;
3065  break;
3066  case 's':
3067  pricing = SCIP_PRICING_STEEP;
3068  break;
3069  case 'q':
3070  pricing = SCIP_PRICING_STEEPQSTART;
3071  break;
3072  case 'd':
3073  pricing = SCIP_PRICING_DEVEX;
3074  break;
3075  default:
3076  SCIPerrorMessage("invalid LP pricing parameter <%c>\n", pricingchar);
3077  return SCIP_INVALIDDATA;
3078  }
3079 
3080  SCIP_CALL( lpSetPricing(lp, pricing) );
3081 
3082  return SCIP_OKAY;
3083 }
3084 
3085 /** sets the verbosity of the LP solver */
3086 static
3088  SCIP_LP* lp, /**< current LP data */
3089  SCIP_Bool lpinfo /**< should the LP solver display status messages? */
3090  )
3091 {
3092  SCIP_Bool success;
3093 
3094  assert(lp != NULL);
3095 
3097 
3098  if( lpinfo != lp->lpilpinfo )
3099  {
3100  SCIP_CALL( lpSetBoolpar(lp, SCIP_LPPAR_LPINFO, lpinfo, &success) );
3101  if( success )
3102  lp->lpilpinfo = lpinfo;
3103  }
3104 
3105  return SCIP_OKAY;
3106 }
3107 
3108 /** sets the CONDITIONLIMIT setting of the LP solver */
3109 static
3111  SCIP_LP* lp, /**< current LP data */
3112  SCIP_Real condlimit, /**< new CONDITIONLIMIT value */
3113  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3114  )
3115 {
3116  assert(lp != NULL);
3117  assert(success != NULL);
3118 
3120 
3121  if( condlimit != lp->lpiconditionlimit ) /*lint !e777*/
3122  {
3123  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_CONDITIONLIMIT, condlimit, success) );
3124  if( *success )
3125  lp->lpiconditionlimit = condlimit;
3126  }
3127  else
3128  *success = FALSE;
3129 
3130  return SCIP_OKAY;
3131 }
3132 
3133 /** sets the MARKOWITZ setting of the LP solver */
3134 static
3136  SCIP_LP* lp, /**< current LP data */
3137  SCIP_Real threshhold, /**< new MARKOWITZ value */
3138  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3139  )
3140 {
3141  assert(lp != NULL);
3142  assert(success != NULL);
3143 
3145 
3146  if( threshhold != lp->lpimarkowitz ) /*lint !e777*/
3147  {
3148  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_MARKOWITZ, threshhold, success) );
3149  if( *success )
3150  lp->lpimarkowitz = threshhold;
3151  }
3152  else
3153  *success = FALSE;
3154 
3155  return SCIP_OKAY;
3156 }
3157 
3158 /** sets the type of timer of the LP solver */
3159 static
3161  SCIP_LP* lp, /**< current LP data */
3162  SCIP_CLOCKTYPE timing, /**< new timing value */
3163  SCIP_Bool enabled, /**< is timing enabled? */
3164  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3165  )
3166 {
3167  int lptiming;
3168 
3169  assert(lp != NULL);
3170  assert(success != NULL);
3171  assert((int) SCIP_CLOCKTYPE_CPU == 1 && (int) SCIP_CLOCKTYPE_WALL == 2); /*lint !e506*//*lint !e1564*/
3172 
3174 
3175  if( !enabled )
3176  lptiming = 0;
3177  else
3178  lptiming = (int) timing;
3179 
3180  if( lptiming != lp->lpitiming ) /*lint !e777*/
3181  {
3182  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_TIMING, lptiming, success) );
3183  if( *success )
3184  lp->lpitiming = lptiming;
3185  }
3186  else
3187  *success = FALSE;
3188 
3189  return SCIP_OKAY;
3190 }
3191 
3192 /** sets the initial random seed of the LP solver */
3193 static
3195  SCIP_LP* lp, /**< current LP data */
3196  int randomseed, /**< new initial random seed */
3197  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3198  )
3199 {
3200  assert(lp != NULL);
3201  assert(success != NULL);
3202 
3203  /* we don't check this parameter because SoPlex will always return its current random seed, not the initial one */
3204 
3205  if( randomseed == 0 )
3206  {
3207  lp->lpirandomseed = randomseed;
3208  *success = TRUE;
3209  }
3210  else if( randomseed != lp->lpirandomseed ) /*lint !e777*/
3211  {
3212  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_RANDOMSEED, randomseed, success) );
3213  if( *success )
3214  lp->lpirandomseed = randomseed;
3215  }
3216  else
3217  *success = FALSE;
3218 
3219  return SCIP_OKAY;
3220 }
3221 
3222 /** sets the LP solution polishing method */
3223 static
3225  SCIP_LP* lp, /**< current LP data */
3226  SCIP_Bool polishing, /**< LP solution polishing activated (0: disabled, 1: enabled) */
3227  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3228  )
3229 {
3230  assert(lp != NULL);
3231  assert(success != NULL);
3232 
3233  if( polishing != lp->lpisolutionpolishing )
3234  {
3235  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_POLISHING, (polishing ? 1 : 0), success) );
3236  if( *success )
3237  lp->lpisolutionpolishing = polishing;
3238  }
3239  else
3240  *success = FALSE;
3241 
3242  return SCIP_OKAY;
3243 }
3244 
3245 /** sets the LP refactorization interval */
3246 static
3248  SCIP_LP* lp, /**< current LP data */
3249  int refactor, /**< LP refactorization interval (0: automatic) */
3250  SCIP_Bool* success /**< pointer to store whether the parameter was successfully changed */
3251  )
3252 {
3253  assert(lp != NULL);
3254  assert(success != NULL);
3255 
3256  if( refactor != lp->lpirefactorinterval )
3257  {
3258  SCIP_CALL( lpSetIntpar(lp, SCIP_LPPAR_REFACTOR, refactor, success) );
3259  if( *success )
3260  lp->lpirefactorinterval = refactor;
3261  }
3262  else
3263  *success = FALSE;
3264 
3265  return SCIP_OKAY;
3266 }
3267 
3268 
3269 /*
3270  * Column methods
3271  */
3272 
3273 /** creates an LP column */
3275  SCIP_COL** col, /**< pointer to column data */
3276  BMS_BLKMEM* blkmem, /**< block memory */
3277  SCIP_SET* set, /**< global SCIP settings */
3278  SCIP_STAT* stat, /**< problem statistics */
3279  SCIP_VAR* var, /**< variable, this column represents */
3280  int len, /**< number of nonzeros in the column */
3281  SCIP_ROW** rows, /**< array with rows of column entries */
3282  SCIP_Real* vals, /**< array with coefficients of column entries */
3283  SCIP_Bool removable /**< should the column be removed from the LP due to aging or cleanup? */
3284  )
3285 {
3286  int i;
3287 
3288  assert(col != NULL);
3289  assert(blkmem != NULL);
3290  assert(set != NULL);
3291  assert(stat != NULL);
3292  assert(var != NULL);
3293  assert(len >= 0);
3294  assert(len == 0 || (rows != NULL && vals != NULL));
3295 
3296  SCIP_ALLOC( BMSallocBlockMemory(blkmem, col) );
3297 
3298  if( len > 0 )
3299  {
3300  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->rows, rows, len) );
3301  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*col)->vals, vals, len) );
3302  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*col)->linkpos, len) );
3303 
3304  for( i = 0; i < len; ++i )
3305  {
3306  assert(rows[i] != NULL);
3307  assert(!SCIPsetIsZero(set, vals[i]));
3308  (*col)->linkpos[i] = -1;
3309  }
3310  }
3311  else
3312  {
3313  (*col)->rows = NULL;
3314  (*col)->vals = NULL;
3315  (*col)->linkpos = NULL;
3316  }
3317 
3318  (*col)->var = var;
3319  (*col)->obj = SCIPvarGetObj(var);
3320  (*col)->unchangedobj = SCIPvarGetUnchangedObj(var);
3321  (*col)->lb = SCIPvarGetLbLocal(var);
3322  (*col)->ub = SCIPvarGetUbLocal(var);
3323  (*col)->flushedobj = 0.0;
3324  (*col)->flushedlb = 0.0;
3325  (*col)->flushedub = 0.0;
3326  (*col)->index = stat->ncolidx;
3327  SCIPstatIncrement(stat, set, ncolidx);
3328  (*col)->size = len;
3329  (*col)->len = len;
3330  (*col)->nlprows = 0;
3331  (*col)->nunlinked = len;
3332  (*col)->lppos = -1;
3333  (*col)->lpipos = -1;
3334  (*col)->lpdepth = -1;
3335  (*col)->primsol = 0.0;
3336  (*col)->redcost = SCIP_INVALID;
3337  (*col)->farkascoef = SCIP_INVALID;
3338  (*col)->minprimsol = (*col)->ub;
3339  (*col)->maxprimsol = (*col)->lb;
3340  (*col)->sbdown = SCIP_INVALID;
3341  (*col)->sbup = SCIP_INVALID;
3342  (*col)->sbsolval = SCIP_INVALID;
3343  (*col)->sblpobjval = SCIP_INVALID;
3344  (*col)->sbnode = -1;
3345  (*col)->validredcostlp = -1;
3346  (*col)->validfarkaslp = -1;
3347  (*col)->validsblp = -1;
3348  (*col)->sbitlim = -1;
3349  (*col)->nsbcalls = 0;
3350  (*col)->age = 0;
3351  (*col)->obsoletenode = -1;
3352  (*col)->var_probindex = SCIPvarGetProbindex(var);
3353  (*col)->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
3354  (*col)->lprowssorted = TRUE;
3355  (*col)->nonlprowssorted = (len <= 1);
3356  (*col)->objchanged = FALSE;
3357  (*col)->lbchanged = FALSE;
3358  (*col)->ubchanged = FALSE;
3359  (*col)->coefchanged = FALSE;
3360  (*col)->integral = SCIPvarIsIntegral(var);
3361  (*col)->removable = removable;
3362  (*col)->sbdownvalid = FALSE;
3363  (*col)->sbupvalid = FALSE;
3364  (*col)->lazylb = SCIPvarGetLbLazy(var);
3365  (*col)->lazyub = SCIPvarGetUbLazy(var);
3366  (*col)->storedsolvals = NULL;
3367 
3368  return SCIP_OKAY;
3369 }
3370 
3371 /** frees an LP column */
3373  SCIP_COL** col, /**< pointer to LP column */
3374  BMS_BLKMEM* blkmem, /**< block memory */
3375  SCIP_SET* set, /**< global SCIP settings */
3376  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3377  SCIP_LP* lp /**< current LP data */
3378  )
3379 {
3380  assert(blkmem != NULL);
3381  assert(col != NULL);
3382  assert(*col != NULL);
3383  assert((*col)->var != NULL);
3384  assert(SCIPvarGetStatus((*col)->var) == SCIP_VARSTATUS_COLUMN);
3385  assert(&(*col)->var->data.col == col); /* SCIPcolFree() has to be called from SCIPvarFree() */
3386  assert((*col)->lppos == -1);
3387  assert((*col)->lpipos == -1);
3388 
3389  /* remove column indices from corresponding rows */
3390  SCIP_CALL( colUnlink(*col, blkmem, set, eventqueue, lp) );
3391 
3392  BMSfreeBlockMemoryNull(blkmem, &(*col)->storedsolvals);
3393  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->rows, (*col)->size);
3394  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->vals, (*col)->size);
3395  BMSfreeBlockMemoryArrayNull(blkmem, &(*col)->linkpos, (*col)->size);
3396  BMSfreeBlockMemory(blkmem, col);
3397 
3398  return SCIP_OKAY;
3399 }
3400 
3401 /** output column to file stream */
3403  SCIP_COL* col, /**< LP column */
3404  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
3405  FILE* file /**< output file (or NULL for standard output) */
3406  )
3407 {
3408  int r;
3409 
3410  assert(col != NULL);
3411  assert(col->var != NULL);
3412 
3413  /* print bounds */
3414  SCIPmessageFPrintInfo(messagehdlr, file, "(obj: %.15g) [%.15g,%.15g], ", col->obj, col->lb, col->ub);
3415 
3416  /* print coefficients */
3417  if( col->len == 0 )
3418  SCIPmessageFPrintInfo(messagehdlr, file, "<empty>");
3419  for( r = 0; r < col->len; ++r )
3420  {
3421  assert(col->rows[r] != NULL);
3422  assert(col->rows[r]->name != NULL);
3423  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", col->vals[r], col->rows[r]->name);
3424  }
3425  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
3426 }
3427 
3428 /** sorts column entries such that LP rows precede non-LP rows and inside both parts lower row indices precede higher ones
3429  */
3431  SCIP_COL* col /**< column to be sorted */
3432  )
3433 {
3434  /* sort LP rows */
3435  colSortLP(col);
3436 
3437  /* sort non-LP rows */
3438  colSortNonLP(col);
3439 }
3440 
3441 /** adds a previously non existing coefficient to an LP column */
3443  SCIP_COL* col, /**< LP column */
3444  BMS_BLKMEM* blkmem, /**< block memory */
3445  SCIP_SET* set, /**< global SCIP settings */
3446  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3447  SCIP_LP* lp, /**< current LP data */
3448  SCIP_ROW* row, /**< LP row */
3449  SCIP_Real val /**< value of coefficient */
3450  )
3451 {
3452  assert(lp != NULL);
3453  assert(!lp->diving);
3454 
3455  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3456 
3457  checkLinks(lp);
3458 
3459  return SCIP_OKAY;
3460 }
3461 
3462 /** deletes existing coefficient from column */
3464  SCIP_COL* col, /**< column to be changed */
3465  BMS_BLKMEM* blkmem, /**< block memory */
3466  SCIP_SET* set, /**< global SCIP settings */
3467  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3468  SCIP_LP* lp, /**< current LP data */
3469  SCIP_ROW* row /**< coefficient to be deleted */
3470  )
3471 {
3472  int pos;
3473 
3474  assert(col != NULL);
3475  assert(col->var != NULL);
3476  assert(lp != NULL);
3477  assert(!lp->diving);
3478  assert(row != NULL);
3479 
3480  /* search the position of the row in the column's row vector */
3481  pos = colSearchCoef(col, row);
3482  if( pos == -1 )
3483  {
3484  SCIPerrorMessage("coefficient for row <%s> doesn't exist in column <%s>\n", row->name, SCIPvarGetName(col->var));
3485  return SCIP_INVALIDDATA;
3486  }
3487  assert(0 <= pos && pos < col->len);
3488  assert(col->rows[pos] == row);
3489 
3490  /* if row knows of the column, remove the column from the row's col vector */
3491  if( col->linkpos[pos] >= 0 )
3492  {
3493  assert(row->cols[col->linkpos[pos]] == col);
3494  assert(row->cols_index[col->linkpos[pos]] == col->index);
3495  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3496  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos]) );
3497  }
3498 
3499  /* delete the row from the column's row vector */
3500  SCIP_CALL( colDelCoefPos(col, set, lp, pos) );
3501 
3502  checkLinks(lp);
3503 
3504  return SCIP_OKAY;
3505 }
3506 
3507 /** changes or adds a coefficient to an LP column */
3509  SCIP_COL* col, /**< LP column */
3510  BMS_BLKMEM* blkmem, /**< block memory */
3511  SCIP_SET* set, /**< global SCIP settings */
3512  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3513  SCIP_LP* lp, /**< current LP data */
3514  SCIP_ROW* row, /**< LP row */
3515  SCIP_Real val /**< value of coefficient */
3516  )
3517 {
3518  int pos;
3519 
3520  assert(col != NULL);
3521  assert(lp != NULL);
3522  assert(!lp->diving);
3523  assert(row != NULL);
3524 
3525  /* search the position of the row in the column's row vector */
3526  pos = colSearchCoef(col, row);
3527 
3528  /* check, if row already exists in the column's row vector */
3529  if( pos == -1 )
3530  {
3531  /* add previously not existing coefficient */
3532  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, val, -1) );
3533  }
3534  else
3535  {
3536  /* modify already existing coefficient */
3537  assert(0 <= pos && pos < col->len);
3538  assert(col->rows[pos] == row);
3539 
3540  /* if row knows of the column, change the corresponding coefficient in the row */
3541  if( col->linkpos[pos] >= 0 )
3542  {
3543  assert(row->cols[col->linkpos[pos]] == col);
3544  assert(row->cols_index[col->linkpos[pos]] == col->index);
3545  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3546  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], val) );
3547  }
3548 
3549  /* change the coefficient in the column */
3550  SCIP_CALL( colChgCoefPos(col, set, lp, pos, val) );
3551  }
3552 
3553  checkLinks(lp);
3554 
3555  return SCIP_OKAY;
3556 }
3557 
3558 /** increases value of an existing or non-existing coefficient in an LP column */
3560  SCIP_COL* col, /**< LP column */
3561  BMS_BLKMEM* blkmem, /**< block memory */
3562  SCIP_SET* set, /**< global SCIP settings */
3563  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
3564  SCIP_LP* lp, /**< current LP data */
3565  SCIP_ROW* row, /**< LP row */
3566  SCIP_Real incval /**< value to add to the coefficient */
3567  )
3568 {
3569  int pos;
3570 
3571  assert(col != NULL);
3572  assert(lp != NULL);
3573  assert(!lp->diving);
3574  assert(row != NULL);
3575 
3576  if( SCIPsetIsZero(set, incval) )
3577  return SCIP_OKAY;
3578 
3579  /* search the position of the row in the column's row vector */
3580  pos = colSearchCoef(col, row);
3581 
3582  /* check, if row already exists in the column's row vector */
3583  if( pos == -1 )
3584  {
3585  /* add previously not existing coefficient */
3586  SCIP_CALL( colAddCoef(col, blkmem, set, eventqueue, lp, row, incval, -1) );
3587  }
3588  else
3589  {
3590  /* modify already existing coefficient */
3591  assert(0 <= pos && pos < col->len);
3592  assert(col->rows[pos] == row);
3593 
3594  /* if row knows of the column, change the corresponding coefficient in the row */
3595  if( col->linkpos[pos] >= 0 )
3596  {
3597  assert(row->cols[col->linkpos[pos]] == col);
3598  assert(row->cols_index[col->linkpos[pos]] == col->index);
3599  assert(SCIPsetIsEQ(set, row->vals[col->linkpos[pos]], col->vals[pos]));
3600  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, col->linkpos[pos], col->vals[pos] + incval) );
3601  }
3602 
3603  /* change the coefficient in the column */
3604  SCIP_CALL( colChgCoefPos(col, set, lp, pos, col->vals[pos] + incval) );
3605  }
3606 
3607  checkLinks(lp);
3608 
3609  return SCIP_OKAY;
3610 }
3611 
3612 /** insert column in the chgcols list (if not already there) */
3613 static
3615  SCIP_COL* col, /**< LP column to change */
3616  SCIP_SET* set, /**< global SCIP settings */
3617  SCIP_LP* lp /**< current LP data */
3618  )
3619 {
3620  if( !col->objchanged && !col->lbchanged && !col->ubchanged )
3621  {
3622  SCIP_CALL( ensureChgcolsSize(lp, set, lp->nchgcols+1) );
3623  lp->chgcols[lp->nchgcols] = col;
3624  lp->nchgcols++;
3625  }
3626 
3627  /* mark the current LP unflushed */
3628  lp->flushed = FALSE;
3629 
3630  return SCIP_OKAY;
3631 }
3632 
3633 /** Is the new value reliable or may we have cancellation?
3634  *
3635  * @note: Here we only consider cancellations which can occur during decreasing the oldvalue to newvalue; not the
3636  * cancellations which can occur during increasing the oldvalue to the newvalue
3637  */
3638 static
3640  SCIP_SET* set, /**< global SCIP settings */
3641  SCIP_Real newvalue, /**< new value */
3642  SCIP_Real oldvalue /**< old reliable value */
3643  )
3644 {
3645  SCIP_Real quotient;
3646 
3647  assert(set != NULL);
3648  assert(oldvalue < SCIP_INVALID);
3649 
3650  quotient = (REALABS(newvalue)+1.0) / (REALABS(oldvalue) + 1.0);
3651 
3652  return SCIPsetIsZero(set, quotient);
3653 }
3654 
3655 /** update norms of objective function vector */
3656 static
3658  SCIP_LP* lp, /**< current LP data */
3659  SCIP_SET* set, /**< global SCIP settings */
3660  SCIP_Real oldobj, /**< old objective value of variable */
3661  SCIP_Real newobj /**< new objective value of variable */
3662  )
3663 {
3664  if( REALABS(newobj) != REALABS(oldobj) ) /*lint !e777*/
3665  {
3666  if( !lp->objsqrnormunreliable )
3667  {
3668  SCIP_Real oldvalue;
3669 
3670  oldvalue = lp->objsqrnorm;
3671  lp->objsqrnorm += SQR(newobj) - SQR(oldobj);
3672 
3673  /* due to numerical cancellations, we recalculate lp->objsqrnorm using all variables */
3674  if( SCIPsetIsLT(set, lp->objsqrnorm, 0.0) || isNewValueUnreliable(set, lp->objsqrnorm, oldvalue) )
3675  lp->objsqrnormunreliable = TRUE;
3676  else
3677  {
3678  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
3679 
3680  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
3681  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
3682 
3683  assert(lp->objsqrnorm >= 0.0);
3684  }
3685  }
3686 
3687  lp->objsumnorm += REALABS(newobj) - REALABS(oldobj);
3688  lp->objsumnorm = MAX(lp->objsumnorm, 0.0);
3689  }
3690 }
3691 
3692 /** changes objective value of column */
3694  SCIP_COL* col, /**< LP column to change */
3695  SCIP_SET* set, /**< global SCIP settings */
3696  SCIP_LP* lp, /**< current LP data */
3697  SCIP_Real newobj /**< new objective value */
3698  )
3699 {
3700  assert(col != NULL);
3701  assert(col->var != NULL);
3702  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3703  assert(SCIPvarGetCol(col->var) == col);
3704  assert(lp != NULL);
3705 
3706  SCIPsetDebugMsg(set, "changing objective value of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->obj, newobj);
3707 
3708  /* only add actual changes */
3709  if( !SCIPsetIsEQ(set, col->obj, newobj) )
3710  {
3711  /* only variables with a real position in the LPI can be inserted */
3712  if( col->lpipos >= 0 )
3713  {
3714  /* insert column in the chgcols list (if not already there) */
3715  SCIP_CALL( insertColChgcols(col, set, lp) );
3716 
3717  /* mark objective value change in the column */
3718  col->objchanged = TRUE;
3719 
3720  assert(lp->nchgcols > 0);
3721  }
3722  /* in any case, when the sign of the objective (and thereby the best bound) changes, the variable has to enter the
3723  * LP and the LP has to be flushed
3724  */
3725  else if( (col->obj < 0.0 && newobj >= 0.0 && SCIPsetIsZero(set, col->ub))
3726  || (col->obj >= 0.0 && newobj < 0.0 && SCIPsetIsZero(set, col->lb)) )
3727  {
3728  /* mark the LP unflushed */
3729  lp->flushed = FALSE;
3730  }
3731  }
3732 
3733  /* store new objective function value */
3734  col->obj = newobj;
3735 
3736  /* update original objective value, as long as we are not in diving or probing and changed objective values */
3737  if( !lp->divingobjchg )
3738  {
3739  SCIP_Real oldobj = col->unchangedobj;
3740 
3741  assert(SCIPsetIsEQ(set, newobj, SCIPvarGetUnchangedObj(col->var)));
3742  col->unchangedobj = newobj;
3743 
3744  /* update the objective function vector norms */
3745  lpUpdateObjNorms(lp, set, oldobj, newobj);
3746  }
3747 
3748  return SCIP_OKAY;
3749 }
3750 
3751 /** changes lower bound of column */
3753  SCIP_COL* col, /**< LP column to change */
3754  SCIP_SET* set, /**< global SCIP settings */
3755  SCIP_LP* lp, /**< current LP data */
3756  SCIP_Real newlb /**< new lower bound value */
3757  )
3758 {
3759  assert(col != NULL);
3760  assert(col->var != NULL);
3761  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3762  assert(SCIPvarGetCol(col->var) == col);
3763  assert(lp != NULL);
3764 
3765  SCIPsetDebugMsg(set, "changing lower bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->lb, newlb);
3766 
3767  /* only add actual changes */
3768  if( !SCIPsetIsEQ(set, col->lb, newlb) )
3769  {
3770  /* only variables with a real position in the LPI can be inserted */
3771  if( col->lpipos >= 0 )
3772  {
3773  /* insert column in the chgcols list (if not already there) */
3774  SCIP_CALL( insertColChgcols(col, set, lp) );
3775 
3776  /* mark bound change in the column */
3777  col->lbchanged = TRUE;
3778 
3779  assert(lp->nchgcols > 0);
3780  }
3781  /* 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
3782  * flushed
3783  */
3784  else if( col->obj >= 0.0 && SCIPsetIsZero(set, col->lb) )
3785  {
3786  /* mark the LP unflushed */
3787  lp->flushed = FALSE;
3788  }
3789  }
3790 
3791  col->lb = newlb;
3792 
3793  return SCIP_OKAY;
3794 }
3795 
3796 /** changes upper bound of column */
3798  SCIP_COL* col, /**< LP column to change */
3799  SCIP_SET* set, /**< global SCIP settings */
3800  SCIP_LP* lp, /**< current LP data */
3801  SCIP_Real newub /**< new upper bound value */
3802  )
3803 {
3804  assert(col != NULL);
3805  assert(col->var != NULL);
3806  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3807  assert(SCIPvarGetCol(col->var) == col);
3808  assert(lp != NULL);
3809 
3810  SCIPsetDebugMsg(set, "changing upper bound of column <%s> from %f to %f\n", SCIPvarGetName(col->var), col->ub, newub);
3811 
3812  /* only add actual changes */
3813  if( !SCIPsetIsEQ(set, col->ub, newub) )
3814  {
3815  /* only variables with a real position in the LPI can be inserted */
3816  if( col->lpipos >= 0 )
3817  {
3818  /* insert column in the chgcols list (if not already there) */
3819  SCIP_CALL( insertColChgcols(col, set, lp) );
3820 
3821  /* mark bound change in the column */
3822  col->ubchanged = TRUE;
3823 
3824  assert(lp->nchgcols > 0);
3825  }
3826  /* 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
3827  * flushed
3828  */
3829  else if( col->obj < 0.0 && SCIPsetIsZero(set, col->ub) )
3830  {
3831  /* mark the LP unflushed */
3832  lp->flushed = FALSE;
3833  }
3834  }
3835 
3836  col->ub = newub;
3837 
3838  return SCIP_OKAY;
3839 }
3840 
3841 /** calculates the reduced costs of a column using the given dual solution vector */
3843  SCIP_COL* col, /**< LP column */
3844  SCIP_Real* dualsol /**< dual solution vector for current LP rows */
3845  )
3846 {
3847  SCIP_ROW* row;
3848  SCIP_Real redcost;
3849  int i;
3850 
3851  assert(col != NULL);
3852  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3853  assert(SCIPvarGetCol(col->var) == col);
3854  assert(dualsol != NULL);
3855 
3856  redcost = col->obj;
3857  for( i = 0; i < col->nlprows; ++i )
3858  {
3859  row = col->rows[i];
3860  assert(row != NULL);
3861  assert(row->lppos >= 0);
3862  redcost -= col->vals[i] * dualsol[row->lppos];
3863  }
3864 
3865  if( col->nunlinked > 0 )
3866  {
3867  for( i = col->nlprows; i < col->len; ++i )
3868  {
3869  row = col->rows[i];
3870  assert(row != NULL);
3871  assert(row->lppos == -1 || col->linkpos[i] == -1);
3872  if( row->lppos >= 0 )
3873  redcost -= col->vals[i] * dualsol[row->lppos];
3874  }
3875  }
3876 #ifndef NDEBUG
3877  else
3878  {
3879  for( i = col->nlprows; i < col->len; ++i )
3880  {
3881  row = col->rows[i];
3882  assert(row != NULL);
3883  assert(row->lppos == -1);
3884  assert(col->linkpos[i] >= 0);
3885  }
3886  }
3887 #endif
3888 
3889  return redcost;
3890 }
3891 
3892 /** calculates the reduced costs of a column using the dual solution stored in the rows */
3893 static
3895  SCIP_COL* col /**< LP column */
3896  )
3897 {
3898  SCIP_ROW* row;
3899  SCIP_Real redcost;
3900  int i;
3901 
3902  assert(col != NULL);
3903  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
3904  assert(SCIPvarGetCol(col->var) == col);
3905 
3906  redcost = col->obj;
3907  for( i = 0; i < col->nlprows; ++i )
3908  {
3909  row = col->rows[i];
3910  assert(row != NULL);
3911  assert(row->dualsol < SCIP_INVALID);
3912  assert(row->lppos >= 0);
3913  assert(col->linkpos[i] >= 0);
3914  redcost -= col->vals[i] * row->dualsol;
3915  }
3916 
3917  if( col->nunlinked > 0 )
3918  {
3919  for( i = col->nlprows; i < col->len; ++i )
3920  {
3921  row = col->rows[i];
3922  assert(row != NULL);
3923  assert(row->lppos >= 0 || row->dualsol == 0.0);
3924  assert(row->lppos == -1 || col->linkpos[i] == -1);
3925  if( row->lppos >= 0 )
3926  redcost -= col->vals[i] * row->dualsol;
3927  }
3928  }
3929 #ifndef NDEBUG
3930  else
3931  {
3932  for( i = col->nlprows; i < col->len; ++i )
3933  {
3934  row = col->rows[i];
3935  assert(row != NULL);
3936  assert(row->dualsol == 0.0);
3937  assert(row->lppos == -1);
3938  assert(col->linkpos[i] >= 0);
3939  }
3940  }
3941 #endif
3942 
3943  return redcost;
3944 }
3945 
3946 /** gets the reduced costs of a column in last LP or after recalculation */
3948  SCIP_COL* col, /**< LP column */
3949  SCIP_STAT* stat, /**< problem statistics */
3950  SCIP_LP* lp /**< current LP data */
3951  )
3952 {
3953  assert(col != NULL);
3954  assert(stat != NULL);
3955  assert(lp != NULL);
3956  assert(col->validredcostlp <= stat->lpcount);
3957  assert(lp->validsollp == stat->lpcount);
3958 
3959  if( col->validredcostlp < stat->lpcount )
3960  {
3961  col->redcost = colCalcInternalRedcost(col);
3962  col->validredcostlp = stat->lpcount;
3963  }
3964  assert(col->validredcostlp == stat->lpcount);
3965  assert(col->redcost < SCIP_INVALID);
3966 
3967  return col->redcost;
3968 }
3969 
3970 /** gets the feasibility of (the dual row of) a column in last LP or after recalculation */
3972  SCIP_COL* col, /**< LP column */
3973  SCIP_SET* set, /**< global SCIP settings */
3974  SCIP_STAT* stat, /**< problem statistics */
3975  SCIP_LP* lp /**< current LP data */
3976  )
3977 {
3978  assert(col != NULL);
3979  assert(set != NULL);
3980  assert(stat != NULL);
3981  assert(lp != NULL);
3982  assert(lp->validsollp == stat->lpcount);
3983 
3984  /* A column's reduced cost is defined as
3985  * redcost = obj - activity, activity = y^T * col. (activity = obj - redcost)
3986  * The activity is equal to the activity of the corresponding row in the dual LP.
3987  * The column's feasibility is the feasibility of the corresponding row in the dual LP.
3988  * The sides of the dual row depend on the bounds of the column:
3989  * - lb == ub : dual row is a free row with infinite sides
3990  * - 0 <= lb < ub: activity <= obj => 0 <= redcost
3991  * - lb < 0 < ub: obj <= activity <= obj => 0 <= redcost <= 0
3992  * - lb < ub <= 0: obj <= activity => redcost <= 0
3993  */
3994  if( SCIPsetIsEQ(set, col->lb, col->ub) )
3995  {
3996  /* dual row is free */
3997  return SCIPsetInfinity(set);
3998  }
3999  else
4000  {
4001  SCIP_Real redcost;
4002 
4003  /* calculate reduced costs */
4004  redcost = SCIPcolGetRedcost(col, stat, lp);
4005 
4006  if( !SCIPsetIsNegative(set, col->lb) )
4007  {
4008  /* dual row is activity <= obj <=> redcost >= 0 */
4009  return redcost;
4010  }
4011  else if( SCIPsetIsPositive(set, col->ub) )
4012  {
4013  /* dual row is activity == obj <=> redcost == 0 */
4014  return -REALABS(redcost);
4015  }
4016  else
4017  {
4018  /* dual row is activity >= obj <=> redcost <= 0 */
4019  return -redcost;
4020  }
4021  }
4022 }
4023 
4024 /** calculates the Farkas coefficient y^T A_i of a column i using the given dual Farkas vector y */
4026  SCIP_COL* col, /**< LP column */
4027  SCIP_Real* dualfarkas /**< dense dual Farkas vector for current LP rows */
4028  )
4029 {
4030  SCIP_ROW* row;
4031  SCIP_Real farkas;
4032  int i;
4033 
4034  assert(col != NULL);
4035  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4036  assert(SCIPvarGetCol(col->var) == col);
4037  assert(dualfarkas != NULL);
4038 
4039  farkas = 0.0;
4040  for( i = 0; i < col->nlprows; ++i )
4041  {
4042  row = col->rows[i];
4043  assert(row != NULL);
4044  assert(row->lppos >= 0);
4045  farkas += col->vals[i] * dualfarkas[row->lppos];
4046  }
4047 
4048  if( col->nunlinked > 0 )
4049  {
4050  for( i = col->nlprows; i < col->len; ++i )
4051  {
4052  row = col->rows[i];
4053  assert(row != NULL);
4054  assert(row->lppos == -1 || col->linkpos[i] == -1);
4055  if( row->lppos >= 0 )
4056  farkas += col->vals[i] * dualfarkas[row->lppos];
4057  }
4058  }
4059 #ifndef NDEBUG
4060  else
4061  {
4062  for( i = col->nlprows; i < col->len; ++i )
4063  {
4064  row = col->rows[i];
4065  assert(row != NULL);
4066  assert(row->lppos == -1);
4067  assert(col->linkpos[i] >= 0);
4068  }
4069  }
4070 #endif
4071 
4072  return farkas;
4073 }
4074 
4075 /** gets the Farkas coefficient y^T A_i of a column i in last LP (which must be infeasible) */
4076 static
4078  SCIP_COL* col /**< LP column */
4079  )
4080 {
4081  SCIP_ROW* row;
4082  SCIP_Real farkas;
4083  int i;
4084 
4085  assert(col != NULL);
4086  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4087  assert(SCIPvarGetCol(col->var) == col);
4088 
4089  farkas = 0.0;
4090  for( i = 0; i < col->nlprows; ++i )
4091  {
4092  row = col->rows[i];
4093  assert(row != NULL);
4094  assert(row->dualfarkas < SCIP_INVALID);
4095  assert(row->lppos >= 0);
4096  assert(col->linkpos[i] >= 0);
4097  farkas += col->vals[i] * row->dualfarkas;
4098  }
4099 
4100  if( col->nunlinked > 0 )
4101  {
4102  for( i = col->nlprows; i < col->len; ++i )
4103  {
4104  row = col->rows[i];
4105  assert(row != NULL);
4106  assert(row->lppos >= 0 || row->dualfarkas == 0.0);
4107  assert(row->lppos == -1 || col->linkpos[i] == -1);
4108  if( row->lppos >= 0 )
4109  farkas += col->vals[i] * row->dualfarkas;
4110  }
4111  }
4112 #ifndef NDEBUG
4113  else
4114  {
4115  for( i = col->nlprows; i < col->len; ++i )
4116  {
4117  row = col->rows[i];
4118  assert(row != NULL);
4119  assert(row->dualfarkas == 0.0);
4120  assert(row->lppos == -1);
4121  assert(col->linkpos[i] >= 0);
4122  }
4123  }
4124 #endif
4125 
4126  return farkas;
4127 }
4128 
4129 /** gets the Farkas coefficient of a column in last LP (which must be infeasible) */
4131  SCIP_COL* col, /**< LP column */
4132  SCIP_STAT* stat, /**< problem statistics */
4133  SCIP_LP* lp /**< current LP data */
4134  )
4135 {
4136  assert(col != NULL);
4137  assert(stat != NULL);
4138  assert(lp != NULL);
4139  assert(col->validfarkaslp <= stat->lpcount);
4140  assert(lp->validfarkaslp == stat->lpcount);
4141 
4142  if( col->validfarkaslp < stat->lpcount )
4143  {
4145  col->validfarkaslp = stat->lpcount;
4146  }
4147  assert(col->validfarkaslp == stat->lpcount);
4148  assert(col->farkascoef < SCIP_INVALID);
4149 
4150  return col->farkascoef;
4151 }
4152 
4153 /** gets the Farkas value of a column in last LP (which must be infeasible), i.e. the Farkas coefficient y^T A_i times
4154  * the best bound for this coefficient, i.e. max{y^T A_i x_i | lb <= x_i <= ub}
4155  */
4157  SCIP_COL* col, /**< LP column */
4158  SCIP_STAT* stat, /**< problem statistics */
4159  SCIP_LP* lp /**< current LP data */
4160  )
4161 {
4162  SCIP_Real farkascoef;
4163 
4164  assert(col != NULL);
4165 
4166  farkascoef = SCIPcolGetFarkasCoef(col, stat, lp);
4167 
4168  if( farkascoef > 0.0 )
4169  return col->ub * farkascoef;
4170  else
4171  return col->lb * farkascoef;
4172 }
4173 
4174 /** start strong branching - call before any strong branching */
4176  SCIP_LP* lp /**< LP data */
4177  )
4178 {
4179  assert(lp != NULL);
4180  assert(!lp->strongbranching);
4181 
4182  lp->strongbranching = TRUE;
4183  SCIPdebugMessage("starting strong branching ...\n");
4185 
4186  return SCIP_OKAY;
4187 }
4188 
4189 /** end strong branching - call after any strong branching */
4191  SCIP_LP* lp /**< LP data */
4192  )
4193 {
4194  assert(lp != NULL);
4195  assert(lp->strongbranching);
4196 
4197  lp->strongbranching = FALSE;
4198  SCIPdebugMessage("ending strong branching ...\n");
4200 
4201  return SCIP_OKAY;
4202 }
4203 
4204 /** sets strong branching information for a column variable */
4206  SCIP_COL* col, /**< LP column */
4207  SCIP_SET* set, /**< global SCIP settings */
4208  SCIP_STAT* stat, /**< dynamic problem statistics */
4209  SCIP_LP* lp, /**< LP data */
4210  SCIP_Real lpobjval, /**< objective value of the current LP */
4211  SCIP_Real primsol, /**< primal solution value of the column in the current LP */
4212  SCIP_Real sbdown, /**< dual bound after branching column down */
4213  SCIP_Real sbup, /**< dual bound after branching column up */
4214  SCIP_Bool sbdownvalid, /**< is the returned down value a valid dual bound? */
4215  SCIP_Bool sbupvalid, /**< is the returned up value a valid dual bound? */
4216  SCIP_Longint iter, /**< total number of strong branching iterations */
4217  int itlim /**< iteration limit applied to the strong branching call */
4218  )
4219 {
4220  assert(col != NULL);
4221  assert(col->var != NULL);
4222  assert(SCIPcolIsIntegral(col));
4223  assert(SCIPvarIsIntegral(col->var));
4224  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4225  assert(SCIPvarGetCol(col->var) == col);
4226  assert(col->lpipos >= 0);
4227  assert(col->lppos >= 0);
4228  assert(set != NULL);
4229  assert(stat != NULL);
4230  assert(lp != NULL);
4231  assert(lp->strongbranchprobing);
4232  assert(col->lppos < lp->ncols);
4233  assert(lp->cols[col->lppos] == col);
4234  assert(itlim >= 1);
4235 
4236  col->sblpobjval = lpobjval;
4237  col->sbsolval = primsol;
4238  col->validsblp = stat->nlps;
4239  col->sbnode = stat->nnodes;
4240 
4241  col->sbitlim = itlim;
4242  col->nsbcalls++;
4243 
4244  col->sbdown = MIN(sbdown, lp->cutoffbound);
4245  col->sbup = MIN(sbup, lp->cutoffbound);
4246  col->sbdownvalid = sbdownvalid;
4247  col->sbupvalid = sbupvalid;
4248 
4249  SCIPstatIncrement(stat, set, nstrongbranchs);
4250  SCIPstatAdd(stat, set, nsblpiterations, iter);
4251  if( stat->nnodes == 1 )
4252  {
4253  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4254  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4255  }
4256 }
4257 
4258 /** invalidates strong branching information for a column variable */
4260  SCIP_COL* col, /**< LP column */
4261  SCIP_SET* set, /**< global SCIP settings */
4262  SCIP_STAT* stat, /**< dynamic problem statistics */
4263  SCIP_LP* lp /**< LP data */
4264  )
4265 {
4266  assert(col != NULL);
4267  assert(col->var != NULL);
4268  assert(SCIPcolIsIntegral(col));
4269  assert(SCIPvarIsIntegral(col->var));
4270  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4271  assert(SCIPvarGetCol(col->var) == col);
4272  assert(col->lpipos >= 0);
4273  assert(col->lppos >= 0);
4274  assert(set != NULL);
4275  assert(stat != NULL);
4276  assert(lp != NULL);
4277  assert(lp->strongbranchprobing);
4278  assert(col->lppos < lp->ncols);
4279  assert(lp->cols[col->lppos] == col);
4280 
4281  col->sbdown = SCIP_INVALID;
4282  col->sbup = SCIP_INVALID;
4283  col->sbdownvalid = FALSE;
4284  col->sbupvalid = FALSE;
4285  col->validsblp = -1;
4286  col->sbsolval = SCIP_INVALID;
4287  col->sblpobjval = SCIP_INVALID;
4288  col->sbnode = -1;
4289  col->sbitlim = -1;
4290 }
4291 
4292 
4293 /** gets strong branching information on a column variable */
4295  SCIP_COL* col, /**< LP column */
4296  SCIP_Bool integral, /**< should integral strong branching be performed? */
4297  SCIP_SET* set, /**< global SCIP settings */
4298  SCIP_STAT* stat, /**< dynamic problem statistics */
4299  SCIP_PROB* prob, /**< problem data */
4300  SCIP_LP* lp, /**< LP data */
4301  int itlim, /**< iteration limit for strong branchings */
4302  SCIP_Bool updatecol, /**< should col be updated, or should it stay in its current state ? */
4303  SCIP_Bool updatestat, /**< should stat be updated, or should it stay in its current state ? */
4304  SCIP_Real* down, /**< stores dual bound after branching column down */
4305  SCIP_Real* up, /**< stores dual bound after branching column up */
4306  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4307  * otherwise, it can only be used as an estimate value */
4308  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4309  * otherwise, it can only be used as an estimate value */
4310  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4311  )
4312 {
4313  SCIP_Real sbdown;
4314  SCIP_Real sbup;
4315  SCIP_Bool sbdownvalid;
4316  SCIP_Bool sbupvalid;
4317  SCIP_Longint validsblp;
4318  SCIP_Real sbsolval;
4319  SCIP_Real sblpobjval;
4320  SCIP_Longint sbnode;
4321  int sbitlim;
4322  int nsbcalls;
4323 
4324  assert(col != NULL);
4325  assert(col->var != NULL);
4326  assert(SCIPcolIsIntegral(col));
4327  assert(SCIPvarIsIntegral(col->var));
4328  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4329  assert(SCIPvarGetCol(col->var) == col);
4330  assert(col->primsol < SCIP_INVALID);
4331  assert(col->lpipos >= 0);
4332  assert(col->lppos >= 0);
4333  assert(set != NULL);
4334  assert(stat != NULL);
4335  assert(lp != NULL);
4336  assert(lp->flushed);
4337  assert(lp->solved);
4338  assert(lp->strongbranching);
4339  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4340  assert(lp->validsollp == stat->lpcount);
4341  assert(col->lppos < lp->ncols);
4342  assert(lp->cols[col->lppos] == col);
4343  assert(itlim >= 1);
4344  /* assert(down != NULL);
4345  * assert(up != NULL); temporary hack for cloud branching
4346  */
4347  assert(lperror != NULL);
4348 
4349  *lperror = FALSE;
4350 
4351  sbdown = col->sbdown;
4352  sbup = col->sbup;
4353  sbdownvalid = col->sbdownvalid;
4354  sbupvalid = col->sbupvalid;
4355  sbitlim = col->sbitlim;
4356  nsbcalls = col->nsbcalls;
4357 
4358  validsblp = stat->nlps;
4359  sbsolval = col->primsol;
4360  sblpobjval = SCIPlpGetObjval(lp, set, prob);
4361  sbnode = stat->nnodes;
4362  assert(integral || !SCIPsetIsFeasIntegral(set, col->primsol));
4363 
4364  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4365  if( lp->looseobjvalinf > 0 )
4366  {
4367  sbdown = -SCIPsetInfinity(set);
4368  sbup = -SCIPsetInfinity(set);
4369  sbdownvalid = FALSE;
4370  sbupvalid = FALSE;
4371  }
4372  else
4373  {
4374  SCIP_RETCODE retcode;
4375  int iter;
4376 
4377  SCIPsetDebugMsg(set, "performing strong branching on variable <%s>(%g) with %d iterations\n",
4378  SCIPvarGetName(col->var), col->primsol, itlim);
4379 
4380  /* start timing */
4381  SCIPclockStart(stat->strongbranchtime, set);
4382 
4383  /* call LPI strong branching */
4384  sbitlim = itlim;
4385  nsbcalls++;
4386 
4387  sbdown = lp->lpobjval;
4388  sbup = lp->lpobjval;
4389 
4390  if( integral )
4391  retcode = SCIPlpiStrongbranchInt(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4392  else
4393  {
4394  assert( ! SCIPsetIsIntegral(set, col->primsol) );
4395  retcode = SCIPlpiStrongbranchFrac(lp->lpi, col->lpipos, col->primsol, itlim, down == NULL ? NULL : &sbdown, up == NULL ? NULL : &sbup, &sbdownvalid, &sbupvalid, &iter);
4396  }
4397 
4398  /* check return code for errors */
4399  if( retcode == SCIP_LPERROR )
4400  {
4401  *lperror = TRUE;
4402  sbdown = SCIP_INVALID;
4403  sbup = SCIP_INVALID;
4404  sbdownvalid = FALSE;
4405  sbupvalid = FALSE;
4406  validsblp = -1;
4407  sbsolval = SCIP_INVALID;
4408  sblpobjval = SCIP_INVALID;
4409  sbnode = -1;
4410  }
4411  else
4412  {
4413  SCIP_Real looseobjval;
4414 
4415  *lperror = FALSE;
4416  SCIP_CALL( retcode );
4417 
4418  looseobjval = getFiniteLooseObjval(lp, set, prob);
4419  sbdown = MIN(sbdown + looseobjval, lp->cutoffbound);
4420  sbup = MIN(sbup + looseobjval, lp->cutoffbound);
4421 
4422  /* update strong branching statistics */
4423  if( updatestat )
4424  {
4425  if( iter == -1 )
4426  {
4427  /* calculate average iteration number */
4428  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4429  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4430  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4431  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4432  : 0;
4433  if( iter/2 >= itlim )
4434  iter = 2*itlim;
4435  }
4436  SCIPstatIncrement(stat, set, nstrongbranchs);
4437  SCIPstatAdd(stat, set, nsblpiterations, iter);
4438  if( stat->nnodes == 1 )
4439  {
4440  SCIPstatIncrement(stat, set, nrootstrongbranchs);
4441  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4442  }
4443  }
4444  }
4445 
4446  /* stop timing */
4447  SCIPclockStop(stat->strongbranchtime, set);
4448  }
4449  assert(*lperror || sbdown < SCIP_INVALID);
4450  assert(*lperror || sbup < SCIP_INVALID);
4451 
4452  if( down != NULL)
4453  *down = sbdown;
4454  if( up != NULL )
4455  *up = sbup;
4456  if( downvalid != NULL )
4457  *downvalid = sbdownvalid;
4458  if( upvalid != NULL )
4459  *upvalid = sbupvalid;
4460 
4461  if( updatecol )
4462  {
4463  col->sbdown = sbdown;
4464  col->sbup = sbup;
4465  col->sbdownvalid = sbdownvalid;
4466  col->sbupvalid = sbupvalid;
4467  col->validsblp = validsblp;
4468  col->sbsolval = sbsolval;
4469  col->sblpobjval = sblpobjval;
4470  col->sbnode = sbnode;
4471  col->sbitlim = sbitlim;
4472  col->nsbcalls = nsbcalls;
4473  }
4474 
4475  return SCIP_OKAY;
4476 }
4477 
4478 /** gets strong branching information on column variables */
4480  SCIP_COL** cols, /**< LP columns */
4481  int ncols, /**< number of columns */
4482  SCIP_Bool integral, /**< should integral strong branching be performed? */
4483  SCIP_SET* set, /**< global SCIP settings */
4484  SCIP_STAT* stat, /**< dynamic problem statistics */
4485  SCIP_PROB* prob, /**< problem data */
4486  SCIP_LP* lp, /**< LP data */
4487  int itlim, /**< iteration limit for strong branchings */
4488  SCIP_Real* down, /**< stores dual bounds after branching columns down */
4489  SCIP_Real* up, /**< stores dual bounds after branching columns up */
4490  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds, or NULL;
4491  * otherwise, they can only be used as an estimate value */
4492  SCIP_Bool* upvalid, /**< stores whether the returned up values are valid dual bounds, or NULL;
4493  * otherwise, they can only be used as an estimate value */
4494  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
4495  )
4496 {
4497  SCIP_RETCODE retcode;
4498  SCIP_Real* sbdown;
4499  SCIP_Real* sbup;
4500  SCIP_Bool* sbdownvalid;
4501  SCIP_Bool* sbupvalid;
4502  SCIP_Real* primsols;
4503  SCIP_COL** subcols;
4504  int* lpipos;
4505  int* subidx;
4506  int nsubcols;
4507  int iter;
4508  int j;
4509 
4510  assert(cols != NULL);
4511  assert(set != NULL);
4512  assert(stat != NULL);
4513  assert(lp != NULL);
4514  assert(lp->flushed);
4515  assert(lp->solved);
4516  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
4517  assert(lp->validsollp == stat->lpcount);
4518  assert(itlim >= 1);
4519  assert(down != NULL);
4520  assert(up != NULL);
4521  assert(lperror != NULL);
4522 
4523  *lperror = FALSE;
4524 
4525  if ( ncols <= 0 )
4526  return SCIP_OKAY;
4527 
4528  /* start timing */
4529  SCIPclockStart(stat->strongbranchtime, set);
4530 
4531  /* initialize storage */
4532  SCIP_CALL( SCIPsetAllocBufferArray(set, &subcols, ncols) );
4533  SCIP_CALL( SCIPsetAllocBufferArray(set, &subidx, ncols) );
4534  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpipos, ncols) );
4535  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsols, ncols) );
4536  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdown, ncols) );
4537  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbup, ncols) );
4538  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbdownvalid, ncols) );
4539  SCIP_CALL( SCIPsetAllocBufferArray(set, &sbupvalid, ncols) );
4540 
4541  nsubcols = 0;
4542  for( j = 0; j < ncols; ++j )
4543  {
4544  SCIP_COL* col;
4545  col = cols[j];
4546 
4547  assert(col->lppos < lp->ncols);
4548  assert(lp->cols[col->lppos] == col);
4549  assert(SCIPcolIsIntegral(col));
4550  assert(SCIPvarIsIntegral(col->var));
4551  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
4552  assert(SCIPvarGetCol(col->var) == col);
4553  assert(col->primsol < SCIP_INVALID);
4554  assert(col->lpipos >= 0);
4555  assert(col->lppos >= 0);
4556 
4557  col->validsblp = stat->nlps;
4558  col->sbsolval = col->primsol;
4559  col->sblpobjval = SCIPlpGetObjval(lp, set, prob);
4560  col->sbnode = stat->nnodes;
4561  assert(!SCIPsetIsFeasIntegral(set, col->primsol));
4562 
4563  /* if a loose variables has an infinite best bound, the LP bound is -infinity and no gain can be achieved */
4564  if( lp->looseobjvalinf > 0 )
4565  {
4566  /* directly set up column and result vectors*/
4567  col->sbdown = -SCIPsetInfinity(set);
4568  col->sbup = -SCIPsetInfinity(set);
4569  col->sbdownvalid = FALSE;
4570  col->sbupvalid = FALSE;
4571  down[j] = col->sbdown;
4572  up[j] = col->sbup;
4573  if( downvalid != NULL )
4574  downvalid[j] = col->sbdownvalid;
4575  if( upvalid != NULL )
4576  upvalid[j] = col->sbupvalid;
4577  }
4578  else
4579  {
4580  col->sbitlim = itlim;
4581  col->nsbcalls++;
4582 
4583  lpipos[nsubcols] = col->lpipos;
4584  primsols[nsubcols] = col->primsol;
4585  assert( integral || ! SCIPsetIsFeasIntegral(set, col->primsol) );
4586  subidx[nsubcols] = j;
4587  subcols[nsubcols++] = col;
4588  }
4589  }
4590 
4591  SCIPsetDebugMsg(set, "performing strong branching on %d variables with %d iterations\n", ncols, itlim);
4592 
4593  /* call LPI strong branching */
4594  if ( integral )
4595  retcode = SCIPlpiStrongbranchesInt(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4596  else
4597  retcode = SCIPlpiStrongbranchesFrac(lp->lpi, lpipos, nsubcols, primsols, itlim, sbdown, sbup, sbdownvalid, sbupvalid, &iter);
4598 
4599  /* check return code for errors */
4600  if( retcode == SCIP_LPERROR )
4601  {
4602  *lperror = TRUE;
4603 
4604  for( j = 0; j < nsubcols; ++j )
4605  {
4606  SCIP_COL* col;
4607  int idx;
4608 
4609  col = subcols[j];
4610  idx = subidx[j];
4611 
4612  col->sbdown = SCIP_INVALID;
4613  col->sbup = SCIP_INVALID;
4614  col->sbdownvalid = FALSE;
4615  col->sbupvalid = FALSE;
4616  col->validsblp = -1;
4617  col->sbsolval = SCIP_INVALID;
4618  col->sblpobjval = SCIP_INVALID;
4619  col->sbnode = -1;
4620 
4621  down[idx] = col->sbdown;
4622  up[idx] = col->sbup;
4623  if( downvalid != NULL )
4624  downvalid[idx] = col->sbdownvalid;
4625  if( upvalid != NULL )
4626  upvalid[idx] = col->sbupvalid;
4627  }
4628  }
4629  else
4630  {
4631  SCIP_Real looseobjval;
4632 
4633  *lperror = FALSE;
4634  SCIP_CALL( retcode );
4635 
4636  looseobjval = getFiniteLooseObjval(lp, set, prob);
4637 
4638  for( j = 0; j < nsubcols; ++j )
4639  {
4640  SCIP_COL* col;
4641  int idx;
4642 
4643  col = subcols[j];
4644  idx = subidx[j];
4645 
4646  assert( col->sbdown < SCIP_INVALID);
4647  assert( col->sbup < SCIP_INVALID);
4648 
4649  col->sbdown = MIN(sbdown[j] + looseobjval, lp->cutoffbound);
4650  col->sbup = MIN(sbup[j] + looseobjval, lp->cutoffbound);
4651  col->sbdownvalid = sbdownvalid[j];
4652  col->sbupvalid = sbupvalid[j];
4653 
4654  down[idx] = col->sbdown;
4655  up[idx] = col->sbup;
4656  if( downvalid != NULL )
4657  downvalid[idx] = col->sbdownvalid;
4658  if( upvalid != NULL )
4659  upvalid[idx] = col->sbupvalid;
4660  }
4661 
4662  /* update strong branching statistics */
4663  if( iter == -1 )
4664  {
4665  /* calculate average iteration number */
4666  iter = stat->ndualresolvelps > 0 ? (int)(2*stat->ndualresolvelpiterations / stat->ndualresolvelps)
4667  : stat->nduallps > 0 ? (int)((stat->nduallpiterations / stat->nduallps) / 5)
4668  : stat->nprimalresolvelps > 0 ? (int)(2*stat->nprimalresolvelpiterations / stat->nprimalresolvelps)
4669  : stat->nprimallps > 0 ? (int)((stat->nprimallpiterations / stat->nprimallps) / 5)
4670  : 0;
4671  if( iter/2 >= itlim )
4672  iter = 2*itlim;
4673  }
4674  SCIPstatAdd(stat, set, nstrongbranchs, ncols);
4675  SCIPstatAdd(stat, set, nsblpiterations, iter);
4676  if( stat->nnodes == 1 )
4677  {
4678  SCIPstatAdd(stat, set, nrootstrongbranchs, ncols);
4679  SCIPstatAdd(stat, set, nrootsblpiterations, iter);
4680  }
4681  }
4682 
4683  SCIPsetFreeBufferArray(set, &sbupvalid);
4684  SCIPsetFreeBufferArray(set, &sbdownvalid);
4685  SCIPsetFreeBufferArray(set, &sbup);
4686  SCIPsetFreeBufferArray(set, &sbdown);
4687  SCIPsetFreeBufferArray(set, &primsols);
4688  SCIPsetFreeBufferArray(set, &lpipos);
4689  SCIPsetFreeBufferArray(set, &subidx);
4690  SCIPsetFreeBufferArray(set, &subcols);
4691 
4692  /* stop timing */
4693  SCIPclockStop(stat->strongbranchtime, set);
4694 
4695  return SCIP_OKAY;
4696 }
4697 
4698 /** gets last strong branching information available for a column variable;
4699  * returns values of SCIP_INVALID, if strong branching was not yet called on the given column;
4700  * keep in mind, that the returned old values may have nothing to do with the current LP solution
4701  */
4703  SCIP_COL* col, /**< LP column */
4704  SCIP_Real* down, /**< stores dual bound after branching column down, or NULL */
4705  SCIP_Real* up, /**< stores dual bound after branching column up, or NULL */
4706  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound, or NULL;
4707  * otherwise, it can only be used as an estimate value */
4708  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound, or NULL;
4709  * otherwise, it can only be used as an estimate value */
4710  SCIP_Real* solval, /**< stores LP solution value of column at last strong branching call, or NULL */
4711  SCIP_Real* lpobjval /**< stores LP objective value at last strong branching call, or NULL */
4712  )
4713 {
4714  assert(col != NULL);
4715 
4716  if( down != NULL )
4717  *down = col->sbdown;
4718  if( up != NULL )
4719  *up = col->sbup;
4720  if( downvalid != NULL )
4721  *downvalid = col->sbdownvalid;
4722  if( upvalid != NULL )
4723  *upvalid = col->sbupvalid;
4724  if( solval != NULL )
4725  *solval = col->sbsolval;
4726  if( lpobjval != NULL )
4727  *lpobjval = col->sblpobjval;
4728 }
4729 
4730 /** if strong branching was already applied on the column at the current node, returns the number of LPs solved after
4731  * the LP where the strong branching on this column was applied;
4732  * if strong branching was not yet applied on the column at the current node, returns INT_MAX
4733  */
4735  SCIP_COL* col, /**< LP column */
4736  SCIP_STAT* stat /**< dynamic problem statistics */
4737  )
4738 {
4739  assert(col != NULL);
4740  assert(stat != NULL);
4741 
4742  return (col->sbnode != stat->nnodes ? SCIP_LONGINT_MAX : stat->nlps - col->validsblp);
4743 }
4744 
4745 /** marks a column to be not removable from the LP in the current node because it became obsolete */
4747  SCIP_COL* col, /**< LP column */
4748  SCIP_STAT* stat /**< problem statistics */
4749  )
4750 {
4751  assert(col != NULL);
4752  assert(stat != NULL);
4753  assert(stat->nnodes > 0);
4754 
4755  /* lpRemoveObsoleteCols() does not remove a column if the node number stored in obsoletenode equals the current node number */
4756  col->obsoletenode = stat->nnodes;
4757 }
4758 
4759 
4760 /*
4761  * Row methods
4762  */
4763 
4764 /** calculates row norms and min/maxidx from scratch, and checks for sorting */
4765 static
4767  SCIP_ROW* row, /**< LP row */
4768  SCIP_SET* set /**< global SCIP settings */
4769  )
4770 {
4771  int i;
4772 
4773  assert(row != NULL);
4774  assert(set != NULL);
4775 
4776  row->sqrnorm = 0.0;
4777  row->sumnorm = 0.0;
4778  row->objprod = 0.0;
4779  row->maxval = 0.0;
4780  row->nummaxval = 1;
4781  row->minval = SCIPsetInfinity(set);
4782  row->numminval = 1;
4783  row->minidx = INT_MAX;
4784  row->maxidx = INT_MIN;
4785  row->validminmaxidx = TRUE;
4786  row->lpcolssorted = TRUE;
4787  row->nonlpcolssorted = TRUE;
4788 
4789  /* check, if row is sorted
4790  * calculate sqrnorm, sumnorm, maxval, minval, minidx, and maxidx
4791  */
4792  for( i = 0; i < row->nlpcols; ++i )
4793  {
4794  assert(row->cols[i] != NULL);
4795  assert(!SCIPsetIsZero(set, row->vals[i]));
4796  assert(row->cols[i]->lppos >= 0);
4797  assert(row->linkpos[i] >= 0);
4798  assert(row->cols[i]->index == row->cols_index[i]);
4799 
4800  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4801  if( i > 0 )
4802  {
4803  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4804  row->lpcolssorted = row->lpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4805  }
4806  }
4807  for( i = row->nlpcols; i < row->len; ++i )
4808  {
4809  assert(row->cols[i] != NULL);
4810  assert(!SCIPsetIsZero(set, row->vals[i]));
4811  assert(row->cols[i]->lppos == -1 || row->linkpos[i] == -1);
4812  assert(row->cols[i]->index == row->cols_index[i]);
4813 
4814  rowAddNorms(row, set, row->cols[i], row->vals[i], TRUE);
4815  if( i > row->nlpcols )
4816  {
4817  assert(row->cols[i-1]->index == row->cols_index[i-1]);
4818  row->nonlpcolssorted = row->nonlpcolssorted && (row->cols_index[i-1] < row->cols_index[i]);
4819  }
4820  }
4821 }
4822 
4823 /** calculates min/maxval and min/maxidx from scratch */
4824 static
4826  SCIP_ROW* row, /**< LP row */
4827  SCIP_SET* set /**< global SCIP settings */
4828  )
4829 {
4830  SCIP_COL* col;
4831  SCIP_Real absval;
4832  int i;
4833 
4834  assert(row != NULL);
4835  assert(set != NULL);
4836 
4837  row->maxval = 0.0;
4838  row->nummaxval = 1;
4839  row->numintcols = 0;
4840  row->minval = SCIPsetInfinity(set);
4841  row->numminval = 1;
4842  row->minidx = INT_MAX;
4843  row->maxidx = INT_MIN;
4844  row->validminmaxidx = TRUE;
4845 
4846  /* calculate maxval, minval, minidx, and maxidx */
4847  for( i = 0; i < row->len; ++i )
4848  {
4849  col = row->cols[i];
4850  assert(col != NULL);
4851  assert(!SCIPsetIsZero(set, row->vals[i]));
4852 
4853  absval = REALABS(row->vals[i]);
4854  assert(!SCIPsetIsZero(set, absval));
4855 
4856  /* update min/maxidx */
4857  row->minidx = MIN(row->minidx, col->index);
4858  row->maxidx = MAX(row->maxidx, col->index);
4859  row->numintcols += SCIPcolIsIntegral(col); /*lint !e713*/
4860 
4861  /* update maximal and minimal non-zero value */
4862  if( row->nummaxval > 0 )
4863  {
4864  if( SCIPsetIsGT(set, absval, row->maxval) )
4865  {
4866  row->maxval = absval;
4867  row->nummaxval = 1;
4868  }
4869  else if( SCIPsetIsGE(set, absval, row->maxval) )
4870  {
4871  /* make sure the maxval is always exactly the same */
4872  row->maxval = MAX(absval, row->maxval);
4873  row->nummaxval++;
4874  }
4875  }
4876  if( row->numminval > 0 )
4877  {
4878  if( SCIPsetIsLT(set, absval, row->minval) )
4879  {
4880  row->minval = absval;
4881  row->numminval = 1;
4882  }
4883  else if( SCIPsetIsLE(set, absval, row->minval) )
4884  {
4885  /* make sure the minval is always exactly the same */
4886  row->minval = MIN(absval, row->minval);
4887  row->numminval++;
4888  }
4889  }
4890  }
4891 }
4892 
4893 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
4894 static
4896  SCIP_Real val, /**< value that should be scaled to an integral value */
4897  SCIP_Real scalar, /**< scalar that should be tried */
4898  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
4899  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
4900  SCIP_Real* intval /**< pointer to store the scaled integral value, or NULL */
4901  )
4902 {
4903  SCIP_Real sval;
4904  SCIP_Real downval;
4905  SCIP_Real upval;
4906 
4907  assert(mindelta <= 0.0);
4908  assert(maxdelta >= 0.0);
4909 
4910  sval = val * scalar;
4911  downval = floor(sval);
4912  upval = ceil(sval);
4913 
4914  if( SCIPrelDiff(sval, downval) <= maxdelta )
4915  {
4916  if( intval != NULL )
4917  *intval = downval;
4918  return TRUE;
4919  }
4920  else if( SCIPrelDiff(sval, upval) >= mindelta )
4921  {
4922  if( intval != NULL )
4923  *intval = upval;
4924  return TRUE;
4925  }
4926 
4927  return FALSE;
4928 }
4929 
4930 /** scales row with given factor, and rounds coefficients to integers if close enough;
4931  * the constant is automatically moved to the sides;
4932  * if the row's activity is proven to be integral, the sides are automatically rounded to the next integer
4933  */
4934 static
4936  SCIP_ROW* row, /**< LP row */
4937  BMS_BLKMEM* blkmem, /**< block memory */
4938  SCIP_SET* set, /**< global SCIP settings */
4939  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
4940  SCIP_STAT* stat, /**< problem statistics */
4941  SCIP_LP* lp, /**< current LP data */
4942  SCIP_Real scaleval, /**< value to scale row with */
4943  SCIP_Bool integralcontvars, /**< should the coefficients of the continuous variables also be made integral,
4944  * if they are close to integral values? */
4945  SCIP_Real minrounddelta, /**< minimal relative difference of scaled coefficient s*c and integral i,
4946  * upto which the integral is used instead of the scaled real coefficient */
4947  SCIP_Real maxrounddelta /**< maximal relative difference of scaled coefficient s*c and integral i
4948  * upto which the integral is used instead of the scaled real coefficient */
4949  )
4950 {
4951  SCIP_COL* col;
4952  SCIP_Real val;
4953  SCIP_Real newval;
4954  SCIP_Real intval;
4955  SCIP_Real mindelta;
4956  SCIP_Real maxdelta;
4957  SCIP_Real lb;
4958  SCIP_Real ub;
4959  SCIP_Bool mindeltainf;
4960  SCIP_Bool maxdeltainf;
4961  int oldlen;
4962  int c;
4963 
4964  assert(row != NULL);
4965  assert(row->len == 0 || row->cols != NULL);
4966  assert(row->len == 0 || row->vals != NULL);
4967  assert(SCIPsetIsPositive(set, scaleval));
4968  assert(-1.0 < minrounddelta && minrounddelta <= 0.0);
4969  assert(0.0 <= maxrounddelta && maxrounddelta < 1.0);
4970 
4971  SCIPsetDebugMsg(set, "scale row <%s> with %g (tolerance=[%g,%g])\n", row->name, scaleval, minrounddelta, maxrounddelta);
4972 
4973  mindelta = 0.0;
4974  maxdelta = 0.0;
4975  mindeltainf = FALSE;
4976  maxdeltainf = FALSE;
4977  oldlen = row->len;
4978 
4979  /* scale the row coefficients, thereby recalculating whether the row's activity is always integral;
4980  * if the row coefficients are rounded to the nearest integer value, calculate the maximal activity difference,
4981  * this rounding can lead to
4982  */
4983  row->integral = TRUE;
4984 
4985  c = 0;
4986  while( c < row->len )
4987  {
4988  col = row->cols[c];
4989  val = row->vals[c];
4990  assert(!SCIPsetIsZero(set, val));
4991 
4992  /* get local or global bounds for column, depending on the local or global feasibility of the row */
4993  if( row->local )
4994  {
4995  lb = col->lb;
4996  ub = col->ub;
4997  }
4998  else
4999  {
5000  lb = SCIPvarGetLbGlobal(col->var);
5001  ub = SCIPvarGetUbGlobal(col->var);
5002  }
5003 
5004  /* calculate scaled coefficient */
5005  newval = val * scaleval;
5006  if( (integralcontvars || SCIPcolIsIntegral(col) || SCIPsetIsIntegral(set, newval))
5007  && isIntegralScalar(val, scaleval, minrounddelta, maxrounddelta, &intval) )
5008  {
5009  if( !SCIPsetIsEQ(set, intval, newval) )
5010  {
5011  if( intval < newval )
5012  {
5013  mindelta += (intval - newval)*ub;
5014  maxdelta += (intval - newval)*lb;
5015  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, ub);
5016  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, -lb);
5017  }
5018  else
5019  {
5020  mindelta += (intval - newval)*lb;
5021  maxdelta += (intval - newval)*ub;
5022  mindeltainf = mindeltainf || SCIPsetIsInfinity(set, -lb);
5023  maxdeltainf = maxdeltainf || SCIPsetIsInfinity(set, ub);
5024  }
5025  }
5026  newval = intval;
5027  }
5028 
5029  if( !SCIPsetIsEQ(set, val, newval) )
5030  {
5031  /* if column knows of the row, change the corresponding coefficient in the column */
5032  if( row->linkpos[c] >= 0 )
5033  {
5034  assert(col->rows[row->linkpos[c]] == row);
5035  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[c]], row->vals[c]));
5036  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[c], newval) );
5037  }
5038 
5039  /* change the coefficient in the row, and update the norms and integrality status */
5040  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, c, newval) );
5041 
5042  /* current coefficient has been deleted from the row because it was almost zero */
5043  if( oldlen != row->len )
5044  {
5045  assert(row->len == oldlen - 1);
5046  c--;
5047  oldlen = row->len;
5048  }
5049  }
5050  else
5051  row->integral = row->integral && SCIPcolIsIntegral(col) && SCIPsetIsIntegral(set, val);
5052 
5053  ++c;
5054  }
5055 
5056  /* scale the row sides, and move the constant to the sides; relax the sides with accumulated delta in order
5057  * to not destroy feasibility due to rounding
5058  */
5059  /**@todo ensure that returned cut does not have infinite lhs and rhs */
5060  if( !SCIPsetIsInfinity(set, -row->lhs) )
5061  {
5062  if( mindeltainf )
5063  newval = -SCIPsetInfinity(set);
5064  else
5065  {
5066  newval = (row->lhs - row->constant) * scaleval + mindelta;
5067  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5068  newval = SCIPsetSumCeil(set, newval);
5069  }
5070  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, newval) );
5071  }
5072  if( !SCIPsetIsInfinity(set, row->rhs) )
5073  {
5074  if( maxdeltainf )
5075  newval = SCIPsetInfinity(set);
5076  else
5077  {
5078  newval = (row->rhs - row->constant) * scaleval + maxdelta;
5079  if( SCIPsetIsIntegral(set, newval) || (row->integral && !row->modifiable) )
5080  newval = SCIPsetSumFloor(set, newval);
5081  }
5082  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, newval) );
5083  }
5084 
5085  /* clear the row constant */
5086  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, 0.0) );
5087 
5088  SCIPsetDebugMsg(set, "scaled row <%s> (integral: %u)\n", row->name, row->integral);
5089  debugRowPrint(set, row);
5090 
5091 #ifdef SCIP_DEBUG
5092  /* check integrality status of row */
5093  for( c = 0; c < row->len && SCIPcolIsIntegral(row->cols[c]) && SCIPsetIsIntegral(set, row->vals[c]); ++c )
5094  {}
5095  assert(row->integral == (c == row->len));
5096 #endif
5097 
5098  /* invalid the activity */
5099  row->validactivitylp = -1;
5100 
5101  return SCIP_OKAY;
5102 }
5103 
5104 /** creates and captures an LP row */
5106  SCIP_ROW** row, /**< pointer to LP row data */
5107  BMS_BLKMEM* blkmem, /**< block memory */
5108  SCIP_SET* set, /**< global SCIP settings */
5109  SCIP_STAT* stat, /**< problem statistics */
5110  const char* name, /**< name of row */
5111  int len, /**< number of nonzeros in the row */
5112  SCIP_COL** cols, /**< array with columns of row entries */
5113  SCIP_Real* vals, /**< array with coefficients of row entries */
5114  SCIP_Real lhs, /**< left hand side of row */
5115  SCIP_Real rhs, /**< right hand side of row */
5116  SCIP_ROWORIGINTYPE origintype, /**< type of origin of row */
5117  void* origin, /**< pointer to constraint handler or separator who created the row (NULL if unkown) */
5118  SCIP_Bool local, /**< is row only valid locally? */
5119  SCIP_Bool modifiable, /**< is row modifiable during node processing (subject to column generation)? */
5120  SCIP_Bool removable /**< should the row be removed from the LP due to aging or cleanup? */
5121  )
5122 {
5123  assert(row != NULL);
5124  assert(blkmem != NULL);
5125  assert(stat != NULL);
5126  assert(len >= 0);
5127  assert(len == 0 || (cols != NULL && vals != NULL));
5128  /* note, that the assert tries to avoid numerical troubles in the LP solver.
5129  * in case, for example, lhs > rhs but they are equal with tolerances, one could pass lhs=rhs=lhs+rhs/2 to
5130  * SCIProwCreate() (see cons_linear.c: detectRedundantConstraints())
5131  */
5132  assert(lhs <= rhs);
5133 
5134  SCIP_ALLOC( BMSallocBlockMemory(blkmem, row) );
5135 
5136  (*row)->integral = TRUE;
5137  if( len > 0 )
5138  {
5139  SCIP_VAR* var;
5140  int i;
5141 
5142  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->cols, cols, len) );
5143  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->vals, vals, len) );
5144  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->cols_index, len) );
5145  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*row)->linkpos, len) );
5146 
5147  for( i = 0; i < len; ++i )
5148  {
5149  assert(cols[i] != NULL);
5150  assert(!SCIPsetIsZero(set, vals[i]));
5151 
5152  var = cols[i]->var;
5153  (*row)->cols_index[i] = cols[i]->index;
5154  (*row)->linkpos[i] = -1;
5155  if( SCIPsetIsIntegral(set, (*row)->vals[i]) )
5156  {
5157  (*row)->vals[i] = SCIPsetRound(set, (*row)->vals[i]);
5158  (*row)->integral = (*row)->integral && SCIPvarIsIntegral(var);
5159  }
5160  else
5161  {
5162  (*row)->integral = FALSE;
5163  }
5164  }
5165  }
5166  else
5167  {
5168  (*row)->cols = NULL;
5169  (*row)->cols_index = NULL;
5170  (*row)->vals = NULL;
5171  (*row)->linkpos = NULL;
5172  }
5173 
5174  SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*row)->name, name, strlen(name)+1) );
5175  (*row)->constant = 0.0;
5176  (*row)->lhs = lhs;
5177  (*row)->rhs = rhs;
5178  (*row)->flushedlhs = -SCIPsetInfinity(set);
5179  (*row)->flushedrhs = SCIPsetInfinity(set);
5180  (*row)->sqrnorm = 0.0;
5181  (*row)->sumnorm = 0.0;
5182  (*row)->objprod = 0.0;
5183  (*row)->maxval = 0.0;
5184  (*row)->minval = SCIPsetInfinity(set);
5185  (*row)->dualsol = 0.0;
5186  (*row)->activity = SCIP_INVALID;
5187  (*row)->dualfarkas = 0.0;
5188  (*row)->pseudoactivity = SCIP_INVALID;
5189  (*row)->minactivity = SCIP_INVALID;
5190  (*row)->maxactivity = SCIP_INVALID;
5191  (*row)->origin = origin;
5192  (*row)->eventfilter = NULL;
5193  (*row)->index = stat->nrowidx;
5194  SCIPstatIncrement(stat, set, nrowidx);
5195  (*row)->size = len;
5196  (*row)->len = len;
5197  (*row)->nlpcols = 0;
5198  (*row)->nunlinked = len;
5199  (*row)->nuses = 0;
5200  (*row)->lppos = -1;
5201  (*row)->lpipos = -1;
5202  (*row)->lpdepth = -1;
5203  (*row)->minidx = INT_MAX;
5204  (*row)->maxidx = INT_MIN;
5205  (*row)->nummaxval = 0;
5206  (*row)->numminval = 0;
5207  (*row)->numintcols = -1;
5208  (*row)->validactivitylp = -1;
5209  (*row)->validpsactivitydomchg = -1;
5210  (*row)->validactivitybdsdomchg = -1;
5211  (*row)->nlpsaftercreation = 0L;
5212  (*row)->activeinlpcounter = 0L;
5213  (*row)->age = 0;
5214  (*row)->rank = 0;
5215  (*row)->obsoletenode = -1;
5216  (*row)->fromcutpool = FALSE;
5217  (*row)->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
5218  (*row)->lpcolssorted = TRUE;
5219  (*row)->nonlpcolssorted = (len <= 1);
5220  (*row)->delaysort = FALSE;
5221  (*row)->validminmaxidx = FALSE;
5222  (*row)->lhschanged = FALSE;
5223  (*row)->rhschanged = FALSE;
5224  (*row)->coefchanged = FALSE;
5225  (*row)->local = local;
5226  (*row)->modifiable = modifiable;
5227  (*row)->nlocks = 0;
5228  (*row)->origintype = origintype; /*lint !e641*/
5229  (*row)->removable = removable;
5230  (*row)->inglobalcutpool = FALSE;
5231  (*row)->storedsolvals = NULL;
5232 
5233  /* calculate row norms and min/maxidx, and check if row is sorted */
5234  rowCalcNorms(*row, set);
5235 
5236  /* capture the row */
5237  SCIProwCapture(*row);
5238 
5239  /* create event filter */
5240  SCIP_CALL( SCIPeventfilterCreate(&(*row)->eventfilter, blkmem) );
5241 
5242  /* capture origin constraint if available */
5243  if( origintype == SCIP_ROWORIGINTYPE_CONS )
5244  {
5245  SCIP_CONS* cons = (SCIP_CONS*) origin;
5246  assert(cons != NULL);
5247  SCIPconsCapture(cons);
5248  }
5249 
5250  return SCIP_OKAY;
5251 } /*lint !e715*/
5252 
5253 /** frees an LP row */
5255  SCIP_ROW** row, /**< pointer to LP row */
5256  BMS_BLKMEM* blkmem, /**< block memory */
5257  SCIP_SET* set, /**< global SCIP settings */
5258  SCIP_LP* lp /**< current LP data */
5259  )
5260 {
5261  assert(blkmem != NULL);
5262  assert(row != NULL);
5263  assert(*row != NULL);
5264  assert((*row)->nuses == 0);
5265  assert((*row)->lppos == -1);
5266  assert((*row)->eventfilter != NULL);
5267 
5268  /* release constraint that has been used for creating the row */
5269  if( (SCIP_ROWORIGINTYPE) (*row)->origintype == SCIP_ROWORIGINTYPE_CONS )
5270  {
5271  SCIP_CONS* cons = (SCIP_CONS*) (*row)->origin;
5272  assert(cons != NULL);
5273  SCIP_CALL( SCIPconsRelease(&cons, blkmem, set) );
5274  }
5275 
5276  /* remove column indices from corresponding rows */
5277  SCIP_CALL( rowUnlink(*row, set, lp) );
5278 
5279  /* free event filter */
5280  SCIP_CALL( SCIPeventfilterFree(&(*row)->eventfilter, blkmem, set) );
5281 
5282  BMSfreeBlockMemoryNull(blkmem, &(*row)->storedsolvals);
5283  BMSfreeBlockMemoryArray(blkmem, &(*row)->name, strlen((*row)->name)+1);
5284  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols, (*row)->size);
5285  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->cols_index, (*row)->size);
5286  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->vals, (*row)->size);
5287  BMSfreeBlockMemoryArrayNull(blkmem, &(*row)->linkpos, (*row)->size);
5288  BMSfreeBlockMemory(blkmem, row);
5289 
5290  return SCIP_OKAY;
5291 }
5292 
5293 /** output row to file stream */
5295  SCIP_ROW* row, /**< LP row */
5296  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
5297  FILE* file /**< output file (or NULL for standard output) */
5298  )
5299 {
5300  int i;
5301 
5302  assert(row != NULL);
5303 
5304  /* print row name */
5305  if( row->name != NULL && row->name[0] != '\0' )
5306  {
5307  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", row->name);
5308  }
5309 
5310  /* print left hand side */
5311  SCIPmessageFPrintInfo(messagehdlr, file, "%.15g <= ", row->lhs);
5312 
5313  /* print coefficients */
5314  if( row->len == 0 )
5315  SCIPmessageFPrintInfo(messagehdlr, file, "0 ");
5316  for( i = 0; i < row->len; ++i )
5317  {
5318  assert(row->cols[i] != NULL);
5319  assert(row->cols[i]->var != NULL);
5320  assert(SCIPvarGetName(row->cols[i]->var) != NULL);
5321  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
5322  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g<%s> ", row->vals[i], SCIPvarGetName(row->cols[i]->var));
5323  }
5324 
5325  /* print constant */
5326  if( REALABS(row->constant) > SCIP_DEFAULT_EPSILON )
5327  SCIPmessageFPrintInfo(messagehdlr, file, "%+.15g ", row->constant);
5328 
5329  /* print right hand side */
5330  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g\n", row->rhs);
5331 }
5332 
5333 /** increases usage counter of LP row */
5335  SCIP_ROW* row /**< LP row */
5336  )
5337 {
5338  assert(row != NULL);
5339  assert(row->nuses >= 0);
5340  assert(row->nlocks <= (unsigned int)(row->nuses)); /*lint !e574*/
5341 
5342  SCIPdebugMessage("capture row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5343  row->nuses++;
5344 }
5345 
5346 /** decreases usage counter of LP row, and frees memory if necessary */
5348  SCIP_ROW** row, /**< pointer to LP row */
5349  BMS_BLKMEM* blkmem, /**< block memory */
5350  SCIP_SET* set, /**< global SCIP settings */
5351  SCIP_LP* lp /**< current LP data */
5352  )
5353 {
5354  assert(blkmem != NULL);
5355  assert(row != NULL);
5356  assert(*row != NULL);
5357  assert((*row)->nuses >= 1);
5358  assert((*row)->nlocks < (unsigned int)((*row)->nuses)); /*lint !e574*/
5359 
5360  SCIPsetDebugMsg(set, "release row <%s> with nuses=%d and nlocks=%u\n", (*row)->name, (*row)->nuses, (*row)->nlocks);
5361  (*row)->nuses--;
5362  if( (*row)->nuses == 0 )
5363  {
5364  SCIP_CALL( SCIProwFree(row, blkmem, set, lp) );
5365  }
5366 
5367  *row = NULL;
5368 
5369  return SCIP_OKAY;
5370 }
5371 
5372 /** locks an unmodifiable row, which forbids further changes; has no effect on modifiable rows */
5374  SCIP_ROW* row /**< LP row */
5375  )
5376 {
5377  assert(row != NULL);
5378 
5379  /* check, if row is modifiable */
5380  if( !row->modifiable )
5381  {
5382  SCIPdebugMessage("lock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5383  row->nlocks++;
5384  }
5385 }
5386 
5387 /** unlocks a lock of an unmodifiable row; a row with no sealed lock may be modified; has no effect on modifiable rows */
5389  SCIP_ROW* row /**< LP row */
5390  )
5391 {
5392  assert(row != NULL);
5393 
5394  /* check, if row is modifiable */
5395  if( !row->modifiable )
5396  {
5397  SCIPdebugMessage("unlock row <%s> with nuses=%d and nlocks=%u\n", row->name, row->nuses, row->nlocks);
5398  assert(row->nlocks > 0);
5399  row->nlocks--;
5400  }
5401 }
5402 
5403 /** adds a previously non existing coefficient to an LP row */
5405  SCIP_ROW* row, /**< LP row */
5406  BMS_BLKMEM* blkmem, /**< block memory */
5407  SCIP_SET* set, /**< global SCIP settings */
5408  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5409  SCIP_LP* lp, /**< current LP data */
5410  SCIP_COL* col, /**< LP column */
5411  SCIP_Real val /**< value of coefficient */
5412  )
5413 {
5414  assert(lp != NULL);
5415  assert(!lp->diving || row->lppos == -1);
5416 
5417  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5418 
5419  checkLinks(lp);
5420 
5421  return SCIP_OKAY;
5422 }
5423 
5424 /** deletes coefficient from row */
5426  SCIP_ROW* row, /**< row to be changed */
5427  BMS_BLKMEM* blkmem, /**< block memory */
5428  SCIP_SET* set, /**< global SCIP settings */
5429  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5430  SCIP_LP* lp, /**< current LP data */
5431  SCIP_COL* col /**< coefficient to be deleted */
5432  )
5433 {
5434  int pos;
5435 
5436  assert(row != NULL);
5437  assert(!row->delaysort);
5438  assert(lp != NULL);
5439  assert(!lp->diving || row->lppos == -1);
5440  assert(col != NULL);
5441  assert(col->var != NULL);
5442 
5443  /* search the position of the column in the row's col vector */
5444  pos = rowSearchCoef(row, col);
5445  if( pos == -1 )
5446  {
5447  SCIPerrorMessage("coefficient for column <%s> doesn't exist in row <%s>\n", SCIPvarGetName(col->var), row->name);
5448  return SCIP_INVALIDDATA;
5449  }
5450  assert(0 <= pos && pos < row->len);
5451  assert(row->cols[pos] == col);
5452  assert(row->cols_index[pos] == col->index);
5453 
5454  /* if column knows of the row, remove the row from the column's row vector */
5455  if( row->linkpos[pos] >= 0 )
5456  {
5457  assert(col->rows[row->linkpos[pos]] == row);
5458  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5459  SCIP_CALL( colDelCoefPos(col, set, lp, row->linkpos[pos]) );
5460  }
5461 
5462  /* delete the column from the row's col vector */
5463  SCIP_CALL( rowDelCoefPos(row, blkmem, set, eventqueue, lp, pos) );
5464 
5465  checkLinks(lp);
5466 
5467  return SCIP_OKAY;
5468 }
5469 
5470 /** changes or adds a coefficient to an LP row */
5472  SCIP_ROW* row, /**< LP row */
5473  BMS_BLKMEM* blkmem, /**< block memory */
5474  SCIP_SET* set, /**< global SCIP settings */
5475  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5476  SCIP_LP* lp, /**< current LP data */
5477  SCIP_COL* col, /**< LP column */
5478  SCIP_Real val /**< value of coefficient */
5479  )
5480 {
5481  int pos;
5482 
5483  assert(row != NULL);
5484  assert(!row->delaysort);
5485  assert(lp != NULL);
5486  assert(!lp->diving || row->lppos == -1);
5487  assert(col != NULL);
5488 
5489  /* search the position of the column in the row's col vector */
5490  pos = rowSearchCoef(row, col);
5491 
5492  /* check, if column already exists in the row's col vector */
5493  if( pos == -1 )
5494  {
5495  /* add previously not existing coefficient */
5496  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, val, -1) );
5497  }
5498  else
5499  {
5500  /* modify already existing coefficient */
5501  assert(0 <= pos && pos < row->len);
5502  assert(row->cols[pos] == col);
5503  assert(row->cols_index[pos] == col->index);
5504 
5505  /* if column knows of the row, change the corresponding coefficient in the column */
5506  if( row->linkpos[pos] >= 0 )
5507  {
5508  assert(col->rows[row->linkpos[pos]] == row);
5509  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5510  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], val) );
5511  }
5512 
5513  /* change the coefficient in the row */
5514  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, val) );
5515  }
5516 
5517  checkLinks(lp);
5518 
5519  return SCIP_OKAY;
5520 }
5521 
5522 /** increases value of an existing or non-existing coefficient in an LP row */
5524  SCIP_ROW* row, /**< LP row */
5525  BMS_BLKMEM* blkmem, /**< block memory */
5526  SCIP_SET* set, /**< global SCIP settings */
5527  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5528  SCIP_LP* lp, /**< current LP data */
5529  SCIP_COL* col, /**< LP column */
5530  SCIP_Real incval /**< value to add to the coefficient */
5531  )
5532 {
5533  int pos;
5534 
5535  assert(row != NULL);
5536  assert(lp != NULL);
5537  assert(!lp->diving || row->lppos == -1);
5538  assert(col != NULL);
5539 
5540  if( SCIPsetIsZero(set, incval) )
5541  return SCIP_OKAY;
5542 
5543  /* search the position of the column in the row's col vector */
5544  pos = rowSearchCoef(row, col);
5545 
5546  /* check, if column already exists in the row's col vector */
5547  if( pos == -1 )
5548  {
5549  /* coefficient doesn't exist, or sorting is delayed: add coefficient to the end of the row's arrays */
5550  SCIP_CALL( rowAddCoef(row, blkmem, set, eventqueue, lp, col, incval, -1) );
5551  }
5552  else
5553  {
5554  /* modify already existing coefficient */
5555  assert(0 <= pos && pos < row->len);
5556  assert(row->cols[pos] == col);
5557  assert(row->cols_index[pos] == col->index);
5558 
5559  /* if column knows of the row, change the corresponding coefficient in the column */
5560  if( row->linkpos[pos] >= 0 )
5561  {
5562  assert(col->rows[row->linkpos[pos]] == row);
5563  assert(SCIPsetIsEQ(set, col->vals[row->linkpos[pos]], row->vals[pos]));
5564  SCIP_CALL( colChgCoefPos(col, set, lp, row->linkpos[pos], row->vals[pos] + incval) );
5565  }
5566 
5567  /* change the coefficient in the row */
5568  SCIP_CALL( rowChgCoefPos(row, blkmem, set, eventqueue, lp, pos, row->vals[pos] + incval) );
5569  }
5570 
5571  checkLinks(lp);
5572 
5573  /* invalid the activity */
5574  row->validactivitylp = -1;
5575 
5576  return SCIP_OKAY;
5577 }
5578 
5579 /** changes constant value of a row */
5581  SCIP_ROW* row, /**< LP row */
5582  BMS_BLKMEM* blkmem, /**< block memory */
5583  SCIP_SET* set, /**< global SCIP settings */
5584  SCIP_STAT* stat, /**< problem statistics */
5585  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5586  SCIP_LP* lp, /**< current LP data */
5587  SCIP_Real constant /**< new constant value */
5588  )
5589 {
5590  assert(row != NULL);
5591  assert(row->lhs <= row->rhs);
5592  assert(!SCIPsetIsInfinity(set, REALABS(constant)));
5593  assert(stat != NULL);
5594  assert(lp != NULL);
5595  assert(!lp->diving || row->lppos == -1);
5596 
5597  if( !SCIPsetIsEQ(set, constant, row->constant) )
5598  {
5599  SCIP_Real oldconstant;
5600 
5601  if( row->validpsactivitydomchg == stat->domchgcount )
5602  {
5603  assert(row->pseudoactivity < SCIP_INVALID);
5604  row->pseudoactivity += constant - row->constant;
5605  }
5606  if( row->validactivitybdsdomchg == stat->domchgcount )
5607  {
5608  assert(row->minactivity < SCIP_INVALID);
5609  assert(row->maxactivity < SCIP_INVALID);
5610  row->minactivity += constant - row->constant;
5611  row->maxactivity += constant - row->constant;
5612  }
5613 
5614  if( !SCIPsetIsInfinity(set, -row->lhs) )
5615  {
5616  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5617  }
5618  if( !SCIPsetIsInfinity(set, row->rhs) )
5619  {
5620  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5621  }
5622 
5623  oldconstant = row->constant;
5624 
5625  row->constant = constant;
5626 
5627  /* issue row constant changed event */
5628  SCIP_CALL( rowEventConstantChanged(row, blkmem, set, eventqueue, oldconstant, constant) );
5629  }
5630 
5631  return SCIP_OKAY;
5632 }
5633 
5634 /** add constant value to a row */
5636  SCIP_ROW* row, /**< LP row */
5637  BMS_BLKMEM* blkmem, /**< block memory */
5638  SCIP_SET* set, /**< global SCIP settings */
5639  SCIP_STAT* stat, /**< problem statistics */
5640  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5641  SCIP_LP* lp, /**< current LP data */
5642  SCIP_Real addval /**< constant value to add to the row */
5643  )
5644 {
5645  assert(row != NULL);
5646  assert(row->lhs <= row->rhs);
5647  assert(!SCIPsetIsInfinity(set, REALABS(addval)));
5648  assert(stat != NULL);
5649  assert(lp != NULL);
5650  assert(!lp->diving || row->lppos == -1);
5651 
5652  if( !SCIPsetIsZero(set, addval) )
5653  {
5654  SCIP_CALL( SCIProwChgConstant(row, blkmem, set, stat, eventqueue, lp, row->constant + addval) );
5655  }
5656 
5657  return SCIP_OKAY;
5658 }
5659 
5660 /** changes left hand side of LP row */
5662  SCIP_ROW* row, /**< LP row */
5663  BMS_BLKMEM* blkmem, /**< block memory */
5664  SCIP_SET* set, /**< global SCIP settings */
5665  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5666  SCIP_LP* lp, /**< current LP data */
5667  SCIP_Real lhs /**< new left hand side */
5668  )
5669 {
5670  assert(row != NULL);
5671  assert(lp != NULL);
5672 
5673  if( !SCIPsetIsEQ(set, row->lhs, lhs) )
5674  {
5675  SCIP_Real oldlhs;
5676 
5677  oldlhs = row->lhs;
5678 
5679  row->lhs = lhs;
5680  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_LEFT) );
5681 
5682  if( !lp->diving )
5683  {
5684  /* issue row side changed event */
5685  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_LEFT, oldlhs, lhs) );
5686  }
5687  }
5688 
5689  return SCIP_OKAY;
5690 }
5691 
5692 /** changes right hand side of LP row */
5694  SCIP_ROW* row, /**< LP row */
5695  BMS_BLKMEM* blkmem, /**< block memory */
5696  SCIP_SET* set, /**< global SCIP settings */
5697  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5698  SCIP_LP* lp, /**< current LP data */
5699  SCIP_Real rhs /**< new right hand side */
5700  )
5701 {
5702  assert(row != NULL);
5703  assert(lp != NULL);
5704 
5705  if( !SCIPsetIsEQ(set, row->rhs, rhs) )
5706  {
5707  SCIP_Real oldrhs;
5708 
5709  oldrhs = row->rhs;
5710 
5711  row->rhs = rhs;
5712  SCIP_CALL( rowSideChanged(row, set, lp, SCIP_SIDETYPE_RIGHT) );
5713 
5714  if( !lp->diving )
5715  {
5716  /* issue row side changed event */
5717  SCIP_CALL( rowEventSideChanged(row, blkmem, set, eventqueue, SCIP_SIDETYPE_RIGHT, oldrhs, rhs) );
5718  }
5719  }
5720 
5721  return SCIP_OKAY;
5722 }
5723 
5724 /** changes the local flag of LP row */
5726  SCIP_ROW* row, /**< LP row */
5727  SCIP_Bool local /**< new value for local flag */
5728  )
5729 {
5730  assert(row != NULL);
5731 
5732  row->local = local;
5733 
5734  return SCIP_OKAY;
5735 }
5736 
5737 /** additional scalars that are tried in integrality scaling */
5738 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
5739 static const int nscalars = 9;
5740 
5741 /** tries to find a value, such that all row coefficients, if scaled with this value become integral */
5743  SCIP_ROW* row, /**< LP row */
5744  SCIP_SET* set, /**< global SCIP settings */
5745  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5746  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5747  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5748  SCIP_Real maxscale, /**< maximal allowed scalar */
5749  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5750  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
5751  SCIP_Bool* success /**< stores whether returned value is valid */
5752  )
5753 {
5754 #ifndef NDEBUG
5755  SCIP_COL* col;
5756 #endif
5757  SCIP_Longint gcd;
5758  SCIP_Longint scm;
5759  SCIP_Longint nominator;
5760  SCIP_Longint denominator;
5761  SCIP_Real val;
5762  SCIP_Real absval;
5763  SCIP_Real minval;
5764  SCIP_Real scaleval;
5765  SCIP_Real twomultval;
5766  SCIP_Bool scalable;
5767  SCIP_Bool twomult;
5768  SCIP_Bool rational;
5769  int c;
5770  int s;
5771 
5772  /**@todo call misc.c:SCIPcalcIntegralScalar() instead - if usecontvars == FALSE, filter the integer variables first */
5773  assert(row != NULL);
5774  assert(row->len == 0 || row->cols != NULL);
5775  assert(row->len == 0 || row->cols_index != NULL);
5776  assert(row->len == 0 || row->vals != NULL);
5777  assert(maxdnom >= 1);
5778  assert(mindelta < 0.0);
5779  assert(maxdelta > 0.0);
5780  assert(success != NULL);
5781 
5782  SCIPsetDebugMsg(set, "trying to find rational representation for row <%s> (contvars: %u)\n", SCIProwGetName(row), usecontvars);
5783  SCIPdebug( val = 0; ); /* avoid warning "val might be used uninitialized; see SCIPdebugMessage lastval=%g below */
5784 
5785  if( intscalar != NULL )
5786  *intscalar = SCIP_INVALID;
5787  *success = FALSE;
5788 
5789  /* get minimal absolute non-zero value */
5790  minval = SCIP_REAL_MAX;
5791  for( c = 0; c < row->len; ++c )
5792  {
5793 #ifndef NDEBUG
5794  col = row->cols[c];
5795  assert(col != NULL);
5796  assert(col->var != NULL);
5797  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
5798  assert(SCIPvarGetCol(col->var) == col);
5799 #endif
5800  val = row->vals[c];
5801  assert(!SCIPsetIsZero(set, val));
5802 
5803  if( val < mindelta || val > maxdelta )
5804  {
5805  absval = REALABS(val);
5806  minval = MIN(minval, absval);
5807  }
5808  }
5809  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
5810  {
5811  /* all coefficients are zero (inside tolerances) */
5812  if( intscalar != NULL )
5813  *intscalar = 1.0;
5814  *success = TRUE;
5815  SCIPsetDebugMsg(set, " -> all values are zero (inside tolerances)\n");
5816 
5817  return SCIP_OKAY;
5818  }
5819  assert(minval > MIN(-mindelta, maxdelta));
5820  assert(SCIPsetIsPositive(set, minval));
5821  assert(!SCIPsetIsInfinity(set, minval));
5822 
5823  /* try, if row coefficients can be made integral by multiplying them with the reciprocal of the smallest coefficient
5824  * and a power of 2
5825  */
5826  scaleval = 1.0/minval;
5827  scalable = (scaleval <= maxscale);
5828  for( c = 0; c < row->len && scalable; ++c )
5829  {
5830  /* don't look at continuous variables, if we don't have to */
5831  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5832  continue;
5833 
5834  /* check, if the coefficient can be scaled with a simple scalar */
5835  val = row->vals[c];
5836  absval = REALABS(val);
5837  while( scaleval <= maxscale
5838  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta, NULL)) )
5839  {
5840  for( s = 0; s < nscalars; ++s )
5841  {
5842  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta, NULL) )
5843  {
5844  scaleval *= scalars[s];
5845  break;
5846  }
5847  }
5848  if( s >= nscalars )
5849  scaleval *= 2.0;
5850  }
5851  scalable = (scaleval <= maxscale);
5852  SCIPsetDebugMsg(set, " -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n", val, scaleval, val*scaleval, scalable);
5853  }
5854  if( scalable )
5855  {
5856  /* make row coefficients integral by dividing them by the smallest coefficient
5857  * (and multiplying them with a power of 2)
5858  */
5859  assert(scaleval <= maxscale);
5860  if( intscalar != NULL )
5861  *intscalar = scaleval;
5862  *success = TRUE;
5863  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (minval=%g)\n", scaleval, minval);
5864 
5865  return SCIP_OKAY;
5866  }
5867 
5868  /* try, if row coefficients can be made integral by multiplying them by a power of 2 */
5869  twomultval = 1.0;
5870  twomult = (twomultval <= maxscale);
5871  for( c = 0; c < row->len && twomult; ++c )
5872  {
5873  /* don't look at continuous variables, if we don't have to */
5874  if( !usecontvars && !SCIPcolIsIntegral(row->cols[c]) )
5875  continue;
5876 
5877  /* check, if the coefficient can be scaled with a simple scalar */
5878  val = row->vals[c];
5879  absval = REALABS(val);
5880  while( twomultval <= maxscale
5881  && (absval * twomultval < 0.5 || !isIntegralScalar(val, twomultval, mindelta, maxdelta, NULL)) )
5882  {
5883  for( s = 0; s < nscalars; ++s )
5884  {
5885  if( isIntegralScalar(val, twomultval * scalars[s], mindelta, maxdelta, NULL) )
5886  {
5887  twomultval *= scalars[s];
5888  break;
5889  }
5890  }
5891  if( s >= nscalars )
5892  twomultval *= 2.0;
5893  }
5894  twomult = (twomultval <= maxscale);
5895  SCIPsetDebugMsg(set, " -> val=%g, twomult=%g, val*twomult=%g, twomultable=%u\n",
5896  val, twomultval, val*twomultval, twomult);
5897  }
5898  if( twomult )
5899  {
5900  /* make row coefficients integral by multiplying them with a power of 2 */
5901  assert(twomultval <= maxscale);
5902  if( intscalar != NULL )
5903  *intscalar = twomultval;
5904  *success = TRUE;
5905  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (power of 2)\n", twomultval);
5906 
5907  return SCIP_OKAY;
5908  }
5909 
5910  /* convert each coefficient into a rational number, calculate the greatest common divisor of the numerators
5911  * and the smallest common multiple of the denominators
5912  */
5913  gcd = 1;
5914  scm = 1;
5915  rational = (maxdnom > 1);
5916 
5917  /* first coefficient (to initialize gcd) */
5918  for( c = 0; c < row->len && rational; ++c )
5919  {
5920  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5921  {
5922  val = row->vals[c];
5923  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5924  if( rational && nominator != 0 )
5925  {
5926  assert(denominator > 0);
5927  gcd = ABS(nominator);
5928  scm = denominator;
5929  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5930  SCIPsetDebugMsg(set, " -> first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5931  val, nominator, denominator, gcd, scm, rational);
5932  break;
5933  }
5934  }
5935  }
5936 
5937  /* remaining coefficients */
5938  for( ++c; c < row->len && rational; ++c )
5939  {
5940  if( usecontvars || SCIPcolIsIntegral(row->cols[c]) )
5941  {
5942  val = row->vals[c];
5943  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
5944  if( rational && nominator != 0 )
5945  {
5946  assert(denominator > 0);
5947  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
5948  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
5949  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5950  SCIPsetDebugMsg(set, " -> next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
5951  val, nominator, denominator, gcd, scm, rational);
5952  }
5953  }
5954  }
5955 
5956  if( rational )
5957  {
5958  /* make row coefficients integral by multiplying them with the smallest common multiple of the denominators */
5959  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
5960  if( intscalar != NULL )
5961  *intscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
5962  *success = TRUE;
5963  SCIPsetDebugMsg(set, " -> integrality can be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
5964  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
5965  }
5966  else
5967  {
5968  assert(!(*success));
5969  SCIPsetDebugMsg(set, " -> rationalizing failed: gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", lastval=%g\n", gcd, scm, val); /*lint !e771*/
5970  }
5971 
5972  return SCIP_OKAY;
5973 }
5974 
5975 /** tries to scale row, s.t. all coefficients become integral */
5977  SCIP_ROW* row, /**< LP row */
5978  BMS_BLKMEM* blkmem, /**< block memory */
5979  SCIP_SET* set, /**< global SCIP settings */
5980  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
5981  SCIP_STAT* stat, /**< problem statistics */
5982  SCIP_LP* lp, /**< current LP data */
5983  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
5984  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
5985  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
5986  SCIP_Real maxscale, /**< maximal value to scale row with */
5987  SCIP_Bool usecontvars, /**< should the coefficients of the continuous variables also be made integral? */
5988  SCIP_Bool* success /**< stores whether row could be made rational */
5989  )
5990 {
5991  SCIP_Real intscalar;
5992 
5993  assert(success != NULL);
5994 
5995  /* calculate scalar to make coefficients integral */
5996  SCIP_CALL( SCIProwCalcIntegralScalar(row, set, mindelta, maxdelta, maxdnom, maxscale, usecontvars,
5997  &intscalar, success) );
5998 
5999  if( *success )
6000  {
6001  /* scale the row */
6002  SCIP_CALL( rowScale(row, blkmem, set, eventqueue, stat, lp, intscalar, usecontvars, mindelta, maxdelta) );
6003  }
6004 
6005  return SCIP_OKAY;
6006 }
6007 
6008 /** sorts row entries such that LP columns precede non-LP columns and inside both parts lower column indices precede
6009  * higher ones
6010  */
6012  SCIP_ROW* row /**< row to be sorted */
6013  )
6014 {
6015  assert(row != NULL);
6016 
6017  /* sort LP columns */
6018  rowSortLP(row);
6019 
6020  /* sort non-LP columns */
6021  rowSortNonLP(row);
6022 
6023 #ifdef SCIP_MORE_DEBUG
6024  /* check the sorting */
6025  {
6026  int c;
6027  if( !row->delaysort )
6028  {
6029  for( c = 1; c < row->nlpcols; ++c )
6030  assert(row->cols[c]->index >= row->cols[c-1]->index);
6031  for( c = row->nlpcols + 1; c < row->len; ++c )
6032  assert(row->cols[c]->index >= row->cols[c-1]->index);
6033  }
6034  }
6035 #endif
6036 }
6037 
6038 /** sorts row, and merges equal column entries (resulting from lazy sorting and adding) into a single entry; removes
6039  * zero entries from row
6040  * the row must not be linked to the columns; otherwise, we would need to update the columns as
6041  * well, which is too expensive
6042  */
6043 static
6045  SCIP_ROW* row, /**< row to be sorted */
6046  SCIP_SET* set /**< global SCIP settings */
6047  )
6048 {
6049  assert(row != NULL);
6050  assert(!row->delaysort);
6051  assert(row->nunlinked == row->len);
6052  assert(row->nlpcols == 0);
6053 
6054  SCIPsetDebugMsg(set, "merging row <%s>\n", row->name);
6055 
6056  /* do nothing on empty rows; if row is sorted, nothing has to be done */
6057  if( row->len > 0 && (!row->lpcolssorted || !row->nonlpcolssorted) )
6058  {
6059  SCIP_COL** cols;
6060  int* cols_index;
6061  SCIP_Real* vals;
6062  int s;
6063  int t;
6064 
6065  /* make sure, the row is sorted */
6066  SCIProwSort(row);
6067  assert(row->lpcolssorted);
6068  assert(row->nonlpcolssorted);
6069 
6070  /* merge equal columns, thereby recalculating whether the row's activity is always integral */
6071  cols = row->cols;
6072  cols_index = row->cols_index;
6073  vals = row->vals;
6074  assert(cols != NULL);
6075  assert(cols_index != NULL);
6076  assert(vals != NULL);
6077 
6078  t = 0;
6079  row->integral = TRUE;
6080  assert(!SCIPsetIsZero(set, vals[0]));
6081  assert(row->linkpos[0] == -1);
6082 
6083  for( s = 1; s < row->len; ++s )
6084  {
6085  assert(!SCIPsetIsZero(set, vals[s]));
6086  assert(row->linkpos[s] == -1);
6087 
6088  if( cols[s] == cols[t] )
6089  {
6090  /* merge entries with equal column */
6091  vals[t] += vals[s];
6092  }
6093  else
6094  {
6095  /* go to the next entry, overwriting current entry if coefficient is zero */
6096  if( !SCIPsetIsZero(set, vals[t]) )
6097  {
6098  /* in case the coefficient is integral w.r.t. numerics we explicitly round the coefficient to an integral value */
6099  vals[t] = SCIPsetIsIntegral(set, vals[t]) ? SCIPsetRound(set, vals[t]) : vals[t];
6100 
6101  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6102  t++;
6103  }
6104  cols[t] = cols[s];
6105  cols_index[t] = cols_index[s];
6106  vals[t] = vals[s];
6107  }
6108  }
6109  if( !SCIPsetIsZero(set, vals[t]) )
6110  {
6111  row->integral = row->integral && SCIPcolIsIntegral(cols[t]) && SCIPsetIsIntegral(set, vals[t]);
6112  t++;
6113  }
6114  assert(s == row->len);
6115  assert(t <= row->len);
6116 
6117  row->len = t;
6118  row->nunlinked = t;
6119 
6120  /* if equal entries were merged, we have to recalculate the norms, since the squared Euclidean norm is wrong */
6121  if( t < s )
6122  rowCalcNorms(row, set);
6123  }
6124 
6125 #ifndef NDEBUG
6126  /* check for double entries */
6127  {
6128  int i;
6129  int j;
6130 
6131  for( i = 0; i < row->len; ++i )
6132  {
6133  assert(row->cols[i] != NULL);
6134  assert(row->cols[i]->index == row->cols_index[i]);
6135  for( j = i+1; j < row->len; ++j )
6136  assert(row->cols[i] != row->cols[j]);
6137  }
6138  }
6139 #endif
6140 }
6141 
6142 /** enables delaying of row sorting */
6144  SCIP_ROW* row /**< LP row */
6145  )
6146 {
6147  assert(row != NULL);
6148  assert(!row->delaysort);
6149 
6150  row->delaysort = TRUE;
6151 }
6152 
6153 /** disables delaying of row sorting, sorts row and merges coefficients with equal columns */
6155  SCIP_ROW* row, /**< LP row */
6156  SCIP_SET* set /**< global SCIP settings */
6157  )
6158 {
6159  assert(row != NULL);
6160  assert(row->delaysort);
6161 
6162  row->delaysort = FALSE;
6163  rowMerge(row, set);
6164 }
6165 
6166 /** recalculates the current activity of a row */
6168  SCIP_ROW* row, /**< LP row */
6169  SCIP_STAT* stat /**< problem statistics */
6170  )
6171 {
6172  SCIP_COL* col;
6173  int c;
6174 
6175  assert(row != NULL);
6176  assert(stat != NULL);
6177 
6178  row->activity = row->constant;
6179  for( c = 0; c < row->nlpcols; ++c )
6180  {
6181  col = row->cols[c];
6182  assert(col != NULL);
6183  assert(col->primsol < SCIP_INVALID);
6184  assert(col->lppos >= 0);
6185  assert(row->linkpos[c] >= 0);
6186  row->activity += row->vals[c] * col->primsol;
6187  }
6188 
6189  if( row->nunlinked > 0 )
6190  {
6191  for( c = row->nlpcols; c < row->len; ++c )
6192  {
6193  col = row->cols[c];
6194  assert(col != NULL);
6195  assert(col->lppos >= 0 || col->primsol == 0.0);
6196  assert(col->lppos == -1 || row->linkpos[c] == -1);
6197  if( col->lppos >= 0 )
6198  row->activity += row->vals[c] * col->primsol;
6199  }
6200  }
6201 #ifndef NDEBUG
6202  else
6203  {
6204  for( c = row->nlpcols; c < row->len; ++c )
6205  {
6206  col = row->cols[c];
6207  assert(col != NULL);
6208  assert(col->primsol == 0.0);
6209  assert(col->lppos == -1);
6210  assert(row->linkpos[c] >= 0);
6211  }
6212  }
6213 #endif
6214 
6215  row->validactivitylp = stat->lpcount;
6216 }
6217 
6218 /** returns the activity of a row in the current LP solution */
6220  SCIP_ROW* row, /**< LP row */
6221  SCIP_SET* set, /**< global SCIP settings */
6222  SCIP_STAT* stat, /**< problem statistics */
6223  SCIP_LP* lp /**< current LP data */
6224  )
6225 {
6226  SCIP_Real inf;
6227  SCIP_Real activity;
6228 
6229  assert(row != NULL);
6230  assert(stat != NULL);
6231  assert(lp != NULL);
6232  assert(row->validactivitylp <= stat->lpcount);
6233  assert(lp->validsollp == stat->lpcount);
6234 
6235  if( row->validactivitylp != stat->lpcount )
6236  SCIProwRecalcLPActivity(row, stat);
6237  assert(row->validactivitylp == stat->lpcount);
6238  assert(row->activity < SCIP_INVALID);
6239 
6240  activity = row->activity;
6241  inf = SCIPsetInfinity(set);
6242  activity = MAX(activity, -inf);
6243  activity = MIN(activity, +inf);
6244 
6245  return activity;
6246 }
6247 
6248 /** returns the feasibility of a row in the current LP solution: negative value means infeasibility */
6250  SCIP_ROW* row, /**< LP row */
6251  SCIP_SET* set, /**< global SCIP settings */
6252  SCIP_STAT* stat, /**< problem statistics */
6253  SCIP_LP* lp /**< current LP data */
6254  )
6255 {
6256  SCIP_Real activity;
6257 
6258  assert(row != NULL);
6259 
6260  activity = SCIProwGetLPActivity(row, set, stat, lp);
6261 
6262  return MIN(row->rhs - activity, activity - row->lhs);
6263 }
6264 
6265 /** returns the feasibility of a row in the relaxed solution solution: negative value means infeasibility
6266  *
6267  * @todo Implement calculation of activities similar to LPs.
6268  */
6270  SCIP_ROW* row, /**< LP row */
6271  SCIP_SET* set, /**< global SCIP settings */
6272  SCIP_STAT* stat /**< problem statistics */
6273  )
6274 {
6275  SCIP_Real inf;
6276  SCIP_Real activity;
6277  SCIP_COL* col;
6278  int c;
6279 
6280  assert( row != NULL );
6281  assert( stat != NULL );
6282 
6283  activity = row->constant;
6284  for (c = 0; c < row->nlpcols; ++c)
6285  {
6286  col = row->cols[c];
6287  assert( col != NULL );
6288  assert( col->lppos >= 0 );
6289  assert( col->var != NULL );
6290  assert( row->linkpos[c] >= 0 );
6291  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6292  }
6293 
6294  if ( row->nunlinked > 0 )
6295  {
6296  for (c = row->nlpcols; c < row->len; ++c)
6297  {
6298  col = row->cols[c];
6299  assert( col != NULL );
6300  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6301  if ( col->lppos >= 0 )
6302  {
6303  assert( col->var != NULL );
6304  activity += row->vals[c] * SCIPvarGetRelaxSol(col->var, set);
6305  }
6306  }
6307  }
6308 #ifndef NDEBUG
6309  else
6310  {
6311  for (c = row->nlpcols; c < row->len; ++c)
6312  {
6313  col = row->cols[c];
6314  assert( col != NULL );
6315  assert( col->lppos == -1 );
6316  assert( row->linkpos[c] >= 0 );
6317  }
6318  }
6319 #endif
6320  inf = SCIPsetInfinity(set);
6321  activity = MAX(activity, -inf);
6322  activity = MIN(activity, +inf);
6323 
6324  return MIN(row->rhs - activity, activity - row->lhs);
6325 }
6326 
6327 /** returns the feasibility of a row in the current NLP solution: negative value means infeasibility
6328  *
6329  * @todo Implement calculation of activities similar to LPs.
6330  */
6332  SCIP_ROW* row, /**< LP row */
6333  SCIP_SET* set, /**< global SCIP settings */
6334  SCIP_STAT* stat /**< problem statistics */
6335  )
6336 {
6337  SCIP_Real inf;
6338  SCIP_Real activity;
6339  SCIP_COL* col;
6340  int c;
6341 
6342  assert( row != NULL );
6343  assert( stat != NULL );
6344 
6345  activity = row->constant;
6346  for (c = 0; c < row->nlpcols; ++c)
6347  {
6348  col = row->cols[c];
6349  assert( col != NULL );
6350  assert( col->lppos >= 0 );
6351  assert( col->var != NULL );
6352  assert( row->linkpos[c] >= 0 );
6353  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6354  }
6355 
6356  if ( row->nunlinked > 0 )
6357  {
6358  for (c = row->nlpcols; c < row->len; ++c)
6359  {
6360  col = row->cols[c];
6361  assert( col != NULL );
6362  assert( col->lppos == -1 || row->linkpos[c] == -1 );
6363  if ( col->lppos >= 0 )
6364  {
6365  assert( col->var != NULL );
6366  activity += row->vals[c] * SCIPvarGetNLPSol(col->var);
6367  }
6368  }
6369  }
6370 #ifndef NDEBUG
6371  else
6372  {
6373  for (c = row->nlpcols; c < row->len; ++c)
6374  {
6375  col = row->cols[c];
6376  assert( col != NULL );
6377  assert( col->lppos == -1 );
6378  assert( row->linkpos[c] >= 0 );
6379  }
6380  }
6381 #endif
6382  inf = SCIPsetInfinity(set);
6383  activity = MAX(activity, -inf);
6384  activity = MIN(activity, +inf);
6385 
6386  return MIN(row->rhs - activity, activity - row->lhs);
6387 }
6388 
6389 /** calculates the current pseudo activity of a row */
6391  SCIP_ROW* row, /**< row data */
6392  SCIP_STAT* stat /**< problem statistics */
6393  )
6394 {
6395  SCIP_COL* col;
6396  int i;
6397 
6398  assert(row != NULL);
6399  assert(stat != NULL);
6400 
6401  row->pseudoactivity = row->constant;
6402  for( i = 0; i < row->len; ++i )
6403  {
6404  col = row->cols[i];
6405  assert(col != NULL);
6406  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6407  assert(col->var != NULL);
6408  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
6409 
6410  row->pseudoactivity += SCIPcolGetBestBound(col) * row->vals[i];
6411  }
6412  row->validpsactivitydomchg = stat->domchgcount;
6413  assert(!row->integral || EPSISINT(row->pseudoactivity - row->constant, SCIP_DEFAULT_SUMEPSILON));
6414 }
6415 
6416 /** returns the pseudo activity of a row in the current pseudo solution */
6418  SCIP_ROW* row, /**< LP row */
6419  SCIP_SET* set, /**< global SCIP settings */
6420  SCIP_STAT* stat /**< problem statistics */
6421  )
6422 {
6423  SCIP_Real inf;
6424  SCIP_Real activity;
6425 
6426  assert(row != NULL);
6427  assert(stat != NULL);
6428  assert(row->validpsactivitydomchg <= stat->domchgcount);
6429 
6430  /* check, if pseudo activity has to be calculated */
6431  if( row->validpsactivitydomchg != stat->domchgcount )
6432  SCIProwRecalcPseudoActivity(row, stat);
6433  assert(row->validpsactivitydomchg == stat->domchgcount);
6434  assert(row->pseudoactivity < SCIP_INVALID);
6435 
6436  activity = row->pseudoactivity;
6437  inf = SCIPsetInfinity(set);
6438  activity = MAX(activity, -inf);
6439  activity = MIN(activity, +inf);
6440 
6441  return activity;
6442 }
6443 
6444 /** returns the pseudo feasibility of a row in the current pseudo solution: negative value means infeasibility */
6446  SCIP_ROW* row, /**< LP row */
6447  SCIP_SET* set, /**< global SCIP settings */
6448  SCIP_STAT* stat /**< problem statistics */
6449  )
6450 {
6451  SCIP_Real pseudoactivity;
6452 
6453  assert(row != NULL);
6454 
6455  pseudoactivity = SCIProwGetPseudoActivity(row, set, stat);
6456 
6457  return MIN(row->rhs - pseudoactivity, pseudoactivity - row->lhs);
6458 }
6459 
6460 /** returns the activity of a row for a given solution */
6462  SCIP_ROW* row, /**< LP row */
6463  SCIP_SET* set, /**< global SCIP settings */
6464  SCIP_STAT* stat, /**< problem statistics data */
6465  SCIP_SOL* sol /**< primal CIP solution */
6466  )
6467 {
6468  SCIP_COL* col;
6469  SCIP_Real inf;
6470  SCIP_Real activity;
6471  SCIP_Real solval;
6472  int i;
6473 
6474  assert(row != NULL);
6475 
6476  activity = row->constant;
6477  for( i = 0; i < row->len; ++i )
6478  {
6479  col = row->cols[i];
6480  assert(col != NULL);
6481  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6482  solval = SCIPsolGetVal(sol, set, stat, col->var);
6483  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
6484  {
6485  if( SCIPsetIsInfinity(set, -row->lhs) )
6486  solval = (row->vals[i] >= 0.0 ? col->lb : col->ub);
6487  else if( SCIPsetIsInfinity(set, row->rhs) )
6488  solval = (row->vals[i] >= 0.0 ? col->ub : col->lb);
6489  else
6490  solval = (col->lb + col->ub)/2.0;
6491  }
6492  activity += row->vals[i] * solval;
6493  }
6494 
6495  inf = SCIPsetInfinity(set);
6496  activity = MAX(activity, -inf);
6497  activity = MIN(activity, +inf);
6498 
6499  return activity;
6500 }
6501 
6502 /** returns the feasibility of a row for the given solution */
6504  SCIP_ROW* row, /**< LP row */
6505  SCIP_SET* set, /**< global SCIP settings */
6506  SCIP_STAT* stat, /**< problem statistics data */
6507  SCIP_SOL* sol /**< primal CIP solution */
6508  )
6509 {
6510  SCIP_Real activity;
6511 
6512  assert(row != NULL);
6513 
6514  activity = SCIProwGetSolActivity(row, set, stat, sol);
6515 
6516  return MIN(row->rhs - activity, activity - row->lhs);
6517 }
6518 
6519 /** calculates minimal and maximal activity of row w.r.t. the column's bounds */
6520 static
6522  SCIP_ROW* row, /**< row data */
6523  SCIP_SET* set, /**< global SCIP settings */
6524  SCIP_STAT* stat /**< problem statistics data */
6525  )
6526 {
6527  SCIP_COL* col;
6528  SCIP_Real val;
6529  SCIP_Bool mininfinite;
6530  SCIP_Bool maxinfinite;
6531  int i;
6532 
6533  assert(row != NULL);
6534  assert(!SCIPsetIsInfinity(set, REALABS(row->constant)));
6535  assert(stat != NULL);
6536 
6537  /* calculate activity bounds */
6538  mininfinite = FALSE;
6539  maxinfinite = FALSE;
6540  row->minactivity = row->constant;
6541  row->maxactivity = row->constant;
6542  for( i = 0; i < row->len && (!mininfinite || !maxinfinite); ++i )
6543  {
6544  col = row->cols[i];
6545  assert(col != NULL);
6546  assert((i < row->nlpcols) == (row->linkpos[i] >= 0 && col->lppos >= 0));
6547  val = row->vals[i];
6548  if( val >= 0.0 )
6549  {
6550  mininfinite = mininfinite || SCIPsetIsInfinity(set, -col->lb);
6551  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, col->ub);
6552  if( !mininfinite )
6553  row->minactivity += val * col->lb;
6554  if( !maxinfinite )
6555  row->maxactivity += val * col->ub;
6556  }
6557  else
6558  {
6559  mininfinite = mininfinite || SCIPsetIsInfinity(set, col->ub);
6560  maxinfinite = maxinfinite || SCIPsetIsInfinity(set, -col->lb);
6561  if( !mininfinite )
6562  row->minactivity += val * col->ub;
6563  if( !maxinfinite )
6564  row->maxactivity += val * col->lb;
6565  }
6566  }
6567 
6568  if( mininfinite )
6569  row->minactivity = -SCIPsetInfinity(set);
6570  if( maxinfinite )
6571  row->maxactivity = SCIPsetInfinity(set);
6572  row->validactivitybdsdomchg = stat->domchgcount;
6573 
6574 #ifndef NDEBUG
6575  {
6576  SCIP_Real inttol = 1000.0*SCIPsetFeastol(set);
6577 
6578  /* even if the row is integral, the bounds on the variables used for computing minimum and maximum activity might
6579  * be integral only within feasibility tolerance; this can happen, e.g., if a continuous variable is promoted to
6580  * an (implicit) integer variable and the bounds cannot be adjusted because they are minimally tighter than the
6581  * rounded bound value; hence, the activity may violate integrality; we allow 1000 times the default feasibility
6582  * tolerance as a proxy to account for the accumulation effect
6583  */
6584  assert(!row->integral || mininfinite || REALABS(row->minactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6585  || EPSISINT(row->minactivity - row->constant, inttol));
6586  assert(!row->integral || maxinfinite || REALABS(row->maxactivity - row->constant) > 1.0/SCIPsetSumepsilon(set)
6587  || EPSISINT(row->maxactivity - row->constant, inttol));
6588  }
6589 #endif
6590 }
6591 
6592 /** returns the minimal activity of a row w.r.t. the columns' bounds */
6594  SCIP_ROW* row, /**< LP row */
6595  SCIP_SET* set, /**< global SCIP settings */
6596  SCIP_STAT* stat /**< problem statistics data */
6597  )
6598 {
6599  assert(row != NULL);
6600  assert(stat != NULL);
6601  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6602 
6603  /* check, if activity bounds has to be calculated */
6604  if( row->validactivitybdsdomchg != stat->domchgcount )
6605  rowCalcActivityBounds(row, set, stat);
6606  assert(row->validactivitybdsdomchg == stat->domchgcount);
6607  assert(row->minactivity < SCIP_INVALID);
6608  assert(row->maxactivity < SCIP_INVALID);
6609 
6610  return row->minactivity;
6611 }
6612 
6613 /** returns the maximal activity of a row w.r.t. the columns' bounds */
6615  SCIP_ROW* row, /**< LP row */
6616  SCIP_SET* set, /**< global SCIP settings */
6617  SCIP_STAT* stat /**< problem statistics data */
6618  )
6619 {
6620  assert(row != NULL);
6621  assert(stat != NULL);
6622  assert(row->validactivitybdsdomchg <= stat->domchgcount);
6623 
6624  /* check, if activity bounds has to be calculated */
6625  if( row->validactivitybdsdomchg != stat->domchgcount )
6626  rowCalcActivityBounds(row, set, stat);
6627  assert(row->validactivitybdsdomchg == stat->domchgcount);
6628  assert(row->minactivity < SCIP_INVALID);
6629  assert(row->maxactivity < SCIP_INVALID);
6630 
6631  return row->maxactivity;
6632 }
6633 
6634 /** returns whether the row is unmodifiable and redundant w.r.t. the columns' bounds */
6636  SCIP_ROW* row, /**< LP row */
6637  SCIP_SET* set, /**< global SCIP settings */
6638  SCIP_STAT* stat /**< problem statistics data */
6639  )
6640 {
6641  assert(row != NULL);
6642 
6643  if( row->modifiable )
6644  return FALSE;
6645  if( !SCIPsetIsInfinity(set, -row->lhs) )
6646  {
6647  SCIP_Real minactivity;
6648 
6649  minactivity = SCIProwGetMinActivity(row, set, stat);
6650  if( SCIPsetIsFeasLT(set, minactivity, row->lhs) )
6651  return FALSE;
6652  }
6653  if( !SCIPsetIsInfinity(set, row->rhs) )
6654  {
6655  SCIP_Real maxactivity;
6656 
6657  maxactivity = SCIProwGetMaxActivity(row, set, stat);
6658  if( SCIPsetIsFeasGT(set, maxactivity, row->rhs) )
6659  return FALSE;
6660  }
6661 
6662  return TRUE;
6663 }
6664 
6665 /** gets maximal absolute value of row vector coefficients */
6667  SCIP_ROW* row, /**< LP row */
6668  SCIP_SET* set /**< global SCIP settings */
6669  )
6670 {
6671  assert(row != NULL);
6672 
6673  if( row->nummaxval == 0 )
6674  rowCalcIdxsAndVals(row, set);
6675  assert(row->nummaxval > 0);
6676  assert(row->maxval >= 0.0 || row->len == 0);
6677 
6678  return row->maxval;
6679 }
6680 
6681 /** gets minimal absolute value of row vector's non-zero coefficients */
6683  SCIP_ROW* row, /**< LP row */
6684  SCIP_SET* set /**< global SCIP settings */
6685  )
6686 {
6687  assert(row != NULL);
6688 
6689  if( row->numminval == 0 )
6690  rowCalcIdxsAndVals(row, set);
6691  assert(row->numminval > 0);
6692  assert(row->minval >= 0.0 || row->len == 0);
6693 
6694  return row->minval;
6695 }
6696 
6697 /** gets maximal column index of row entries */
6699  SCIP_ROW* row, /**< LP row */
6700  SCIP_SET* set /**< global SCIP settings */
6701  )
6702 {
6703  assert(row != NULL);
6704 
6705  if( row->validminmaxidx == 0 )
6706  rowCalcIdxsAndVals(row, set);
6707  assert(row->maxidx >= 0 || row->len == 0);
6708  assert(row->validminmaxidx);
6709 
6710  return row->maxidx;
6711 }
6712 
6713 /** gets minimal column index of row entries */
6715  SCIP_ROW* row, /**< LP row */
6716  SCIP_SET* set /**< global SCIP settings */
6717  )
6718 {
6719  assert(row != NULL);
6720 
6721  if( row->validminmaxidx == 0 )
6722  rowCalcIdxsAndVals(row, set);
6723  assert(row->minidx >= 0 || row->len == 0);
6724  assert(row->validminmaxidx);
6725 
6726  return row->minidx;
6727 }
6728 
6729 /** gets number of integral columns in row */
6731  SCIP_ROW* row, /**< LP row */
6732  SCIP_SET* set /**< global SCIP settings */
6733  )
6734 {
6735  assert(row != NULL);
6736 
6737  if( row->numintcols == -1 )
6738  rowCalcIdxsAndVals(row, set);
6739 
6740  assert(row->numintcols <= row->len && row->numintcols >= 0);
6741 
6742  return row->numintcols;
6743 }
6744 
6745 /** returns row's cutoff distance in the direction of the given primal solution */
6747  SCIP_ROW* row, /**< LP row */
6748  SCIP_SET* set, /**< global SCIP settings */
6749  SCIP_STAT* stat, /**< problem statistics data */
6750  SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
6751  SCIP_LP* lp /**< current LP data */
6752  )
6753 {
6754  SCIP_Real solcutoffdist;
6755  int k;
6756 
6757  assert(sol != NULL);
6758 
6759  if( lp->validsoldirlp != stat->lpcount || lp->validsoldirsol != sol )
6760  {
6761  SCIP_Real scale = 0.0;
6762 
6763  lp->validsoldirlp = stat->lpcount;
6764  lp->validsoldirsol = sol;
6765 
6767 
6768  for( k = 0; k < lp->ncols; ++k )
6769  {
6770  assert(lp->cols[k]->lppos == k);
6771  lp->soldirection[k] = SCIPsolGetVal(sol, set, stat, lp->cols[k]->var) - lp->cols[k]->primsol;
6772  scale += SQR(lp->soldirection[k]);
6773  }
6774 
6775  if( scale > 0.0 )
6776  {
6777  scale = 1.0 / SQRT(scale);
6778 
6779  for( k = 0; k < lp->ncols; ++k )
6780  lp->soldirection[k] *= scale;
6781  }
6782  }
6783 
6784  solcutoffdist = 0.0;
6785  for( k = 0; k < row->nlpcols; ++k )
6786  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6787 
6788  for( k = row->nlpcols; k < row->len; ++k )
6789  {
6790  if( row->cols[k]->lppos >= 0 )
6791  solcutoffdist += row->vals[k] * lp->soldirection[row->cols[k]->lppos];
6792  }
6793 
6794  if( SCIPsetIsSumZero(set, solcutoffdist) )
6795  solcutoffdist = set->num_sumepsilon;
6796 
6797  solcutoffdist = -SCIProwGetLPFeasibility(row, set, stat, lp) / ABS(solcutoffdist); /*lint !e795*/
6798 
6799  return solcutoffdist;
6800 }
6801 
6802 /** returns row's efficacy with respect to the current LP solution: e = -feasibility/norm */
6804  SCIP_ROW* row, /**< LP row */
6805  SCIP_SET* set, /**< global SCIP settings */
6806  SCIP_STAT* stat, /**< problem statistics data */
6807  SCIP_LP* lp /**< current LP data */
6808  )
6809 {
6810  SCIP_Real norm;
6811  SCIP_Real feasibility;
6812  SCIP_Real eps;
6813 
6814  assert(set != NULL);
6815 
6816  switch( set->sepa_efficacynorm )
6817  {
6818  case 'e':
6819  norm = SCIProwGetNorm(row);
6820  break;
6821  case 'm':
6822  norm = SCIProwGetMaxval(row, set);
6823  break;
6824  case 's':
6825  norm = SCIProwGetSumNorm(row);
6826  break;
6827  case 'd':
6828  norm = (row->len == 0 ? 0.0 : 1.0);
6829  break;
6830  default:
6831  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6832  SCIPABORT();
6833  norm = 0.0; /*lint !e527*/
6834  }
6835 
6836  eps = SCIPsetSumepsilon(set);
6837  norm = MAX(norm, eps);
6838  feasibility = SCIProwGetLPFeasibility(row, set, stat, lp);
6839 
6840  return -feasibility / norm;
6841 }
6842 
6843 /** returns whether the row's efficacy with respect to the current LP solution is greater than the minimal cut efficacy */
6845  SCIP_ROW* row, /**< LP row */
6846  SCIP_SET* set, /**< global SCIP settings */
6847  SCIP_STAT* stat, /**< problem statistics data */
6848  SCIP_LP* lp, /**< current LP data */
6849  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6850  )
6851 {
6852  SCIP_Real efficacy;
6853 
6854  efficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
6855 
6856  return SCIPsetIsEfficacious(set, root, efficacy);
6857 }
6858 
6859 /** returns row's efficacy with respect to the given primal solution: e = -feasibility/norm */
6861  SCIP_ROW* row, /**< LP row */
6862  SCIP_SET* set, /**< global SCIP settings */
6863  SCIP_STAT* stat, /**< problem statistics data */
6864  SCIP_SOL* sol /**< primal CIP solution */
6865  )
6866 {
6867  SCIP_Real norm;
6868  SCIP_Real feasibility;
6869  SCIP_Real eps;
6870 
6871  assert(set != NULL);
6872 
6873  switch( set->sepa_efficacynorm )
6874  {
6875  case 'e':
6876  norm = SCIProwGetNorm(row);
6877  break;
6878  case 'm':
6879  norm = SCIProwGetMaxval(row, set);
6880  break;
6881  case 's':
6882  norm = SCIProwGetSumNorm(row);
6883  break;
6884  case 'd':
6885  norm = (row->len == 0 ? 0.0 : 1.0);
6886  break;
6887  default:
6888  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6889  SCIPABORT();
6890  norm = 0.0; /*lint !e527*/
6891  }
6892 
6893  eps = SCIPsetSumepsilon(set);
6894  norm = MAX(norm, eps);
6895  feasibility = SCIProwGetSolFeasibility(row, set, stat, sol);
6896 
6897  return -feasibility / norm;
6898 }
6899 
6900 /** returns whether the row's efficacy with respect to the given primal solution is greater than the minimal cut
6901  * efficacy
6902  */
6904  SCIP_ROW* row, /**< LP row */
6905  SCIP_SET* set, /**< global SCIP settings */
6906  SCIP_STAT* stat, /**< problem statistics data */
6907  SCIP_SOL* sol, /**< primal CIP solution */
6908  SCIP_Bool root /**< should the root's minimal cut efficacy be used? */
6909  )
6910 {
6911  SCIP_Real efficacy;
6912 
6913  efficacy = SCIProwGetSolEfficacy(row, set, stat, sol);
6914 
6915  return SCIPsetIsEfficacious(set, root, efficacy);
6916 }
6917 
6918 /** returns row's efficacy with respect to the relaxed solution: e = -feasibility/norm */
6920  SCIP_ROW* row, /**< LP row */
6921  SCIP_SET* set, /**< global SCIP settings */
6922  SCIP_STAT* stat /**< problem statistics data */
6923  )
6924 {
6925  SCIP_Real norm;
6926  SCIP_Real feasibility;
6927  SCIP_Real eps;
6928 
6929  assert(set != NULL);
6930 
6931  switch( set->sepa_efficacynorm )
6932  {
6933  case 'e':
6934  norm = SCIProwGetNorm(row);
6935  break;
6936  case 'm':
6937  norm = SCIProwGetMaxval(row, set);
6938  break;
6939  case 's':
6940  norm = SCIProwGetSumNorm(row);
6941  break;
6942  case 'd':
6943  norm = (row->len == 0 ? 0.0 : 1.0);
6944  break;
6945  default:
6946  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6947  SCIPABORT();
6948  norm = 0.0; /*lint !e527*/
6949  }
6950 
6951  eps = SCIPsetSumepsilon(set);
6952  norm = MAX(norm, eps);
6953  feasibility = SCIProwGetRelaxFeasibility(row, set, stat);
6954 
6955  return -feasibility / norm;
6956 }
6957 
6958 /** returns row's efficacy with respect to the NLP solution: e = -feasibility/norm */
6960  SCIP_ROW* row, /**< LP row */
6961  SCIP_SET* set, /**< global SCIP settings */
6962  SCIP_STAT* stat /**< problem statistics data */
6963  )
6964 {
6965  SCIP_Real norm;
6966  SCIP_Real feasibility;
6967  SCIP_Real eps;
6968 
6969  assert(set != NULL);
6970 
6971  switch( set->sepa_efficacynorm )
6972  {
6973  case 'e':
6974  norm = SCIProwGetNorm(row);
6975  break;
6976  case 'm':
6977  norm = SCIProwGetMaxval(row, set);
6978  break;
6979  case 's':
6980  norm = SCIProwGetSumNorm(row);
6981  break;
6982  case 'd':
6983  norm = (row->len == 0 ? 0.0 : 1.0);
6984  break;
6985  default:
6986  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", set->sepa_efficacynorm);
6987  SCIPABORT();
6988  norm = 0.0; /*lint !e527*/
6989  }
6990 
6991  eps = SCIPsetSumepsilon(set);
6992  norm = MAX(norm, eps);
6993  feasibility = SCIProwGetNLPFeasibility(row, set, stat);
6994 
6995  return -feasibility / norm;
6996 }
6997 
6998 /** returns the scalar product of the coefficient vectors of the two given rows
6999  *
7000  * @note the scalar product is computed w.r.t. the current LP columns only
7001  * @todo also consider non-LP columns for the computation?
7002  */
7004  SCIP_ROW* row1, /**< first LP row */
7005  SCIP_ROW* row2 /**< second LP row */
7006  )
7007 {
7008  SCIP_Real scalarprod;
7009  int* row1colsidx;
7010  int* row2colsidx;
7011  int i1;
7012  int i2;
7013 
7014  assert(row1 != NULL);
7015  assert(row2 != NULL);
7016 
7017  /* Sort the column indices of both rows.
7018  *
7019  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7020  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7021  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7022  * for both or one of the non-LP columns for both.
7023  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7024  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7025  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7026  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7027  *
7028  * We distinguish the following cases:
7029  *
7030  * 1) both rows have no unlinked columns
7031  * -> we just check the LP partitions
7032  *
7033  * 2) exactly one row is completely unlinked, the other one is completely linked
7034  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7035  * (thus all common LP columns are regarded)
7036  *
7037  * 3) we have unlinked and LP columns in both rows
7038  * -> we need to compare four partitions at once
7039  *
7040  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7041  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7042  * other row
7043  *
7044  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7045  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7046  *
7047  * 5) both rows are completely unlinked
7048  * -> we need to compare two partitions: both complete rows
7049  */
7050  SCIProwSort(row1);
7051  assert(row1->lpcolssorted);
7052  assert(row1->nonlpcolssorted);
7053  SCIProwSort(row2);
7054  assert(row2->lpcolssorted);
7055  assert(row2->nonlpcolssorted);
7056 
7057  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7058  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7059 
7060  row1colsidx = row1->cols_index;
7061  row2colsidx = row2->cols_index;
7062 
7063 #ifndef NDEBUG
7064  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7065  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7066  {
7067  i1 = 0;
7068  i2 = row2->nlpcols;
7069  while( i1 < row1->nlpcols && i2 < row2->len )
7070  {
7071  assert(row1->cols[i1] != row2->cols[i2]);
7072  if( row1->cols[i1]->index < row2->cols[i2]->index )
7073  ++i1;
7074  else
7075  {
7076  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7077  ++i2;
7078  }
7079  }
7080  assert(i1 == row1->nlpcols || i2 == row2->len);
7081 
7082  i1 = row1->nlpcols;
7083  i2 = 0;
7084  while( i1 < row1->len && i2 < row2->nlpcols )
7085  {
7086  assert(row1->cols[i1] != row2->cols[i2]);
7087  if( row1->cols[i1]->index < row2->cols[i2]->index )
7088  ++i1;
7089  else
7090  {
7091  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7092  ++i2;
7093  }
7094  }
7095  assert(i1 == row1->len || i2 == row2->nlpcols);
7096  }
7097 #endif
7098 
7099  /* The "easy" cases 1) and 2) */
7100  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7101  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7102  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7103  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7104  {
7105  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7106  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7107 
7108  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7109  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7110  */
7111  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7112  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7113  scalarprod = 0.0;
7114 
7115  /* calculate the scalar product */
7116  while( i1 >= 0 && i2 >= 0 )
7117  {
7118  assert(row1->cols[i1]->index == row1colsidx[i1]);
7119  assert(row2->cols[i2]->index == row2colsidx[i2]);
7120  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7121  if( row1colsidx[i1] < row2colsidx[i2] )
7122  --i2;
7123  else if( row1colsidx[i1] > row2colsidx[i2] )
7124  --i1;
7125  else
7126  {
7127  scalarprod += row1->vals[i1] * row2->vals[i2];
7128  --i1;
7129  --i2;
7130  }
7131  }
7132  }
7133  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7134  else
7135  {
7136  SCIP_Bool lpcols;
7137  int ilp1;
7138  int inlp1;
7139  int ilp2;
7140  int inlp2;
7141  int end1;
7142  int end2;
7143 
7144  scalarprod = 0;
7145  ilp1 = 0;
7146  ilp2 = 0;
7147 
7148  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7149  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7150  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7151 
7152  /* handle the case of four partitions (case 3) until one partition is finished;
7153  * cases 4a), 4b), and 5) will fail the while-condition
7154  */
7155  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7156  {
7157  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7158  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7159  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7160  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7161  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7162  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7163  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7164  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7165 
7166  /* rows have the same linked LP columns */
7167  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7168  {
7169  scalarprod += row1->vals[ilp1] * row2->vals[ilp2];
7170  ++ilp1;
7171  ++ilp2;
7172  }
7173  /* LP column of row1 is the same as unlinked column of row2 */
7174  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7175  {
7176  scalarprod += row1->vals[ilp1] * row2->vals[inlp2];
7177  ++ilp1;
7178  ++inlp2;
7179  }
7180  /* unlinked column of row1 is the same as LP column of row2 */
7181  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7182  {
7183  scalarprod += row1->vals[inlp1] * row2->vals[ilp2];
7184  ++inlp1;
7185  ++ilp2;
7186  }
7187  /* two unlinked LP columns are the same */
7188  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7189  {
7190  scalarprod += row1->vals[inlp1] * row2->vals[inlp2];
7191  ++inlp1;
7192  ++inlp2;
7193  }
7194  /* increase smallest counter */
7195  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7196  {
7197  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7198  {
7199  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7200  ++ilp1;
7201  else
7202  ++ilp2;
7203  }
7204  else
7205  {
7206  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7207  ++ilp1;
7208  else
7209  ++inlp2;
7210  }
7211  }
7212  else
7213  {
7214  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7215  {
7216  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7217  ++inlp1;
7218  else
7219  ++ilp2;
7220  }
7221  else
7222  {
7223  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7224  ++inlp1;
7225  else
7226  ++inlp2;
7227  }
7228  }
7229  }
7230 
7231  /* One partition was completely handled, we just have to handle the three remaining partitions:
7232  * the remaining partition of this row and the two partitions of the other row.
7233  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7234  */
7235  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7236  {
7237  int tmpilp;
7238  int tmpinlp;
7239 
7240  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7241 
7242  SCIPswapPointers((void**) &row1, (void**) &row2);
7243  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7244  tmpilp = ilp1;
7245  tmpinlp = inlp1;
7246  ilp1 = ilp2;
7247  inlp1 = inlp2;
7248  ilp2 = tmpilp;
7249  inlp2 = tmpinlp;
7250  }
7251 
7252  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7253  * -> this merges cases 4a) and 4b)
7254  */
7255  if( ilp1 == row1->nlpcols )
7256  {
7257  i1 = inlp1;
7258  end1 = row1->len;
7259  lpcols = FALSE;
7260  }
7261  else
7262  {
7263  assert(inlp1 == row1->len);
7264 
7265  i1 = ilp1;
7266  end1 = row1->nlpcols;
7267  lpcols = TRUE;
7268  }
7269 
7270  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7271  * case 5) will fail the while-condition
7272  */
7273  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7274  {
7275  assert(row1->cols[i1]->index == row1colsidx[i1]);
7276  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7277  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7278  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7279  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7280 
7281  /* current column in row 1 is the same as the current LP column in row 2 */
7282  if( row1colsidx[i1] == row2colsidx[ilp2] )
7283  {
7284  scalarprod += row1->vals[i1] * row2->vals[ilp2];
7285  ++i1;
7286  ++ilp2;
7287  }
7288  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7289  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7290  {
7291  scalarprod += row1->vals[i1] * row2->vals[inlp2];
7292  ++i1;
7293  ++inlp2;
7294  }
7295  /* increase smallest counter */
7296  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7297  {
7298  if( row1colsidx[i1] < row2colsidx[ilp2] )
7299  ++i1;
7300  else
7301  ++ilp2;
7302  }
7303  else
7304  {
7305  if( row1colsidx[i1] < row2colsidx[inlp2] )
7306  ++i1;
7307  else
7308  ++inlp2;
7309  }
7310  }
7311 
7312  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7313  * the two rows
7314  */
7315  if( i1 < end1 )
7316  {
7317  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7318  if( ilp2 == row2->nlpcols )
7319  {
7320  i2 = inlp2;
7321  end2 = row2->len;
7322  lpcols = FALSE;
7323  }
7324  else
7325  {
7326  assert(inlp2 == row2->len);
7327 
7328  i2 = ilp2;
7329  end2 = row2->nlpcols;
7330  }
7331 
7332  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7333  while( i1 < end1 && i2 < end2 )
7334  {
7335  assert(row1->cols[i1]->index == row1colsidx[i1]);
7336  assert(row2->cols[i2]->index == row2colsidx[i2]);
7337  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7338 
7339  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7340  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7341  {
7342  scalarprod += row1->vals[i1] * row2->vals[i2];
7343  ++i1;
7344  ++i2;
7345  }
7346  /* increase smallest counter */
7347  else if( row1colsidx[i1] < row2colsidx[i2] )
7348  ++i1;
7349  else
7350  ++i2;
7351  }
7352  }
7353  }
7354 
7355  return scalarprod;
7356 }
7357 
7358 /** returns the discrete scalar product of the coefficient vectors of the two given rows */
7359 static
7361  SCIP_ROW* row1, /**< first LP row */
7362  SCIP_ROW* row2 /**< second LP row */
7363  )
7364 {
7365  int prod;
7366  int* row1colsidx;
7367  int* row2colsidx;
7368  int i1;
7369  int i2;
7370 
7371  assert(row1 != NULL);
7372  assert(row2 != NULL);
7373 
7374  /* Sort the column indices of both rows.
7375  *
7376  * The columns in a row are divided into two parts: LP columns, which are currently in the LP and non-LP columns;
7377  * we sort the rows, but that only ensures that within these two parts, columns are sorted w.r.t. their index.
7378  * Normally, this should be suficient, because a column contained in both rows should either be one of the LP columns
7379  * for both or one of the non-LP columns for both.
7380  * However, directly after a row was created, before a row is added to the LP, the row is not linked to all its
7381  * columns and all columns are treated as non-LP columns. Moreover, for example when doing column generation,
7382  * columns can be added later and remain unlinked while all previously added columns might already be linked.
7383  * Therefore, we have to be very careful about whether we can rely on the partitioning of the variables.
7384  *
7385  * We distinguish the following cases:
7386  *
7387  * 1) both rows have no unlinked columns
7388  * -> we just check the LP partitions
7389  *
7390  * 2) exactly one row is completely unlinked, the other one is completely linked
7391  * -> we compare the non-LP (unlinked) partition with the LP partition of the other row
7392  * (thus all common LP columns are regarded)
7393  *
7394  * 3) we have unlinked and LP columns in both rows
7395  * -> we need to compare four partitions at once
7396  *
7397  * 4a) we have one row with unlinked and LP columns and the other without any unlinked columns
7398  * -> we need to compare three partitions: the LP part of the completely linked row and both partitions of the
7399  * other row
7400  *
7401  * 4b) we have one row with unlinked and LP columns and the other is completely unlinked
7402  * -> we need to compare three partitions: the complete unlinked row and both partitions of the other row
7403  *
7404  * 5) both rows are completely unlinked
7405  * -> we need to compare two partitions: both complete rows
7406  */
7407  SCIProwSort(row1);
7408  assert(row1->lpcolssorted);
7409  assert(row1->nonlpcolssorted);
7410  SCIProwSort(row2);
7411  assert(row2->lpcolssorted);
7412  assert(row2->nonlpcolssorted);
7413 
7414  assert(row1->nunlinked <= row1->len - row1->nlpcols);
7415  assert(row2->nunlinked <= row2->len - row2->nlpcols);
7416 
7417  row1colsidx = row1->cols_index;
7418  row2colsidx = row2->cols_index;
7419 
7420 #ifndef NDEBUG
7421  /* check that we can rely on the partition into LP columns and non-LP columns if the rows are completely linked */
7422  if( row1->nunlinked == 0 && row2->nunlinked == 0 )
7423  {
7424  i1 = 0;
7425  i2 = row2->nlpcols;
7426  while( i1 < row1->nlpcols && i2 < row2->len )
7427  {
7428  assert(row1->cols[i1] != row2->cols[i2]);
7429  if( row1->cols[i1]->index < row2->cols[i2]->index )
7430  ++i1;
7431  else
7432  {
7433  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7434  ++i2;
7435  }
7436  }
7437  assert(i1 == row1->nlpcols || i2 == row2->len);
7438 
7439  i1 = row1->nlpcols;
7440  i2 = 0;
7441  while( i1 < row1->len && i2 < row2->nlpcols )
7442  {
7443  assert(row1->cols[i1] != row2->cols[i2]);
7444  if( row1->cols[i1]->index < row2->cols[i2]->index )
7445  ++i1;
7446  else
7447  {
7448  assert(row1->cols[i1]->index > row2->cols[i2]->index);
7449  ++i2;
7450  }
7451  }
7452  assert(i1 == row1->len || i2 == row2->nlpcols);
7453  }
7454 #endif
7455 
7456  /* The "easy" cases 1) and 2) */
7457  if( (row1->nunlinked == 0 && row2->nunlinked == 0) ||
7458  ((row1->nlpcols == row1->len || row1->nunlinked == row1->len)
7459  && (row2->nlpcols == row2->len || row2->nunlinked == row2->len)
7460  && (row1->nunlinked == 0 || row2->nunlinked == 0)) )
7461  {
7462  assert(row1->nunlinked == 0 || row1->nunlinked == row1->len);
7463  assert(row2->nunlinked == 0 || row2->nunlinked == row2->len);
7464 
7465  /* set the iterators to the last column we want to regard in the row: nunlinked is either 0 or row->len,
7466  * therefore, we get nlpcols if nunlinked is 0 and row->len if the row is completely unlinked
7467  */
7468  i1 = MAX(row1->nlpcols, row1->nunlinked) - 1;
7469  i2 = MAX(row2->nlpcols, row2->nunlinked) - 1;
7470  prod = 0;
7471 
7472  /* calculate the scalar product */
7473  while( i1 >= 0 && i2 >= 0 )
7474  {
7475  assert(row1->cols[i1]->index == row1colsidx[i1]);
7476  assert(row2->cols[i2]->index == row2colsidx[i2]);
7477  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7478  if( row1colsidx[i1] < row2colsidx[i2] )
7479  --i2;
7480  else if( row1colsidx[i1] > row2colsidx[i2] )
7481  --i1;
7482  else
7483  {
7484  ++prod;
7485  --i1;
7486  --i2;
7487  }
7488  }
7489  }
7490  /* the "harder" cases 3) - 5): start with four partitions and reduce their number iteratively */
7491  else
7492  {
7493  SCIP_Bool lpcols;
7494  int ilp1;
7495  int inlp1;
7496  int ilp2;
7497  int inlp2;
7498  int end1;
7499  int end2;
7500 
7501  prod = 0;
7502  ilp1 = 0;
7503  ilp2 = 0;
7504 
7505  /* if a row is completely linked (case 4a), we do not have to consider its non-LP columns */
7506  inlp1 = (row1->nunlinked > 0 ? row1->nlpcols : row1->len);
7507  inlp2 = (row2->nunlinked > 0 ? row2->nlpcols : row2->len);
7508 
7509  /* handle the case of four partitions (case 3) until one partition is finished;
7510  * cases 4a), 4b), and 5) will fail the while-condition
7511  */
7512  while( ilp1 < row1->nlpcols && inlp1 < row1->len && ilp2 < row2->nlpcols && inlp2 < row2->len )
7513  {
7514  assert(row1->cols[ilp1]->index == row1colsidx[ilp1]);
7515  assert(row1->cols[inlp1]->index == row1colsidx[inlp1]);
7516  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7517  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7518  assert((row1->cols[ilp1] == row2->cols[ilp2]) == (row1colsidx[ilp1] == row2colsidx[ilp2]));
7519  assert((row1->cols[ilp1] == row2->cols[inlp2]) == (row1colsidx[ilp1] == row2colsidx[inlp2]));
7520  assert((row1->cols[inlp1] == row2->cols[ilp2]) == (row1colsidx[inlp1] == row2colsidx[ilp2]));
7521  assert((row1->cols[inlp1] == row2->cols[inlp2]) == (row1colsidx[inlp1] == row2colsidx[inlp2]));
7522 
7523  /* rows have the same linked LP columns */
7524  if( row1colsidx[ilp1] == row2colsidx[ilp2] )
7525  {
7526  ++prod;
7527  ++ilp1;
7528  ++ilp2;
7529  }
7530  /* LP column of row1 is the same as unlinked column of row2 */
7531  else if( row1colsidx[ilp1] == row2colsidx[inlp2] )
7532  {
7533  ++prod;
7534  ++ilp1;
7535  ++inlp2;
7536  }
7537  /* unlinked column of row1 is the same as LP column of row2 */
7538  else if( row1colsidx[inlp1] == row2colsidx[ilp2] )
7539  {
7540  ++prod;
7541  ++inlp1;
7542  ++ilp2;
7543  }
7544  /* two unlinked LP columns are the same */
7545  else if( row1colsidx[inlp1] == row2colsidx[inlp2] && row1->cols[inlp1]->lppos >= 0 )
7546  {
7547  ++prod;
7548  ++inlp1;
7549  ++inlp2;
7550  }
7551  /* increase smallest counter */
7552  else if( row1colsidx[ilp1] < row1colsidx[inlp1] )
7553  {
7554  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7555  {
7556  if( row1colsidx[ilp1] < row2colsidx[ilp2] )
7557  ++ilp1;
7558  else
7559  ++ilp2;
7560  }
7561  else
7562  {
7563  if( row1colsidx[ilp1] < row2colsidx[inlp2] )
7564  ++ilp1;
7565  else
7566  ++inlp2;
7567  }
7568  }
7569  else
7570  {
7571  if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7572  {
7573  if( row1colsidx[inlp1] < row2colsidx[ilp2] )
7574  ++inlp1;
7575  else
7576  ++ilp2;
7577  }
7578  else
7579  {
7580  if( row1colsidx[inlp1] < row2colsidx[inlp2] )
7581  ++inlp1;
7582  else
7583  ++inlp2;
7584  }
7585  }
7586  }
7587 
7588  /* One partition was completely handled, we just have to handle the three remaining partitions:
7589  * the remaining partition of this row and the two partitions of the other row.
7590  * If necessary, we swap the partitions to ensure that row1 is the row with only one remaining partition.
7591  */
7592  if( ilp1 != row1->nlpcols && inlp1 != row1->len )
7593  {
7594  int tmpilp;
7595  int tmpinlp;
7596 
7597  assert(ilp2 == row2->nlpcols || inlp2 == row2->len);
7598 
7599  SCIPswapPointers((void**) &row1, (void**) &row2);
7600  SCIPswapPointers((void**) &row1colsidx, (void**) &row2colsidx);
7601  tmpilp = ilp1;
7602  tmpinlp = inlp1;
7603  ilp1 = ilp2;
7604  inlp1 = inlp2;
7605  ilp2 = tmpilp;
7606  inlp2 = tmpinlp;
7607  }
7608 
7609  /* determine section of row 1 that we want to look at (current iterator = begin, end, LP-columns?)
7610  * -> this merges cases 4a) and 4b)
7611  */
7612  if( ilp1 == row1->nlpcols )
7613  {
7614  i1 = inlp1;
7615  end1 = row1->len;
7616  lpcols = FALSE;
7617  }
7618  else
7619  {
7620  assert(inlp1 == row1->len);
7621 
7622  i1 = ilp1;
7623  end1 = row1->nlpcols;
7624  lpcols = TRUE;
7625  }
7626 
7627  /* handle the case of three partitions (case 4) until one partition is finished, this reduces our problem to case 1), 2), or 5);
7628  * case 5) will fail the while-condition
7629  */
7630  while( i1 < end1 && ilp2 < row2->nlpcols && inlp2 < row2->len )
7631  {
7632  assert(row1->cols[i1]->index == row1colsidx[i1]);
7633  assert(row2->cols[ilp2]->index == row2colsidx[ilp2]);
7634  assert(row2->cols[inlp2]->index == row2colsidx[inlp2]);
7635  assert((row1->cols[i1] == row2->cols[ilp2]) == (row1colsidx[i1] == row2colsidx[ilp2]));
7636  assert((row1->cols[i1] == row2->cols[inlp2]) == (row1colsidx[i1] == row2colsidx[inlp2]));
7637 
7638  /* current column in row 1 is the same as the current LP column in row 2 */
7639  if( row1colsidx[i1] == row2colsidx[ilp2] )
7640  {
7641  ++prod;
7642  ++i1;
7643  ++ilp2;
7644  }
7645  /* linked or unlinked LP column of row1 is the same as unlinked column of row2 */
7646  else if( row1colsidx[i1] == row2colsidx[inlp2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7647  {
7648  ++prod;
7649  ++i1;
7650  ++inlp2;
7651  }
7652  /* increase smallest counter */
7653  else if( row2colsidx[ilp2] < row2colsidx[inlp2] )
7654  {
7655  if( row1colsidx[i1] < row2colsidx[ilp2] )
7656  ++i1;
7657  else
7658  ++ilp2;
7659  }
7660  else
7661  {
7662  if( row1colsidx[i1] < row2colsidx[inlp2] )
7663  ++i1;
7664  else
7665  ++inlp2;
7666  }
7667  }
7668 
7669  /* if the second section of row 1 was finished, we can stop; otherwise, we have to consider the remaining parts of
7670  * the two rows
7671  */
7672  if( i1 < end1 )
7673  {
7674  /* determine section of row 2 that we want to look at (current iterator = begin, end, LP-columns?) */
7675  if( ilp2 == row2->nlpcols )
7676  {
7677  i2 = inlp2;
7678  end2 = row2->len;
7679  lpcols = FALSE;
7680  }
7681  else
7682  {
7683  assert(inlp2 == row2->len);
7684 
7685  i2 = ilp2;
7686  end2 = row2->nlpcols;
7687  }
7688 
7689  /* handle the case of two partitions (standard case 5, or case 1 or 2 due to partition reduction) */
7690  while( i1 < end1 && i2 < end2 )
7691  {
7692  assert(row1->cols[i1]->index == row1colsidx[i1]);
7693  assert(row2->cols[i2]->index == row2colsidx[i2]);
7694  assert((row1->cols[i1] == row2->cols[i2]) == (row1colsidx[i1] == row2colsidx[i2]));
7695 
7696  /* linked or unlinked LP column of row1 is the same as linked or unlinked LP column of row2 */
7697  if( row1colsidx[i1] == row2colsidx[i2] && (lpcols || row1->cols[i1]->lppos >= 0) )
7698  {
7699  ++prod;
7700  ++i1;
7701  ++i2;
7702  }
7703  /* increase smallest counter */
7704  else if( row1colsidx[i1] < row2colsidx[i2] )
7705  ++i1;
7706  else
7707  ++i2;
7708  }
7709  }
7710  }
7711 
7712  return prod;
7713 }
7714 
7715 /** returns the degree of parallelism between the hyperplanes defined by the two row vectors v, w:
7716  * p = |v*w|/(|v|*|w|);
7717  * the hyperplanes are parallel, iff p = 1, they are orthogonal, iff p = 0
7718  */
7720  SCIP_ROW* row1, /**< first LP row */
7721  SCIP_ROW* row2, /**< second LP row */
7722  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7723  )
7724 {
7725  SCIP_Real parallelism;
7726  SCIP_Real scalarprod;
7727 
7728  switch( orthofunc )
7729  {
7730  case 'e':
7731  scalarprod = SCIProwGetScalarProduct(row1, row2);
7732  if( scalarprod == 0.0 )
7733  {
7734  parallelism = 0.0;
7735  break;
7736  }
7737 
7738  if( SCIProwGetNorm(row1) == 0.0 )
7739  {
7740  /* In theory, this should not happen if the scalarproduct is not zero
7741  * But due to bug 520 (also issue 44), it is possible that norms are not correct.
7742  * Thus, if the norm is so bad that it is even 0, then reevaluate it here.
7743  * But as we don't have set available here, we cannot call rowCalcNorms, so do it by hand.
7744  */
7745  int i;
7746  for( i = 0; i < row1->len; ++i )
7747  if( row1->cols[i]->lppos >= 0 )
7748  row1->sqrnorm += SQR(row1->vals[i]);
7749  assert(SCIProwGetNorm(row1) != 0.0);
7750  }
7751 
7752  if( SCIProwGetNorm(row2) == 0.0 )
7753  {
7754  /* same as for row1 above: reeval norms if it is 0, which is wrong */
7755  int i;
7756  for( i = 0; i < row2->len; ++i )
7757  if( row2->cols[i]->lppos >= 0 )
7758  row2->sqrnorm += SQR(row2->vals[i]);
7759  assert(SCIProwGetNorm(row2) != 0.0);
7760  }
7761 
7762  parallelism = REALABS(scalarprod) / (SCIProwGetNorm(row1) * SCIProwGetNorm(row2));
7763  break;
7764 
7765  case 'd':
7766  scalarprod = (SCIP_Real) SCIProwGetDiscreteScalarProduct(row1, row2);
7767  parallelism = scalarprod / (sqrt((SCIP_Real) SCIProwGetNNonz(row1)) * sqrt((SCIP_Real) SCIProwGetNNonz(row2)));
7768  break;
7769 
7770  default:
7771  SCIPerrorMessage("invalid orthogonality function parameter '%c'\n", orthofunc);
7772  SCIPABORT();
7773  parallelism = 0.0; /*lint !e527*/
7774  }
7775 
7776  return parallelism;
7777 }
7778 
7779 /** returns the degree of orthogonality between the hyperplanes defined by the two row vectors v, w:
7780  * o = 1 - |v*w|/(|v|*|w|);
7781  * the hyperplanes are orthogonal, iff p = 1, they are parallel, iff p = 0
7782  */
7784  SCIP_ROW* row1, /**< first LP row */
7785  SCIP_ROW* row2, /**< second LP row */
7786  char orthofunc /**< function used for calc. scalar prod. ('e'uclidean, 'd'iscrete) */
7787  )
7788 {
7789  return 1.0 - SCIProwGetParallelism(row1, row2, orthofunc);
7790 }
7791 
7792 /** gets parallelism of row with objective function: if the returned value is 1, the row is parallel to the objective
7793  * function, if the value is 0, it is orthogonal to the objective function
7794  */
7796  SCIP_ROW* row, /**< LP row */
7797  SCIP_SET* set, /**< global SCIP settings */
7798  SCIP_LP* lp /**< current LP data */
7799  )
7800 {
7801  SCIP_Real prod;
7802  SCIP_Real parallelism;
7803 
7804  assert(row != NULL);
7805  assert(lp != NULL);
7806 
7807  if( lp->objsqrnormunreliable )
7808  SCIPlpRecalculateObjSqrNorm(set, lp);
7809 
7810  assert(!lp->objsqrnormunreliable);
7811  assert(lp->objsqrnorm >= 0.0);
7812 
7813  checkRowSqrnorm(row);
7814  checkRowObjprod(row);
7815 
7816  prod = row->sqrnorm * lp->objsqrnorm;
7817 
7818  parallelism = SCIPsetIsPositive(set, prod) ? REALABS(row->objprod) / SQRT(prod) : 0.0;
7819  assert(SCIPsetIsSumGE(set, parallelism, 0.0));
7820  assert(SCIPsetIsSumLE(set, parallelism, 1.0));
7821  parallelism = MIN(parallelism, 1.0);
7822  parallelism = MAX(parallelism, 0.0);
7823 
7824  return parallelism;
7825 }
7826 
7827 /** includes event handler with given data in row's event filter */
7829  SCIP_ROW* row, /**< row */
7830  BMS_BLKMEM* blkmem, /**< block memory */
7831  SCIP_SET* set, /**< global SCIP settings */
7832  SCIP_EVENTTYPE eventtype, /**< event type to catch */
7833  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7834  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7835  int* filterpos /**< pointer to store position of event filter entry, or NULL */
7836  )
7837 {
7838  assert(row != NULL);
7839  assert(row->eventfilter != NULL);
7840  assert((eventtype & ~SCIP_EVENTTYPE_ROWCHANGED) == 0);
7841  assert((eventtype & SCIP_EVENTTYPE_ROWCHANGED) != 0);
7842 
7843  SCIPsetDebugMsg(set, "catch event of type 0x%" SCIP_EVENTTYPE_FORMAT " of row <%s> with handler %p and data %p\n",
7844  eventtype, row->name, (void*)eventhdlr, (void*)eventdata);
7845 
7846  SCIP_CALL( SCIPeventfilterAdd(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7847 
7848  return SCIP_OKAY;
7849 }
7850 
7851 /** deletes event handler with given data from row's event filter */
7853  SCIP_ROW* row, /**< row */
7854  BMS_BLKMEM* blkmem, /**< block memory */
7855  SCIP_SET* set, /**< global SCIP settings */
7856  SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */
7857  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
7858  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
7859  int filterpos /**< position of event filter entry returned by SCIPvarCatchEvent(), or -1 */
7860  )
7861 {
7862  assert(row != NULL);
7863  assert(row->eventfilter != NULL);
7864 
7865  SCIPsetDebugMsg(set, "drop event of row <%s> with handler %p and data %p\n", row->name, (void*)eventhdlr, (void*)eventdata);
7866 
7867  SCIP_CALL( SCIPeventfilterDel(row->eventfilter, blkmem, set, eventtype, eventhdlr, eventdata, filterpos) );
7868 
7869  return SCIP_OKAY;
7870 }
7871 
7872 /** marks a row to be not removable from the LP in the current node because it became obsolete */
7874  SCIP_ROW* row, /**< LP row */
7875  SCIP_STAT* stat /**< problem statistics */
7876  )
7877 {
7878  assert(row != NULL);
7879  assert(stat != NULL);
7880  assert(stat->nnodes > 0);
7881 
7882  /* lpRemoveObsoleteRows() does not remove a row if the node number stored in obsoletenode equals the current node number */
7883  row->obsoletenode = stat->nnodes;
7884 }
7885 
7886 /*
7887  * LP solver data update
7888  */
7889 
7890 /** resets column data to represent a column not in the LP solver */
7891 static
7893  SCIP_COL* col /**< column to be marked deleted */
7894  )
7895 {
7896  assert(col != NULL);
7897 
7898  col->lpipos = -1;
7899  col->primsol = 0.0;
7900  col->redcost = SCIP_INVALID;
7901  col->farkascoef = SCIP_INVALID;
7902  col->sbdown = SCIP_INVALID;
7903  col->sbup = SCIP_INVALID;
7904  col->sbdownvalid = FALSE;
7905  col->sbupvalid = FALSE;
7906  col->validredcostlp = -1;
7907  col->validfarkaslp = -1;
7908  col->sbitlim = -1;
7909  col->basisstatus = SCIP_BASESTAT_ZERO; /*lint !e641*/
7910 }
7911 
7912 /** applies all cached column removals to the LP solver */
7913 static
7915  SCIP_LP* lp /**< current LP data */
7916  )
7917 {
7918  assert(lp != NULL);
7919  assert(lp->lpifirstchgcol <= lp->nlpicols);
7920  assert(lp->lpifirstchgcol <= lp->ncols);
7921 
7922  /* find the first column to change */
7923  while( lp->lpifirstchgcol < lp->nlpicols
7924  && lp->lpifirstchgcol < lp->ncols
7925  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
7926  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
7927  {
7928  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
7929  lp->lpifirstchgcol++;
7930  }
7931 
7932  /* shrink LP to the part which didn't change */
7933  if( lp->lpifirstchgcol < lp->nlpicols )
7934  {
7935  int i;
7936 
7937  assert(!lp->diving);
7938  SCIPdebugMessage("flushing col deletions: shrink LP from %d to %d columns\n", lp->nlpicols, lp->lpifirstchgcol);
7939  SCIP_CALL( SCIPlpiDelCols(lp->lpi, lp->lpifirstchgcol, lp->nlpicols-1) );
7940  for( i = lp->lpifirstchgcol; i < lp->nlpicols; ++i )
7941  {
7942  markColDeleted(lp->lpicols[i]);
7943  }
7944  lp->nlpicols = lp->lpifirstchgcol;
7945  lp->flushdeletedcols = TRUE;
7946  lp->updateintegrality = TRUE;
7947 
7948  /* mark the LP unsolved */
7949  lp->solved = FALSE;
7950  lp->primalfeasible = FALSE;
7951  lp->primalchecked = FALSE;
7952  lp->lpobjval = SCIP_INVALID;
7954  }
7955  assert(lp->nlpicols == lp->lpifirstchgcol);
7956 
7957  return SCIP_OKAY;
7958 }
7959 
7960 /** computes for the given column the lower and upper bound that should be flushed into the LP
7961  * depending on lazy bounds and diving mode; in diving mode, lazy bounds are ignored, i.e.,
7962  * the bounds are explicitly added to the LP in any case
7963  */
7964 static
7966  SCIP_LP* lp, /**< current LP data */
7967  SCIP_SET* set, /**< global SCIP settings */
7968  SCIP_COL* col, /**< column to compute bounds for */
7969  SCIP_Real lpiinf, /**< infinity value if the LP solver */
7970  SCIP_Real* lb, /**< pointer to store the new lower bound */
7971  SCIP_Real* ub /**< pointer to store the new upper bound */
7972  )
7973 {
7974  assert(lp != NULL);
7975  assert(set != NULL);
7976  assert(col != NULL);
7977  assert(lb != NULL);
7978  assert(ub != NULL);
7979 
7980  /* get the correct new lower bound:
7981  * if lazy lower bound exists and is larger than lower bound, set lower bound to infinity;
7982  * if we are in diving mode, ignore lazy bounds and always take the lower bound
7983  */
7984  if( SCIPsetIsInfinity(set, -col->lb) || (SCIPsetIsLE(set, col->lb, col->lazylb) && !SCIPlpDiving(lp)) )
7985  (*lb) = -lpiinf;
7986  else
7987  (*lb) = col->lb;
7988  /* get the correct new upper bound:
7989  * if lazy upper bound exists and is larger than upper bound, set upper bound to infinity;
7990  * if we are in diving mode, ignore lazy bounds and always take the upper bound
7991  */
7992  if( SCIPsetIsInfinity(set, col->ub) || (SCIPsetIsGE(set, col->ub, col->lazyub) && !SCIPlpDiving(lp)) )
7993  (*ub) = lpiinf;
7994  else
7995  (*ub) = col->ub;
7996 }
7997 
7998 /** applies all cached column additions to the LP solver */
7999 static
8001  SCIP_LP* lp, /**< current LP data */
8002  BMS_BLKMEM* blkmem, /**< block memory */
8003  SCIP_SET* set, /**< global SCIP settings */
8004  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8005  )
8006 {
8007  SCIP_Real* obj;
8008  SCIP_Real* lb;
8009  SCIP_Real* ub;
8010  int* beg;
8011  int* ind;
8012  SCIP_Real* val;
8013  char** name;
8014  SCIP_COL* col;
8015  SCIP_Real lpiinf;
8016  int c;
8017  int pos;
8018  int nnonz;
8019  int naddcols;
8020  int naddcoefs;
8021  int i;
8022  int lpipos;
8023 
8024  assert(lp != NULL);
8025  assert(lp->lpifirstchgcol == lp->nlpicols);
8026  assert(blkmem != NULL);
8027  assert(set != NULL);
8028 
8029  /* if there are no columns to add, we are ready */
8030  if( lp->ncols == lp->nlpicols )
8031  return SCIP_OKAY;
8032 
8033  /* add the additional columns */
8034  assert(!lp->diving);
8035  assert(lp->ncols > lp->nlpicols);
8036  SCIP_CALL( ensureLpicolsSize(lp, set, lp->ncols) );
8037 
8038  /* get the solver's infinity value */
8039  lpiinf = SCIPlpiInfinity(lp->lpi);
8040 
8041  /* count the (maximal) number of added coefficients, calculate the number of added columns */
8042  naddcols = lp->ncols - lp->nlpicols;
8043  naddcoefs = 0;
8044  for( c = lp->nlpicols; c < lp->ncols; ++c )
8045  naddcoefs += lp->cols[c]->len;
8046  assert(naddcols > 0);
8047 
8048  /* get temporary memory for changes */
8049  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, naddcols) );
8050  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, naddcols) );
8051  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, naddcols) );
8052  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddcols) );
8053  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8054  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8055  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddcols) );
8056 
8057  /* fill temporary memory with column data */
8058  nnonz = 0;
8059  for( pos = 0, c = lp->nlpicols; c < lp->ncols; ++pos, ++c )
8060  {
8061  col = lp->cols[c];
8062  assert(col != NULL);
8063  assert(col->var != NULL);
8064  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8065  assert(SCIPvarGetCol(col->var) == col);
8066  assert(col->lppos == c);
8067  assert(nnonz + col->nlprows <= naddcoefs);
8068 
8069  SCIPsetDebugMsg(set, "flushing added column <%s>: ", SCIPvarGetName(col->var));
8070  debugColPrint(set, col);
8071 
8072  /* Because the column becomes a member of the LP solver, it now can take values
8073  * different from zero. That means, we have to include the column in the corresponding
8074  * row vectors.
8075  */
8076  SCIP_CALL( colLink(col, blkmem, set, eventqueue, lp) );
8077 
8078  lp->lpicols[c] = col;
8079  col->lpipos = c;
8080  col->primsol = SCIP_INVALID;
8081  col->redcost = SCIP_INVALID;
8082  col->farkascoef = SCIP_INVALID;
8083  col->sbdown = SCIP_INVALID;
8084  col->sbup = SCIP_INVALID;
8085  col->sbdownvalid = FALSE;
8086  col->sbupvalid = FALSE;
8087  col->validredcostlp = -1;
8088  col->validfarkaslp = -1;
8089  col->sbitlim = -1;
8090  col->objchanged = FALSE;
8091  col->lbchanged = FALSE;
8092  col->ubchanged = FALSE;
8093  col->coefchanged = FALSE;
8094  obj[pos] = col->obj;
8095 
8096  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8097  computeLPBounds(lp, set, col, lpiinf, &(lb[pos]), &(ub[pos]));
8098 
8099  beg[pos] = nnonz;
8100  name[pos] = (char*)SCIPvarGetName(col->var);
8101 
8102  col->flushedobj = obj[pos];
8103  col->flushedlb = lb[pos];
8104  col->flushedub = ub[pos];
8105 
8106  for( i = 0; i < col->nlprows; ++i )
8107  {
8108  assert(col->rows[i] != NULL);
8109  lpipos = col->rows[i]->lpipos;
8110  if( lpipos >= 0 )
8111  {
8112  assert(lpipos < lp->nrows);
8113  assert(nnonz < naddcoefs);
8114  ind[nnonz] = lpipos;
8115  val[nnonz] = col->vals[i];
8116  nnonz++;
8117  }
8118  }
8119 #ifndef NDEBUG
8120  for( i = col->nlprows; i < col->len; ++i )
8121  {
8122  assert(col->rows[i] != NULL);
8123  assert(col->rows[i]->lpipos == -1); /* because the row deletions are already performed */
8124  }
8125 #endif
8126  }
8127 
8128  /* call LP interface */
8129  SCIPsetDebugMsg(set, "flushing col additions: enlarge LP from %d to %d columns\n", lp->nlpicols, lp->ncols);
8130  SCIP_CALL( SCIPlpiAddCols(lp->lpi, naddcols, obj, lb, ub, name, nnonz, beg, ind, val) );
8131  lp->nlpicols = lp->ncols;
8132  lp->lpifirstchgcol = lp->nlpicols;
8133 
8134  /* free temporary memory */
8135  SCIPsetFreeBufferArray(set, &name);
8136  SCIPsetFreeBufferArray(set, &val);
8137  SCIPsetFreeBufferArray(set, &ind);
8138  SCIPsetFreeBufferArray(set, &beg);
8139  SCIPsetFreeBufferArray(set, &ub);
8140  SCIPsetFreeBufferArray(set, &lb);
8141  SCIPsetFreeBufferArray(set, &obj);
8142 
8143  lp->flushaddedcols = TRUE;
8144  lp->updateintegrality = TRUE;
8145 
8146  /* mark the LP unsolved */
8147  lp->solved = FALSE;
8148  lp->dualfeasible = FALSE;
8149  lp->dualchecked = FALSE;
8150  lp->lpobjval = SCIP_INVALID;
8152 
8153  return SCIP_OKAY;
8154 }
8155 
8156 /** resets row data to represent a row not in the LP solver */
8157 static
8159  SCIP_ROW* row /**< row to be marked deleted */
8160  )
8161 {
8162  assert(row != NULL);
8163 
8164  row->lpipos = -1;
8165  row->dualsol = 0.0;
8166  row->activity = SCIP_INVALID;
8167  row->dualfarkas = 0.0;
8168  row->basisstatus = SCIP_BASESTAT_BASIC; /*lint !e641*/
8169  row->validactivitylp = -1;
8170 }
8171 
8172 /** applies all cached row removals to the LP solver */
8173 static
8175  SCIP_LP* lp, /**< current LP data */
8176  BMS_BLKMEM* blkmem, /**< block memory */
8177  SCIP_SET* set /**< global SCIP settings */
8178  )
8179 {
8180  assert(lp != NULL);
8181  assert(lp->lpifirstchgrow <= lp->nlpirows);
8182  assert(lp->lpifirstchgrow <= lp->nrows);
8183 
8184  /* find the first row to change */
8185  while( lp->lpifirstchgrow < lp->nlpirows
8186  && lp->lpifirstchgrow < lp->nrows
8187  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8188  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8189  {
8190  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8191  lp->lpifirstchgrow++;
8192  }
8193 
8194  /* shrink LP to the part which didn't change */
8195  if( lp->lpifirstchgrow < lp->nlpirows )
8196  {
8197  int i;
8198 
8199  SCIPsetDebugMsg(set, "flushing row deletions: shrink LP from %d to %d rows\n", lp->nlpirows, lp->lpifirstchgrow);
8200  SCIP_CALL( SCIPlpiDelRows(lp->lpi, lp->lpifirstchgrow, lp->nlpirows-1) );
8201  for( i = lp->lpifirstchgrow; i < lp->nlpirows; ++i )
8202  {
8203  markRowDeleted(lp->lpirows[i]);
8204  SCIP_CALL( SCIProwRelease(&lp->lpirows[i], blkmem, set, lp) );
8205  }
8206  lp->nlpirows = lp->lpifirstchgrow;
8207  lp->flushdeletedrows = TRUE;
8208 
8209  /* mark the LP unsolved */
8210  lp->solved = FALSE;
8211  lp->dualfeasible = FALSE;
8212  lp->dualchecked = FALSE;
8213  lp->lpobjval = SCIP_INVALID;
8215  }
8216  assert(lp->nlpirows == lp->lpifirstchgrow);
8217 
8218  return SCIP_OKAY;
8219 }
8220 
8221 /** applies all cached row additions and removals to the LP solver */
8222 static
8224  SCIP_LP* lp, /**< current LP data */
8225  BMS_BLKMEM* blkmem, /**< block memory */
8226  SCIP_SET* set, /**< global SCIP settings */
8227  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8228  )
8229 {
8230  SCIP_Real* lhs;
8231  SCIP_Real* rhs;
8232  int* beg;
8233  int* ind;
8234  SCIP_Real* val;
8235  char** name;
8236  SCIP_ROW* row;
8237  SCIP_Real lpiinf;
8238  int r;
8239  int pos;
8240  int nnonz;
8241  int naddrows;
8242  int naddcoefs;
8243  int i;
8244  int lpipos;
8245 
8246  assert(lp != NULL);
8247  assert(lp->lpifirstchgrow == lp->nlpirows);
8248  assert(blkmem != NULL);
8249 
8250  /* if there are no rows to add, we are ready */
8251  if( lp->nrows == lp->nlpirows )
8252  return SCIP_OKAY;
8253 
8254  /* add the additional rows */
8255  assert(lp->nrows > lp->nlpirows);
8256  SCIP_CALL( ensureLpirowsSize(lp, set, lp->nrows) );
8257 
8258  /* get the solver's infinity value */
8259  lpiinf = SCIPlpiInfinity(lp->lpi);
8260 
8261  /* count the (maximal) number of added coefficients, calculate the number of added rows */
8262  naddrows = lp->nrows - lp->nlpirows;
8263  naddcoefs = 0;
8264  for( r = lp->nlpirows; r < lp->nrows; ++r )
8265  naddcoefs += lp->rows[r]->len;
8266  assert(naddrows > 0);
8267 
8268  /* get temporary memory for changes */
8269  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, naddrows) );
8270  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, naddrows) );
8271  SCIP_CALL( SCIPsetAllocBufferArray(set, &beg, naddrows) );
8272  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, naddcoefs) );
8273  SCIP_CALL( SCIPsetAllocBufferArray(set, &val, naddcoefs) );
8274  SCIP_CALL( SCIPsetAllocBufferArray(set, &name, naddrows) );
8275 
8276  /* fill temporary memory with row data */
8277  nnonz = 0;
8278  for( pos = 0, r = lp->nlpirows; r < lp->nrows; ++pos, ++r )
8279  {
8280  row = lp->rows[r];
8281  assert(row != NULL);
8282  assert(row->lppos == r);
8283  assert(nnonz + row->nlpcols <= naddcoefs);
8284 
8285  SCIPsetDebugMsg(set, "flushing added row <%s>: ", row->name);
8286  debugRowPrint(set, row);
8287 
8288  /* Because the row becomes a member of the LP solver, its dual variable now can take values
8289  * different from zero. That means, we have to include the row in the corresponding
8290  * column vectors.
8291  */
8292  SCIP_CALL( rowLink(row, blkmem, set, eventqueue, lp) );
8293 
8294  SCIProwCapture(row);
8295  lp->lpirows[r] = row;
8296  row->lpipos = r;
8297  row->dualsol = SCIP_INVALID;
8298  row->activity = SCIP_INVALID;
8299  row->dualfarkas = SCIP_INVALID;
8300  row->validactivitylp = -1;
8301  row->lhschanged = FALSE;
8302  row->rhschanged = FALSE;
8303  row->coefchanged = FALSE;
8304  if( SCIPsetIsInfinity(set, -row->lhs) )
8305  lhs[pos] = -lpiinf;
8306  else
8307  lhs[pos] = row->lhs - row->constant;
8308  if( SCIPsetIsInfinity(set, row->rhs) )
8309  rhs[pos] = lpiinf;
8310  else
8311  rhs[pos] = row->rhs - row->constant;
8312  beg[pos] = nnonz;
8313  name[pos] = row->name;
8314 
8315  row->flushedlhs = lhs[pos];
8316  row->flushedrhs = rhs[pos];
8317 
8318  SCIPsetDebugMsg(set, "flushing added row (SCIP_LPI): %+g <=", lhs[pos]);
8319  for( i = 0; i < row->nlpcols; ++i )
8320  {
8321  assert(row->cols[i] != NULL);
8322  lpipos = row->cols[i]->lpipos;
8323  if( lpipos >= 0 )
8324  {
8325  assert(lpipos < lp->ncols);
8326  assert(nnonz < naddcoefs);
8327  SCIPsetDebugMsgPrint(set, " %+gx%d(<%s>)", row->vals[i], lpipos+1, SCIPvarGetName(row->cols[i]->var));
8328  ind[nnonz] = lpipos;
8329  val[nnonz] = row->vals[i];
8330  nnonz++;
8331  }
8332  }
8333  SCIPsetDebugMsgPrint(set, " <= %+g\n", rhs[pos]);
8334 #ifndef NDEBUG
8335  for( i = row->nlpcols; i < row->len; ++i )
8336  {
8337  assert(row->cols[i] != NULL);
8338  assert(row->cols[i]->lpipos == -1); /* because the column deletions are already performed */
8339  }
8340 #endif
8341  }
8342 
8343  /* call LP interface */
8344  SCIPsetDebugMsg(set, "flushing row additions: enlarge LP from %d to %d rows\n", lp->nlpirows, lp->nrows);
8345  SCIP_CALL( SCIPlpiAddRows(lp->lpi, naddrows, lhs, rhs, name, nnonz, beg, ind, val) );
8346  lp->nlpirows = lp->nrows;
8347  lp->lpifirstchgrow = lp->nlpirows;
8348 
8349  /* free temporary memory */
8350  SCIPsetFreeBufferArray(set, &name);
8351  SCIPsetFreeBufferArray(set, &val);
8352  SCIPsetFreeBufferArray(set, &ind);
8353  SCIPsetFreeBufferArray(set, &beg);
8354  SCIPsetFreeBufferArray(set, &rhs);
8355  SCIPsetFreeBufferArray(set, &lhs);
8356 
8357  lp->flushaddedrows = TRUE;
8358 
8359  /* mark the LP unsolved */
8360  lp->solved = FALSE;
8361  lp->primalfeasible = FALSE;
8362  lp->primalchecked = FALSE;
8363  lp->lpobjval = SCIP_INVALID;
8365 
8366  return SCIP_OKAY;
8367 }
8368 
8369 /** applies all cached column bound and objective changes to the LP */
8370 static
8372  SCIP_LP* lp, /**< current LP data */
8373  SCIP_SET* set /**< global SCIP settings */
8374  )
8375 {
8376 #ifndef NDEBUG
8377  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8378 #endif
8379  SCIP_COL* col;
8380  int* objind;
8381  int* bdind;
8382  SCIP_Real* obj;
8383  SCIP_Real* lb;
8384  SCIP_Real* ub;
8385  SCIP_Real lpiinf;
8386  int nobjchg;
8387  int nbdchg;
8388  int i;
8389 
8390  assert(lp != NULL);
8391 
8392  if( lp->nchgcols == 0 )
8393  return SCIP_OKAY;
8394 
8395  /* get the solver's infinity value */
8396  lpiinf = SCIPlpiInfinity(lp->lpi);
8397 
8398  /* get temporary memory for changes */
8399  SCIP_CALL( SCIPsetAllocBufferArray(set, &objind, lp->ncols) );
8400  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, lp->ncols) );
8401  SCIP_CALL( SCIPsetAllocBufferArray(set, &bdind, lp->ncols) );
8402  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, lp->ncols) );
8403  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, lp->ncols) );
8404 
8405  /* collect all cached bound and objective changes */
8406  nobjchg = 0;
8407  nbdchg = 0;
8408  for( i = 0; i < lp->nchgcols; ++i )
8409  {
8410  col = lp->chgcols[i];
8411  assert(col != NULL);
8412  assert(col->var != NULL);
8413  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8414  assert(SCIPvarGetCol(col->var) == col);
8415 
8416  if( col->lpipos >= 0 )
8417  {
8418 #ifndef NDEBUG
8419  /* do not check consistency of data with LPI in case of LPI=none */
8420  if( !lpinone )
8421  {
8422  SCIP_Real lpiobj;
8423  SCIP_Real lpilb;
8424  SCIP_Real lpiub;
8425 
8426  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8427  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8428  assert(SCIPsetIsFeasEQ(set, lpiobj, col->flushedobj));
8429  assert((SCIPsetIsInfinity(set, -lpilb) && SCIPsetIsInfinity(set, -col->flushedlb))
8430  || (!SCIPsetIsInfinity(set, -lpilb) && !SCIPsetIsInfinity(set, -col->flushedlb) && SCIPsetIsFeasEQ(set, lpilb, col->flushedlb)));
8431  assert((SCIPsetIsInfinity(set, lpiub) && SCIPsetIsInfinity(set, col->flushedub))
8432  || (!SCIPsetIsInfinity(set, lpiub) && !SCIPsetIsInfinity(set, col->flushedub) && SCIPsetIsFeasEQ(set, lpiub, col->flushedub)));
8433  }
8434 #endif
8435 
8436  if( col->objchanged )
8437  {
8438  SCIP_Real newobj;
8439 
8440  newobj = col->obj;
8441  if( col->flushedobj != newobj ) /*lint !e777*/
8442  {
8443  assert(nobjchg < lp->ncols);
8444  objind[nobjchg] = col->lpipos;
8445  obj[nobjchg] = newobj;
8446  nobjchg++;
8447  col->flushedobj = newobj;
8448  }
8449  col->objchanged = FALSE;
8450  }
8451 
8452  if( col->lbchanged || col->ubchanged )
8453  {
8454  SCIP_Real newlb;
8455  SCIP_Real newub;
8456 
8457  /* compute bounds that should be flushed into the LP (taking into account lazy bounds) */
8458  computeLPBounds(lp, set, col, lpiinf, &newlb, &newub);
8459 
8460  if( col->flushedlb != newlb || col->flushedub != newub ) /*lint !e777*/
8461  {
8462  assert(nbdchg < lp->ncols);
8463  bdind[nbdchg] = col->lpipos;
8464  lb[nbdchg] = newlb;
8465  ub[nbdchg] = newub;
8466  nbdchg++;
8467  col->flushedlb = newlb;
8468  col->flushedub = newub;
8469  }
8470  col->lbchanged = FALSE;
8471  col->ubchanged = FALSE;
8472  }
8473  }
8474  /* maybe lb/ub/objchanged should all be set to false when lpipos is -1 */
8475  }
8476 
8477  /* change objective values in LP */
8478  if( nobjchg > 0 )
8479  {
8480  SCIPsetDebugMsg(set, "flushing objective changes: change %d objective values of %d changed columns\n", nobjchg, lp->nchgcols);
8481  SCIP_CALL( SCIPlpiChgObj(lp->lpi, nobjchg, objind, obj) );
8482 
8483  /* mark the LP unsolved */
8484  lp->solved = FALSE;
8485  lp->dualfeasible = FALSE;
8486  lp->dualchecked = FALSE;
8487  lp->lpobjval = SCIP_INVALID;
8489  }
8490 
8491  /* change bounds in LP */
8492  if( nbdchg > 0 )
8493  {
8494  SCIPsetDebugMsg(set, "flushing bound changes: change %d bounds of %d changed columns\n", nbdchg, lp->nchgcols);
8495  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, nbdchg, bdind, lb, ub) );
8496 
8497  /* mark the LP unsolved */
8498  lp->solved = FALSE;
8499  lp->primalfeasible = FALSE;
8500  lp->primalchecked = FALSE;
8501  lp->lpobjval = SCIP_INVALID;
8503  }
8504 
8505  lp->nchgcols = 0;
8506 
8507  /* free temporary memory */
8508  SCIPsetFreeBufferArray(set, &ub);
8509  SCIPsetFreeBufferArray(set, &lb);
8510  SCIPsetFreeBufferArray(set, &bdind);
8511  SCIPsetFreeBufferArray(set, &obj);
8512  SCIPsetFreeBufferArray(set, &objind);
8513 
8514  return SCIP_OKAY;
8515 }
8516 
8517 /** applies all cached row side changes to the LP */
8518 static
8520  SCIP_LP* lp, /**< current LP data */
8521  SCIP_SET* set /**< global SCIP settings */
8522  )
8523 {
8524 #ifndef NDEBUG
8525  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8526 #endif
8527  SCIP_ROW* row;
8528  int* ind;
8529  SCIP_Real* lhs;
8530  SCIP_Real* rhs;
8531  SCIP_Real lpiinf;
8532  int i;
8533  int nchg;
8534 
8535  assert(lp != NULL);
8536 
8537  if( lp->nchgrows == 0 )
8538  return SCIP_OKAY;
8539 
8540  /* get the solver's infinity value */
8541  lpiinf = SCIPlpiInfinity(lp->lpi);
8542 
8543  /* get temporary memory for changes */
8544  SCIP_CALL( SCIPsetAllocBufferArray(set, &ind, lp->nrows) );
8545  SCIP_CALL( SCIPsetAllocBufferArray(set, &lhs, lp->nrows) );
8546  SCIP_CALL( SCIPsetAllocBufferArray(set, &rhs, lp->nrows) );
8547 
8548  /* collect all cached left and right hand side changes */
8549  nchg = 0;
8550  for( i = 0; i < lp->nchgrows; ++i )
8551  {
8552  row = lp->chgrows[i];
8553  assert(row != NULL);
8554 
8555  if( row->lpipos >= 0 )
8556  {
8557 #ifndef NDEBUG
8558  /* do not check consistency of data with LPI in case of LPI=none */
8559  if( !lpinone )
8560  {
8561  SCIP_Real lpilhs;
8562  SCIP_Real lpirhs;
8563 
8564  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8565  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8566  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8567  }
8568 #endif
8569  if( row->lhschanged || row->rhschanged )
8570  {
8571  SCIP_Real newlhs;
8572  SCIP_Real newrhs;
8573 
8574  newlhs = (SCIPsetIsInfinity(set, -row->lhs) ? -lpiinf : row->lhs - row->constant);
8575  newrhs = (SCIPsetIsInfinity(set, row->rhs) ? lpiinf : row->rhs - row->constant);
8576  if( row->flushedlhs != newlhs || row->flushedrhs != newrhs ) /*lint !e777*/
8577  {
8578  assert(nchg < lp->nrows);
8579  ind[nchg] = row->lpipos;
8580  lhs[nchg] = newlhs;
8581  rhs[nchg] = newrhs;
8582  nchg++;
8583  row->flushedlhs = newlhs;
8584  row->flushedrhs = newrhs;
8585  }
8586  row->lhschanged = FALSE;
8587  row->rhschanged = FALSE;
8588  }
8589  }
8590  }
8591 
8592  /* change left and right hand sides in LP */
8593  if( nchg > 0 )
8594  {
8595  SCIPsetDebugMsg(set, "flushing side changes: change %d sides of %d rows\n", nchg, lp->nchgrows);
8596  SCIP_CALL( SCIPlpiChgSides(lp->lpi, nchg, ind, lhs, rhs) );
8597 
8598  /* mark the LP unsolved */
8599  lp->solved = FALSE;
8600  lp->primalfeasible = FALSE;
8601  lp->primalchecked = FALSE;
8602  lp->lpobjval = SCIP_INVALID;
8604  }
8605 
8606  lp->nchgrows = 0;
8607 
8608  /* free temporary memory */
8609  SCIPsetFreeBufferArray(set, &rhs);
8610  SCIPsetFreeBufferArray(set, &lhs);
8611  SCIPsetFreeBufferArray(set, &ind);
8612 
8613  return SCIP_OKAY;
8614 }
8615 
8616 /** copy integrality information to the LP */
8617 static
8619  SCIP_LP* lp, /**< current LP data */
8620  SCIP_SET* set /**< global SCIP settings */
8621  )
8622 {
8623  int i;
8624  int nintegers;
8625  int* integerInfo;
8626  SCIP_VAR* var;
8627 
8628  assert(lp != NULL);
8629 
8630  SCIP_CALL( SCIPsetAllocBufferArray(set, &integerInfo, lp->ncols) );
8631 
8632  /* count total number of integralities */
8633  nintegers = 0;
8634 
8635  for( i = 0; i < lp->ncols; ++i )
8636  {
8637  var = SCIPcolGetVar(lp->cols[i]);
8638  if( SCIPvarIsIntegral(var) || SCIPvarIsBinary(var) )
8639  {
8640  integerInfo[i] = 1;
8641  ++nintegers;
8642  }
8643  else
8644  integerInfo[i] = 0;
8645  }
8646 
8647  /* only pass integrality information if integer variables are present */
8648  if( nintegers > 0 )
8649  {
8650  SCIP_CALL( SCIPlpiSetIntegralityInformation(lp->lpi, lp->ncols, integerInfo) );
8651  }
8652  else
8653  {
8655  }
8656 
8657  SCIPsetFreeBufferArray(set, &integerInfo);
8658 
8659  /* mark integralities to be updated */
8660  lp->updateintegrality = FALSE;
8661 
8662  return SCIP_OKAY;
8663 }
8664 
8665 /** applies all cached changes to the LP solver */
8667  SCIP_LP* lp, /**< current LP data */
8668  BMS_BLKMEM* blkmem, /**< block memory */
8669  SCIP_SET* set, /**< global SCIP settings */
8670  SCIP_PROB* prob, /**< problem data */
8671  SCIP_EVENTQUEUE* eventqueue /**< event queue */
8672  )
8673 {
8674  assert(lp != NULL);
8675  assert(blkmem != NULL);
8676 
8677  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",
8678  lp->nlpicols, lp->nlpirows, lp->nchgcols, lp->nchgrows, lp->lpifirstchgcol, lp->lpifirstchgrow, lp->ncols, lp->nrows, lp->flushed);
8679 
8680  if( !lp->flushed )
8681  {
8682  lp->flushdeletedcols = FALSE;
8683  lp->flushaddedcols = FALSE;
8684  lp->flushdeletedrows = FALSE;
8685  lp->flushaddedrows = FALSE;
8686 
8687  SCIP_CALL( lpFlushDelCols(lp) );
8688  SCIP_CALL( lpFlushDelRows(lp, blkmem, set) );
8689  SCIP_CALL( lpFlushChgCols(lp, set) );
8690  SCIP_CALL( lpFlushChgRows(lp, set) );
8691  SCIP_CALL( lpFlushAddCols(lp, blkmem, set, eventqueue) );
8692  SCIP_CALL( lpFlushAddRows(lp, blkmem, set, eventqueue) );
8693 
8694  lp->flushed = TRUE;
8695 
8696  checkLinks(lp);
8697  }
8698 
8699  /* if the cutoff bound was changed in between and it is not disabled (e.g. for column generation),
8700  * we want to re-optimize the LP even if nothing else has changed */
8701  if( lp->cutoffbound != lp->lpiobjlim && lp->ncols > 0 && ! lpCutoffDisabled(set, prob) ) /*lint !e777*/
8702  {
8703  lp->solved = FALSE;
8705  }
8706 
8707  assert(lp->nlpicols == lp->ncols);
8708  assert(lp->lpifirstchgcol == lp->nlpicols);
8709  assert(lp->nlpirows == lp->nrows);
8710  assert(lp->lpifirstchgrow == lp->nlpirows);
8711  assert(lp->nchgcols == 0);
8712  assert(lp->nchgrows == 0);
8713 #ifndef NDEBUG
8714  {
8715  int ncols;
8716  int nrows;
8717 
8718  SCIP_CALL( SCIPlpiGetNCols(lp->lpi, &ncols) );
8719  SCIP_CALL( SCIPlpiGetNRows(lp->lpi, &nrows) );
8720  assert(ncols == lp->ncols);
8721  assert(nrows == lp->nrows);
8722  }
8723 #endif
8724 
8725  return SCIP_OKAY;
8726 }
8727 
8728 /** marks the LP to be flushed, even if the LP thinks it is not flushed */
8730  SCIP_LP* lp, /**< current LP data */
8731  SCIP_SET* set /**< global SCIP settings */
8732  )
8733 {
8734 #ifndef NDEBUG
8735  SCIP_Bool lpinone = (strcmp( SCIPlpiGetSolverName(), "NONE") == 0);
8736 #endif
8737  int i;
8738 
8739  assert(lp != NULL);
8740 
8741 #ifndef NDEBUG
8742  /* check, if there are really no column or row deletions or coefficient changes left */
8743  while( lp->lpifirstchgcol < lp->nlpicols
8744  && lp->lpifirstchgcol < lp->ncols
8745  && lp->cols[lp->lpifirstchgcol]->lpipos == lp->lpifirstchgcol
8746  && !lp->cols[lp->lpifirstchgcol]->coefchanged )
8747  {
8748  assert(lp->cols[lp->lpifirstchgcol] == lp->lpicols[lp->lpifirstchgcol]);
8749  lp->lpifirstchgcol++;
8750  }
8751  assert(lp->nlpicols == lp->lpifirstchgcol);
8752 
8753  while( lp->lpifirstchgrow < lp->nlpirows
8754  && lp->lpifirstchgrow < lp->nrows
8755  && lp->rows[lp->lpifirstchgrow]->lpipos == lp->lpifirstchgrow
8756  && !lp->rows[lp->lpifirstchgrow]->coefchanged )
8757  {
8758  assert(lp->rows[lp->lpifirstchgrow] == lp->lpirows[lp->lpifirstchgrow]);
8759  lp->lpifirstchgrow++;
8760  }
8761  assert(lp->nlpirows == lp->lpifirstchgrow);
8762 #endif
8763 
8764  lp->lpifirstchgcol = lp->nlpicols;
8765  lp->lpifirstchgrow = lp->nlpirows;
8766 
8767  /* check, if there are really no column or row additions left */
8768  assert(lp->ncols == lp->nlpicols);
8769  assert(lp->nrows == lp->nlpirows);
8770 
8771  /* mark the changed columns to be unchanged, and check, if this is really correct */
8772  for( i = 0; i < lp->nchgcols; ++i )
8773  {
8774  SCIP_COL* col;
8775 
8776  col = lp->chgcols[i];
8777  assert(col != NULL);
8778  assert(col->var != NULL);
8779  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
8780  assert(SCIPvarGetCol(col->var) == col);
8781 
8782  if( col->lpipos >= 0 )
8783  {
8784 #ifndef NDEBUG
8785  /* do not check consistency of data with LPI in case of LPI=none */
8786  if( !lpinone )
8787  {
8788  SCIP_Real lpiobj;
8789  SCIP_Real lpilb;
8790  SCIP_Real lpiub;
8791 
8792  SCIP_CALL( SCIPlpiGetObj(lp->lpi, col->lpipos, col->lpipos, &lpiobj) );
8793  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, col->lpipos, col->lpipos, &lpilb, &lpiub) );
8794  assert(SCIPsetIsSumEQ(set, lpiobj, col->flushedobj));
8795  assert(SCIPsetIsSumEQ(set, lpilb, col->flushedlb));
8796  assert(SCIPsetIsSumEQ(set, lpiub, col->flushedub));
8797  assert(col->flushedobj == col->obj); /*lint !e777*/
8798  assert(col->flushedlb == (SCIPsetIsInfinity(set, -col->lb) ? -SCIPlpiInfinity(lp->lpi) : col->lb)); /*lint !e777*/
8799  assert(col->flushedub == (SCIPsetIsInfinity(set, col->ub) ? SCIPlpiInfinity(lp->lpi) : col->ub)); /*lint !e777*/
8800  }
8801 #endif
8802  col->objchanged = FALSE;
8803  col->lbchanged = FALSE;
8804  col->ubchanged = FALSE;
8805  }
8806  /* maybe lb/ub/objchanged should be set to false also when lpipos is -1 */
8807  }
8808  lp->nchgcols = 0;
8809 
8810  /* mark the changed rows to be unchanged, and check, if this is really correct */
8811  for( i = 0; i < lp->nchgrows; ++i )
8812  {
8813  SCIP_ROW* row;
8814 
8815  row = lp->chgrows[i];
8816  assert(row != NULL);
8817 
8818  if( row->lpipos >= 0 )
8819  {
8820 #ifndef NDEBUG
8821  /* do not check consistency of data with LPI in case of LPI=none */
8822  if( !lpinone )
8823  {
8824  SCIP_Real lpilhs;
8825  SCIP_Real lpirhs;
8826 
8827  SCIP_CALL( SCIPlpiGetSides(lp->lpi, row->lpipos, row->lpipos, &lpilhs, &lpirhs) );
8828  assert(SCIPsetIsSumEQ(set, lpilhs, row->flushedlhs));
8829  assert(SCIPsetIsSumEQ(set, lpirhs, row->flushedrhs));
8830  assert(row->flushedlhs == (SCIPsetIsInfinity(set, -row->lhs) ? -SCIPlpiInfinity(lp->lpi) : row->lhs - row->constant)); /*lint !e777*/
8831  assert(row->flushedrhs == (SCIPsetIsInfinity(set, row->rhs) ? SCIPlpiInfinity(lp->lpi) : row->rhs - row->constant)); /*lint !e777*/
8832  }
8833 #endif
8834  row->lhschanged = FALSE;
8835  row->rhschanged = FALSE;
8836  }
8837  }
8838  lp->nchgrows = 0;
8839 
8840  /* mark the LP to be flushed */
8841  lp->flushed = TRUE;
8842 
8843  checkLinks(lp);
8844 
8845  return SCIP_OKAY;
8846 }
8847 
8848 
8849 
8850 
8851 /*
8852  * LP methods
8853  */
8854 
8855 /** updates link data after addition of column */
8856 static
8858  SCIP_COL* col, /**< LP column */
8859  SCIP_SET* set /**< global SCIP settings */
8860  )
8861 {
8862  SCIP_ROW* row;
8863  int i;
8864  int pos;
8865 
8866  assert(col != NULL);
8867  assert(col->lppos >= 0);
8868 
8869  /* update column arrays of all linked rows */
8870  for( i = 0; i < col->len; ++i )
8871  {
8872  pos = col->linkpos[i];
8873  if( pos >= 0 )
8874  {
8875  row = col->rows[i];
8876  assert(row != NULL);
8877  assert(row->linkpos[pos] == i);
8878  assert(row->cols[pos] == col);
8879  assert(row->nlpcols <= pos && pos < row->len);
8880 
8881  row->nlpcols++;
8882  rowSwapCoefs(row, pos, row->nlpcols-1);
8883  assert(row->cols[row->nlpcols-1] == col);
8884 
8885  /* if no swap was necessary, mark lpcols to be unsorted */
8886  if( pos == row->nlpcols-1 )
8887  row->lpcolssorted = FALSE;
8888 
8889  /* update norms */
8890  rowAddNorms(row, set, col, row->vals[row->nlpcols-1], FALSE);
8891  }
8892  }
8893 }
8894 
8895 /** updates link data after addition of row */
8896 static
8898  SCIP_ROW* row /**< LP row */
8899  )
8900 {
8901  SCIP_COL* col;
8902  int i;
8903  int pos;
8904 
8905  assert(row != NULL);
8906  assert(row->lppos >= 0);
8907 
8908  /* update row arrays of all linked columns */
8909  for( i = 0; i < row->len; ++i )
8910  {
8911  pos = row->linkpos[i];
8912  if( pos >= 0 )
8913  {
8914  col = row->cols[i];
8915  assert(col != NULL);
8916  assert(col->linkpos[pos] == i);
8917  assert(col->rows[pos] == row);
8918  assert(col->nlprows <= pos && pos < col->len);
8919 
8920  col->nlprows++;
8921  colSwapCoefs(col, pos, col->nlprows-1);
8922 
8923  /* if no swap was necessary, mark lprows to be unsorted */
8924  if( pos == col->nlprows-1 )
8925  col->lprowssorted = FALSE;
8926  }
8927  }
8928 }
8929 
8930 /** updates link data after removal of column */
8931 static
8933  SCIP_COL* col, /**< LP column */
8934  SCIP_SET* set /**< global SCIP settings */
8935  )
8936 {
8937  SCIP_ROW* row;
8938  int i;
8939  int pos;
8940 
8941  assert(col != NULL);
8942  assert(col->lppos == -1);
8943 
8944  /* update column arrays of all linked rows */
8945  for( i = 0; i < col->len; ++i )
8946  {
8947  pos = col->linkpos[i];
8948  if( pos >= 0 )
8949  {
8950  row = col->rows[i];
8951  assert(row != NULL);
8952  assert(row->linkpos[pos] == i);
8953  assert(row->cols[pos] == col);
8954  assert(0 <= pos && pos < row->nlpcols);
8955 
8956  /* update norms */
8957  rowDelNorms(row, set, col, row->vals[pos], TRUE, FALSE, FALSE);
8958 
8959  row->nlpcols--;
8960  rowSwapCoefs(row, pos, row->nlpcols);
8961 
8962  /* if no swap was necessary, mark nonlpcols to be unsorted */
8963  if( pos == row->nlpcols )
8964  row->nonlpcolssorted = FALSE;
8965  }
8966  }
8967 }
8968 
8969 /** updates link data after removal of row */
8970 static
8972  SCIP_ROW* row /**< LP row */
8973  )
8974 {
8975  SCIP_COL* col;
8976  int i;
8977  int pos;
8978 
8979  assert(row != NULL);
8980  assert(row->lppos == -1);
8981 
8982  /* update row arrays of all linked columns */
8983  for( i = 0; i < row->len; ++i )
8984  {
8985  pos = row->linkpos[i];
8986  if( pos >= 0 )
8987  {
8988  col = row->cols[i];
8989  assert(col != NULL);
8990  assert(0 <= pos && pos < col->nlprows);
8991  assert(col->linkpos[pos] == i);
8992  assert(col->rows[pos] == row);
8993 
8994  col->nlprows--;
8995  colSwapCoefs(col, pos, col->nlprows);
8996 
8997  /* if no swap was necessary, mark lprows to be unsorted */
8998  if( pos == col->nlprows )
8999  col->nonlprowssorted = FALSE;
9000  }
9001  }
9002 }
9003 
9004 static
9006  SCIP_LP* lp, /**< LP data object */
9007  int initsize /**< initial size of the arrays */
9008  )
9009 {
9010  assert(lp != NULL);
9011  assert(lp->divechgsides == NULL);
9012  assert(lp->divechgsidetypes == NULL);
9013  assert(lp->divechgrows == NULL);
9014  assert(lp->ndivechgsides == 0);
9015  assert(lp->divechgsidessize == 0);
9016  assert(initsize > 0);
9017 
9018  lp->divechgsidessize = initsize;
9022 
9023  return SCIP_OKAY;
9024 }
9025 
9026 static
9028  SCIP_LP* lp, /**< LP data object */
9029  int minsize, /**< minimal number of elements */
9030  SCIP_Real growfact /**< growing factor */
9031  )
9032 {
9033  assert(lp != NULL);
9034  assert(lp->divechgsides != NULL);
9035  assert(lp->divechgsidetypes != NULL);
9036  assert(lp->divechgrows != NULL);
9037  assert(lp->ndivechgsides > 0);
9038  assert(lp->divechgsidessize > 0);
9039  assert(minsize > 0);
9040 
9041  if( minsize <= lp->divechgsidessize )
9042  return SCIP_OKAY;
9043 
9044  lp->divechgsidessize = MAX(minsize, (int)(lp->divechgsidessize * growfact));
9048 
9049  return SCIP_OKAY;
9050 }
9051 
9052 static
9054  SCIP_LP* lp /**< LP data object */
9055  )
9056 {
9057  assert(lp != NULL);
9058  assert(lp->divechgsides != NULL);
9059  assert(lp->divechgsidetypes != NULL);
9060  assert(lp->divechgrows != NULL);
9061  assert(lp->ndivechgsides == 0);
9062  assert(lp->divechgsidessize > 0);
9063 
9067  lp->divechgsidessize = 0;
9068 }
9069 
9070 #define DIVESTACKINITSIZE 100
9071 
9072 /** creates empty LP data object */
9074  SCIP_LP** lp, /**< pointer to LP data object */
9075  SCIP_SET* set, /**< global SCIP settings */
9076  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
9077  SCIP_STAT* stat, /**< problem statistics */
9078  const char* name /**< problem name */
9079  )
9080 {
9081  SCIP_Bool success;
9082 
9083  assert(lp != NULL);
9084  assert(set != NULL);
9085  assert(stat != NULL);
9086  assert(name != NULL);
9087 
9088  SCIP_ALLOC( BMSallocMemory(lp) );
9089 
9090  /* open LP Solver interface */
9091  SCIP_CALL( SCIPlpiCreate(&(*lp)->lpi, messagehdlr, name, SCIP_OBJSEN_MINIMIZE) );
9092 
9093  (*lp)->lpicols = NULL;
9094  (*lp)->lpirows = NULL;
9095  (*lp)->chgcols = NULL;
9096  (*lp)->chgrows = NULL;
9097  (*lp)->cols = NULL;
9098  (*lp)->soldirection = NULL;
9099  (*lp)->lazycols = NULL;
9100  (*lp)->rows = NULL;
9101  (*lp)->lpobjval = 0.0;
9102  (*lp)->glbpseudoobjval = 0.0;
9103  (*lp)->relglbpseudoobjval = 0.0;
9104  (*lp)->glbpseudoobjvalid = TRUE;
9105  (*lp)->glbpseudoobjvalinf = 0;
9106  (*lp)->pseudoobjval = 0.0;
9107  (*lp)->relpseudoobjval = 0.0;
9108  (*lp)->pseudoobjvalid = TRUE;
9109  (*lp)->pseudoobjvalinf = 0;
9110  (*lp)->looseobjval = 0.0;
9111  (*lp)->rellooseobjval = 0.0;
9112  (*lp)->looseobjvalid = TRUE;
9113  (*lp)->looseobjvalinf = 0;
9114  (*lp)->nloosevars = 0;
9115  (*lp)->rootlpobjval = SCIP_INVALID;
9116  (*lp)->rootlooseobjval = SCIP_INVALID;
9117  (*lp)->cutoffbound = SCIPsetInfinity(set);
9118  (*lp)->feastol = SCIP_INVALID; /* to have it initialized */
9119  SCIPlpResetFeastol(*lp, set);
9120  (*lp)->validdegeneracylp = -1;
9121  (*lp)->objsqrnorm = 0.0;
9122  (*lp)->objsumnorm = 0.0;
9123  (*lp)->lpicolssize = 0;
9124  (*lp)->nlpicols = 0;
9125  (*lp)->lpirowssize = 0;
9126  (*lp)->nlpirows = 0;
9127  (*lp)->lpifirstchgcol = 0;
9128  (*lp)->lpifirstchgrow = 0;
9129  (*lp)->colssize = 0;
9130  (*lp)->soldirectionsize = 0;
9131  (*lp)->ncols = 0;
9132  (*lp)->lazycolssize = 0;
9133  (*lp)->nlazycols = 0;
9134  (*lp)->rowssize = 0;
9135  (*lp)->nrows = 0;
9136  (*lp)->chgcolssize = 0;
9137  (*lp)->nchgcols = 0;
9138  (*lp)->chgrowssize = 0;
9139  (*lp)->nchgrows = 0;
9140  (*lp)->firstnewcol = 0;
9141  (*lp)->firstnewrow = 0;
9142  (*lp)->nremovablecols = 0;
9143  (*lp)->nremovablerows = 0;
9144  (*lp)->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9145  (*lp)->validfarkaslp = -1;
9146  (*lp)->validsoldirlp = -1;
9147  (*lp)->validsoldirsol = NULL;
9148  (*lp)->objsqrnormunreliable = FALSE;
9149  (*lp)->flushdeletedcols = FALSE;
9150  (*lp)->flushaddedcols = FALSE;
9151  (*lp)->flushdeletedrows = FALSE;
9152  (*lp)->flushaddedrows = FALSE;
9153  (*lp)->updateintegrality = TRUE;
9154  (*lp)->flushed = TRUE;
9155  (*lp)->lpsolstat = SCIP_LPSOLSTAT_OPTIMAL;
9156  (*lp)->solved = TRUE;
9157  (*lp)->primalfeasible = TRUE;
9158  (*lp)->primalchecked = TRUE;
9159  (*lp)->dualfeasible = TRUE;
9160  (*lp)->dualchecked = TRUE;
9161  (*lp)->solisbasic = FALSE;
9162  (*lp)->rootlpisrelax = TRUE;
9163  (*lp)->isrelax = TRUE;
9164  (*lp)->installing = FALSE;
9165  (*lp)->strongbranching = FALSE;
9166  (*lp)->strongbranchprobing = FALSE;
9167  (*lp)->probing = FALSE;
9168  (*lp)->diving = FALSE;
9169  (*lp)->divingobjchg = FALSE;
9170  (*lp)->divinglazyapplied = FALSE;
9171  (*lp)->divelpistate = NULL;
9172  (*lp)->divelpwasprimfeas = TRUE;
9173  (*lp)->divelpwasprimchecked = TRUE;
9174  (*lp)->divelpwasdualfeas = TRUE;
9175  (*lp)->divelpwasdualchecked = TRUE;
9176  (*lp)->divechgsides = NULL;
9177  (*lp)->divechgsidetypes = NULL;
9178  (*lp)->divechgrows = NULL;
9179  (*lp)->ndivechgsides = 0;
9180  (*lp)->divechgsidessize = 0;
9181  (*lp)->ndivingrows = 0;
9182  (*lp)->divinglpiitlim = INT_MAX;
9183  (*lp)->resolvelperror = FALSE;
9184  (*lp)->divenolddomchgs = 0;
9185  (*lp)->adjustlpval = FALSE;
9186  (*lp)->lpiobjlim = SCIPlpiInfinity((*lp)->lpi);
9187  (*lp)->lpifeastol = (*lp)->feastol;
9188  (*lp)->lpidualfeastol = SCIPsetDualfeastol(set);
9189  (*lp)->lpibarrierconvtol = SCIPsetBarrierconvtol(set);
9190  (*lp)->lpifromscratch = FALSE;
9191  (*lp)->lpifastmip = set->lp_fastmip;
9192  (*lp)->lpiscaling = set->lp_scaling;
9193  (*lp)->lpipresolving = set->lp_presolving;
9194  (*lp)->lpilpinfo = set->disp_lpinfo;
9195  (*lp)->lpirowrepswitch = set->lp_rowrepswitch;
9196  (*lp)->lpisolutionpolishing = (set->lp_solutionpolishing > 0);
9197  (*lp)->lpirefactorinterval = set->lp_refactorinterval;
9198  (*lp)->lpiconditionlimit = set->lp_conditionlimit;
9199  (*lp)->lpimarkowitz = set->lp_markowitz;
9200  (*lp)->lpiitlim = INT_MAX;
9201  (*lp)->lpipricing = SCIP_PRICING_AUTO;
9202  (*lp)->lastlpalgo = SCIP_LPALGO_DUALSIMPLEX;
9203  (*lp)->lpithreads = set->lp_threads;
9204  (*lp)->lpitiming = (int) set->time_clocktype;
9205  (*lp)->lpirandomseed = set->random_randomseed;
9206  (*lp)->storedsolvals = NULL;
9207 
9208  /* allocate arrays for diving */
9210 
9211  /* set default parameters in LP solver */
9212  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_OBJLIM, (*lp)->lpiobjlim, &success) );
9213  if( !success )
9214  {
9215  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9216  "LP Solver <%s>: objective limit cannot be set -- can lead to unnecessary simplex iterations\n",
9218  }
9219  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_FEASTOL, (*lp)->lpifeastol, &success) );
9220  (*lp)->lpihasfeastol = success;
9221  if( !success )
9222  {
9223  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9224  "LP Solver <%s>: primal feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9226  }
9227  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_DUALFEASTOL, (*lp)->lpidualfeastol, &success) );
9228  (*lp)->lpihasdualfeastol = success;
9229  if( !success )
9230  {
9231  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9232  "LP Solver <%s>: dual feasibility tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9234  }
9235  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_BARRIERCONVTOL, (*lp)->lpibarrierconvtol, &success) );
9236  (*lp)->lpihasbarrierconvtol = success;
9237  if( !success )
9238  {
9239  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9240  "LP Solver <%s>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ\n",
9242  }
9243  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_FROMSCRATCH, (*lp)->lpifromscratch, &success) );
9244  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_FASTMIP, (*lp)->lpifastmip, &success) );
9245  (*lp)->lpihasfastmip = success;
9246  if( !success )
9247  {
9248  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9249  "LP Solver <%s>: fastmip setting not available -- SCIP parameter has no effect\n",
9251  }
9252  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_SCALING, (*lp)->lpiscaling, &success) );
9253  (*lp)->lpihasscaling = success;
9254  if( !success )
9255  {
9256  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9257  "LP Solver <%s>: scaling not available -- SCIP parameter has no effect\n",
9259  }
9260  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_PRESOLVING, (*lp)->lpipresolving, &success) );
9261  (*lp)->lpihaspresolving = success;
9262  if( !success )
9263  {
9264  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9265  "LP Solver <%s>: presolving not available -- SCIP parameter has no effect\n",
9267  }
9268  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_TIMING, (*lp)->lpitiming, &success) );
9269  if( !success )
9270  {
9271  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9272  "LP Solver <%s>: clock type cannot be set\n",
9274  }
9275  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_LPITLIM, (*lp)->lpiitlim, &success) );
9276  if( !success )
9277  {
9278  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9279  "LP Solver <%s>: iteration limit cannot be set -- can lead to unnecessary simplex iterations\n",
9281  }
9282  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_PRICING, (int)(*lp)->lpipricing, &success) );
9283  if( !success )
9284  {
9285  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9286  "LP Solver <%s>: pricing strategy cannot be set -- SCIP parameter has no effect\n",
9288  }
9289  SCIP_CALL( lpSetBoolpar(*lp, SCIP_LPPAR_LPINFO, (*lp)->lpilpinfo, &success) );
9290  if( !success )
9291  {
9292  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9293  "LP Solver <%s>: lpinfo setting not available -- SCIP parameter has no effect\n",
9295  }
9296  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_ROWREPSWITCH, (*lp)->lpirowrepswitch, &success) );
9297  (*lp)->lpihasrowrep = success;
9298  if( !success )
9299  {
9300  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9301  "LP Solver <%s>: row representation of the basis not available -- SCIP parameter lp/rowrepswitch has no effect\n",
9303  }
9304  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_POLISHING, ((*lp)->lpisolutionpolishing ? 1 : 0), &success) );
9305  (*lp)->lpihaspolishing = success;
9306  if( !success )
9307  {
9308  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9309  "LP Solver <%s>: solution polishing not available -- SCIP parameter lp/solutionpolishing has no effect\n",
9311  }
9312  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_REFACTOR, (*lp)->lpirefactorinterval, &success) );
9313  (*lp)->lpihasrefactor = success;
9314  if( !success )
9315  {
9316  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9317  "LP Solver <%s>: refactorization interval not available -- SCIP parameter lp/refactorinterval has no effect\n",
9319  }
9320  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_CONDITIONLIMIT, (*lp)->lpiconditionlimit, &success) );
9321  if( !success )
9322  {
9323  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9324  "LP Solver <%s>: condition number limit for the basis not available -- SCIP parameter lp/conditionlimit has no effect\n",
9326  }
9327  SCIP_CALL( lpSetRealpar(*lp, SCIP_LPPAR_MARKOWITZ, (*lp)->lpimarkowitz, &success) );
9328  if( !success )
9329  {
9330  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9331  "LP Solver <%s>: markowitz threshhold not available -- SCIP parameter lp/minmarkowitz has no effect\n",
9333  }
9334  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_THREADS, (*lp)->lpithreads, &success) );
9335  if( !success )
9336  {
9337  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9338  "LP Solver <%s>: number of threads settings not available -- SCIP parameter has no effect\n",
9340  }
9341  /* keep the default LP random seed if this parameter is set to 0 (current default) */
9342  if( (*lp)->lpirandomseed != 0 )
9343  {
9344  SCIP_CALL( lpSetIntpar(*lp, SCIP_LPPAR_RANDOMSEED, (*lp)->lpirandomseed, &success) );
9345  if( !success )
9346  {
9347  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
9348  "LP Solver <%s>: random seed parameter not available -- SCIP parameter has no effect\n",
9350  }
9351  }
9352 
9353  /* Check that infinity value of LP-solver is at least as large as the one used in SCIP. This is necessary, because we
9354  * transfer SCIP infinity values to the ones by the LPI, but not the converse. */
9355  if ( set->num_infinity > SCIPlpiInfinity((*lp)->lpi) )
9356  {
9357  SCIPerrorMessage("The infinity value of the LP solver has to be at least as large as the one of SCIP.\n");
9358  return SCIP_PARAMETERWRONGVAL;
9359  }
9360 
9361  return SCIP_OKAY;
9362 }
9363 
9364 /** frees LP data object */
9366  SCIP_LP** lp, /**< pointer to LP data object */
9367  BMS_BLKMEM* blkmem, /**< block memory */
9368  SCIP_SET* set, /**< global SCIP settings */
9369  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9370  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9371  )
9372 {
9373  int i;
9374 
9375  assert(lp != NULL);
9376  assert(*lp != NULL);
9377 
9378  SCIP_CALL( SCIPlpClear(*lp, blkmem, set, eventqueue, eventfilter) );
9379 
9380  freeDiveChgSideArrays(*lp);
9381 
9382  /* release LPI rows */
9383  for( i = 0; i < (*lp)->nlpirows; ++i )
9384  {
9385  SCIP_CALL( SCIProwRelease(&(*lp)->lpirows[i], blkmem, set, *lp) );
9386  }
9387 
9388  if( (*lp)->lpi != NULL )
9389  {
9390  SCIP_CALL( SCIPlpiFree(&(*lp)->lpi) );
9391  }
9392 
9393  BMSfreeMemoryNull(&(*lp)->storedsolvals);
9394  BMSfreeMemoryArrayNull(&(*lp)->lpicols);
9395  BMSfreeMemoryArrayNull(&(*lp)->lpirows);
9396  BMSfreeMemoryArrayNull(&(*lp)->chgcols);
9397  BMSfreeMemoryArrayNull(&(*lp)->chgrows);
9398  BMSfreeMemoryArrayNull(&(*lp)->lazycols);
9399  BMSfreeMemoryArrayNull(&(*lp)->cols);
9400  BMSfreeMemoryArrayNull(&(*lp)->rows);
9401  BMSfreeMemoryArrayNull(&(*lp)->soldirection);
9402  BMSfreeMemory(lp);
9403 
9404  return SCIP_OKAY;
9405 }
9406 
9407 /** resets the LP to the empty LP by removing all columns and rows from LP, releasing all rows, and flushing the
9408  * changes to the LP solver
9409  */
9411  SCIP_LP* lp, /**< LP data */
9412  BMS_BLKMEM* blkmem, /**< block memory */
9413  SCIP_SET* set, /**< global SCIP settings */
9414  SCIP_PROB* prob, /**< problem data */
9415  SCIP_STAT* stat, /**< problem statistics */
9416  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9417  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9418  )
9419 {
9420  assert(stat != NULL);
9421 
9422  SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
9423  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
9424 
9425  /* mark the empty LP to be solved */
9427  lp->lpobjval = 0.0;
9428  lp->validsollp = stat->lpcount; /* the initial (empty) SCIP_LP is solved with primal and dual solution of zero */
9429  lp->validfarkaslp = -1;
9430  lp->validdegeneracylp = -1;
9431  lp->validsoldirlp = -1;
9432  lp->validsoldirsol = NULL;
9433  lp->solved = TRUE;
9434  lp->primalfeasible = TRUE;
9435  lp->primalchecked = TRUE;
9436  lp->dualfeasible = TRUE;
9437  lp->dualchecked = TRUE;
9438  lp->solisbasic = FALSE;
9440 
9441  return SCIP_OKAY;
9442 }
9443 
9444 /** adds a column to the LP */
9446  SCIP_LP* lp, /**< LP data */
9447  SCIP_SET* set, /**< global SCIP settings */
9448  SCIP_COL* col, /**< LP column */
9449  int depth /**< depth in the tree where the column addition is performed */
9450  )
9451 {
9452  assert(lp != NULL);
9453  assert(!lp->diving);
9454  assert(col != NULL);
9455  assert(col->len == 0 || col->rows != NULL);
9456  assert(col->lppos == -1);
9457  assert(col->var != NULL);
9458  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9459  assert(SCIPvarGetCol(col->var) == col);
9460  assert(SCIPvarIsIntegral(col->var) == col->integral);
9461 
9462  SCIPsetDebugMsg(set, "adding column <%s> to LP (%d rows, %d cols)\n", SCIPvarGetName(col->var), lp->nrows, lp->ncols);
9463 #ifdef SCIP_DEBUG
9464  {
9465  int i;
9466  SCIPsetDebugMsgPrint(set, " (obj: %g) [%g,%g]", col->obj, col->lb, col->ub);
9467  for( i = 0; i < col->len; ++i )
9468  SCIPsetDebugMsgPrint(set, " %+g<%s>", col->vals[i], col->rows[i]->name);
9469  SCIPsetDebugMsgPrint(set, "\n");
9470  }
9471 #endif
9472 
9473  SCIP_CALL( ensureColsSize(lp, set, lp->ncols+1) );
9474  lp->cols[lp->ncols] = col;
9475  col->lppos = lp->ncols;
9476  col->lpdepth = depth;
9477  col->age = 0;
9478  lp->ncols++;
9479  if( col->removable )
9480  lp->nremovablecols++;
9481 
9482  if( !SCIPsetIsInfinity(set, -col->lazylb) || !SCIPsetIsInfinity(set, col->lazyub) )
9483  {
9484  SCIP_CALL( ensureLazycolsSize(lp, set, lp->nlazycols+1) );
9485  lp->lazycols[lp->nlazycols] = col;
9486  lp->nlazycols++;
9487  }
9488 
9489  /* mark the current LP unflushed */
9490  lp->flushed = FALSE;
9491 
9492  /* update column arrays of all linked rows */
9493  colUpdateAddLP(col, set);
9494 
9495  /* update the objective function vector norms */
9496  lpUpdateObjNorms(lp, set, 0.0, col->unchangedobj);
9497 
9498  checkLinks(lp);
9499 
9500  return SCIP_OKAY;
9501 }
9502 
9503 /** adds a row to the LP and captures it */
9505  SCIP_LP* lp, /**< LP data */
9506  BMS_BLKMEM* blkmem, /**< block memory buffers */
9507  SCIP_SET* set, /**< global SCIP settings */
9508  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9509  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9510  SCIP_ROW* row, /**< LP row */
9511  int depth /**< depth in the tree where the row addition is performed */
9512  )
9513 {
9514  assert(lp != NULL);
9515  assert(row != NULL);
9516  assert(row->len == 0 || row->cols != NULL);
9517  assert(row->lppos == -1);
9518 
9519  SCIProwCapture(row);
9520  SCIProwLock(row);
9521 
9522  SCIPsetDebugMsg(set, "adding row <%s> to LP (%d rows, %d cols)\n", row->name, lp->nrows, lp->ncols);
9523 #ifdef SCIP_DEBUG
9524  {
9525  int i;
9526  SCIPsetDebugMsgPrint(set, " %g <=", row->lhs);
9527  for( i = 0; i < row->len; ++i )
9528  SCIPsetDebugMsgPrint(set, " %+g<%s>", row->vals[i], SCIPvarGetName(row->cols[i]->var));
9529  if( !SCIPsetIsZero(set, row->constant) )
9530  SCIPsetDebugMsgPrint(set, " %+g", row->constant);
9531  SCIPsetDebugMsgPrint(set, " <= %g\n", row->rhs);
9532  }
9533 #endif
9534 
9535  SCIP_CALL( ensureRowsSize(lp, set, lp->nrows+1) );
9536  lp->rows[lp->nrows] = row;
9537  row->lppos = lp->nrows;
9538  row->lpdepth = depth;
9539  row->age = 0;
9540  lp->nrows++;
9541  if( row->removable )
9542  lp->nremovablerows++;
9543 
9544  /* mark the current LP unflushed */
9545  lp->flushed = FALSE;
9546 
9547  /* update row arrays of all linked columns */
9548  rowUpdateAddLP(row);
9549 
9550  checkLinks(lp);
9551 
9552  rowCalcNorms(row, set);
9553 
9554  /* check, if row addition to LP events are tracked
9555  * if so, issue ROWADDEDLP event
9556  */
9557  if( (eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWADDEDLP) != 0) )
9558  {
9559  SCIP_EVENT* event;
9560 
9561  SCIP_CALL( SCIPeventCreateRowAddedLP(&event, blkmem, row) );
9562  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9563  }
9564 
9565  return SCIP_OKAY;
9566 }
9567 
9568 
9569 #ifndef NDEBUG
9570 /** method checks if all columns in the lazycols array have at least one lazy bound and also have a counter part in the
9571  * cols array; furthermore, it is checked if columns in the cols array which have a lazy bound have a counter part in
9572  * the lazycols array
9573  */
9574 static
9576  SCIP_LP* lp, /**< LP data */
9577  SCIP_SET* set /**< global SCIP settings */
9578  )
9579 {
9580  SCIP_Bool contained;
9581  int c;
9582  int i;
9583 
9584  assert(lp != NULL);
9585 
9586  /* check if each column in the lazy column array has a counter part in the column array */
9587  for( i = 0; i < lp->nlazycols; ++i )
9588  {
9589  /* check if each lazy column has at least on lazy bound */
9590  assert(lp->lazycols[i] != NULL);
9591  assert(!SCIPsetIsInfinity(set, lp->lazycols[i]->lazyub) || !SCIPsetIsInfinity(set, -lp->lazycols[i]->lazylb));
9592 
9593  contained = FALSE;
9594  for( c = 0; c < lp->ncols; ++c )
9595  {
9596  if( lp->lazycols[i] == lp->cols[c] )
9597  {
9598  assert(!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb));
9599  contained = TRUE;
9600  }
9601  }
9602  assert(contained);
9603  }
9604 
9605  /* check if each column in the column array which has at least one lazy bound has a counter part in the lazy column *
9606  * array */
9607  for( c = 0; c < lp->ncols; ++c )
9608  {
9609  contained = FALSE;
9610  assert(lp->cols[c] != NULL);
9611 
9612  for( i = 0; i < lp->nlazycols; ++i )
9613  {
9614  if( lp->lazycols[i] == lp->cols[c] )
9615  {
9616  contained = TRUE;
9617  }
9618  }
9619 
9620  assert(contained == (!SCIPsetIsInfinity(set, lp->cols[c]->lazyub) || !SCIPsetIsInfinity(set, -lp->cols[c]->lazylb)));
9621  }
9622 }
9623 #else
9624 #define checkLazyColArray(lp, set) /**/
9625 #endif
9626 
9627 /** removes all columns after the given number of cols from the LP */
9629  SCIP_LP* lp, /**< LP data */
9630  SCIP_SET* set, /**< global SCIP settings */
9631  int newncols /**< new number of columns in the LP */
9632  )
9633 {
9634  SCIP_COL* col;
9635  int c;
9636 
9637  assert(lp != NULL);
9638 
9639  SCIPsetDebugMsg(set, "shrinking LP from %d to %d columns\n", lp->ncols, newncols);
9640  assert(0 <= newncols);
9641  assert(newncols <= lp->ncols);
9642 
9643  if( newncols < lp->ncols )
9644  {
9645  assert(!lp->diving);
9646 
9647  for( c = lp->ncols-1; c >= newncols; --c )
9648  {
9649  col = lp->cols[c];
9650  assert(col != NULL);
9651  assert(col->len == 0 || col->rows != NULL);
9652  assert(col->var != NULL);
9653  assert(SCIPvarGetStatus(col->var) == SCIP_VARSTATUS_COLUMN);
9654  assert(SCIPvarGetCol(col->var) == lp->cols[c]);
9655  assert(col->lppos == c);
9656 
9657  /* mark column to be removed from the LP */
9658  col->lppos = -1;
9659  col->lpdepth = -1;
9660  lp->ncols--;
9661 
9662  /* count removable columns */
9663  if( col->removable )
9664  lp->nremovablecols--;
9665 
9666  /* update column arrays of all linked rows */
9667  colUpdateDelLP(col, set);
9668 
9669  /* update the objective function vector norms */
9670  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
9671  }
9672  assert(lp->ncols == newncols);
9673  lp->lpifirstchgcol = MIN(lp->lpifirstchgcol, newncols);
9674 
9675  /* remove columns which are deleted from the lazy column array */
9676  c = 0;
9677  while( c < lp->nlazycols )
9678  {
9679  if( lp->lazycols[c]->lppos < 0 )
9680  {
9681  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
9682  lp->nlazycols--;
9683  }
9684  else
9685  c++;
9686  }
9687 
9688  /* mark the current LP unflushed */
9689  lp->flushed = FALSE;
9690 
9691  checkLazyColArray(lp, set);
9692  checkLinks(lp);
9693  }
9694  assert(lp->nremovablecols <= lp->ncols);
9695 
9696  return SCIP_OKAY;
9697 }
9698 
9699 /** removes and releases all rows after the given number of rows from the LP */
9701  SCIP_LP* lp, /**< LP data */
9702  BMS_BLKMEM* blkmem, /**< block memory */
9703  SCIP_SET* set, /**< global SCIP settings */
9704  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9705  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
9706  int newnrows /**< new number of rows in the LP */
9707  )
9708 {
9709  SCIP_ROW* row;
9710  int r;
9711 
9712  assert(lp != NULL);
9713  assert(0 <= newnrows && newnrows <= lp->nrows);
9714 
9715  SCIPsetDebugMsg(set, "shrinking LP from %d to %d rows\n", lp->nrows, newnrows);
9716  if( newnrows < lp->nrows )
9717  {
9718  for( r = lp->nrows-1; r >= newnrows; --r )
9719  {
9720  row = lp->rows[r];
9721  assert(row != NULL);
9722  assert(row->len == 0 || row->cols != NULL);
9723  assert(row->lppos == r);
9724 
9725  /* mark row to be removed from the LP */
9726  row->lppos = -1;
9727  row->lpdepth = -1;
9728  lp->nrows--;
9729 
9730  /* count removable rows */
9731  if( row->removable )
9732  lp->nremovablerows--;
9733 
9734  /* update row arrays of all linked columns */
9735  rowUpdateDelLP(row);
9736 
9737  SCIProwUnlock(lp->rows[r]);
9738 
9739  /* check, if row deletion events are tracked
9740  * if so, issue ROWDELETEDLP event
9741  */
9742  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
9743  {
9744  SCIP_EVENT* event;
9745 
9746  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, lp->rows[r]) );
9747  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
9748  }
9749 
9750  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
9751  }
9752  assert(lp->nrows == newnrows);
9753  lp->lpifirstchgrow = MIN(lp->lpifirstchgrow, newnrows);
9754 
9755  /* mark the current LP unflushed */
9756  lp->flushed = FALSE;
9757 
9758  checkLinks(lp);
9759  }
9760  assert(lp->nremovablerows <= lp->nrows);
9761 
9762  return SCIP_OKAY;
9763 }
9764 
9765 /** removes all columns and rows from LP, releases all rows */
9767  SCIP_LP* lp, /**< LP data */
9768  BMS_BLKMEM* blkmem, /**< block memory */
9769  SCIP_SET* set, /**< global SCIP settings */
9770  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
9771  SCIP_EVENTFILTER* eventfilter /**< global event filter */
9772  )
9773 {
9774  assert(lp != NULL);
9775  assert(!lp->diving);
9776 
9777  SCIPsetDebugMsg(set, "clearing LP\n");
9778  SCIP_CALL( SCIPlpShrinkCols(lp, set, 0) );
9779  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, 0) );
9780 
9781  return SCIP_OKAY;
9782 }
9783 
9784 /** remembers number of columns and rows to track the newly added ones */
9786  SCIP_LP* lp /**< current LP data */
9787  )
9788 {
9789  assert(lp != NULL);
9790  assert(!lp->diving);
9791 
9792  lp->firstnewrow = lp->nrows;
9793  lp->firstnewcol = lp->ncols;
9794 }
9795 
9796 /** sets the remembered number of columns and rows to the given values */
9798  SCIP_LP* lp, /**< current LP data */
9799  int nrows, /**< number of rows to set the size marker to */
9800  int ncols /**< number of columns to set the size marker to */
9801  )
9802 {
9803  assert(lp != NULL);
9804  assert(!lp->diving);
9805 
9806  lp->firstnewrow = nrows;
9807  lp->firstnewcol = ncols;
9808 }
9809 
9810 /** gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1 */
9812  SCIP_LP* lp, /**< LP data */
9813  int* basisind /**< pointer to store basis indices ready to keep number of rows entries */
9814  )
9815 {
9816  assert(lp != NULL);
9817  assert(lp->flushed);
9818  assert(lp->solved);
9819  assert(lp->solisbasic);
9820  assert(basisind != NULL);
9821 
9822  SCIP_CALL( SCIPlpiGetBasisInd(lp->lpi, basisind) );
9823 
9824  return SCIP_OKAY;
9825 }
9826 
9827 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
9829  SCIP_LP* lp, /**< LP data */
9830  int* cstat, /**< array to store column basis status, or NULL */
9831  int* rstat /**< array to store row basis status, or NULL */
9832  )
9833 {
9834  assert(lp != NULL);
9835  assert(lp->flushed);
9836  assert(lp->solved);
9837  assert(lp->solisbasic);
9838 
9839  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
9840 
9841  return SCIP_OKAY;
9842 }
9843 
9844 /** gets a row from the inverse basis matrix B^-1 */
9846  SCIP_LP* lp, /**< LP data */
9847  int r, /**< row number */
9848  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9849  int* inds, /**< array to store the non-zero indices, or NULL */
9850  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9851  * (-1: if we do not store sparsity informations) */
9852  )
9853 {
9854  assert(lp != NULL);
9855  assert(lp->flushed);
9856  assert(lp->solved);
9857  assert(lp->solisbasic);
9858  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9859  assert(coef != NULL);
9860 
9861  SCIP_CALL( SCIPlpiGetBInvRow(lp->lpi, r, coef, inds, ninds) );
9862 
9863  return SCIP_OKAY;
9864 }
9865 
9866 /** gets a column from the inverse basis matrix B^-1 */
9868  SCIP_LP* lp, /**< LP data */
9869  int c, /**< column number of B^-1; this is NOT the number of the column in the LP
9870  * returned by SCIPcolGetLPPos(); you have to call SCIPgetBasisInd()
9871  * to get the array which links the B^-1 column numbers to the row and
9872  * column numbers of the LP! c must be between 0 and nrows-1, since the
9873  * basis has the size nrows * nrows */
9874  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9875  int* inds, /**< array to store the non-zero indices, or NULL */
9876  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9877  * (-1: if we do not store sparsity informations) */
9878  )
9879 {
9880  assert(lp != NULL);
9881  assert(lp->flushed);
9882  assert(lp->solved);
9883  assert(lp->solisbasic);
9884  assert(0 <= c && c < lp->nrows); /* the basis matrix is nrows x nrows */
9885  assert(coef != NULL);
9886 
9887  SCIP_CALL( SCIPlpiGetBInvCol(lp->lpi, c, coef, inds, ninds) );
9888 
9889  return SCIP_OKAY;
9890 }
9891 
9892 /** gets a row from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A) */
9894  SCIP_LP* lp, /**< LP data */
9895  int r, /**< row number */
9896  SCIP_Real* binvrow, /**< row in B^-1 from prior call to SCIPlpGetBInvRow(), or NULL */
9897  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
9898  int* inds, /**< array to store the non-zero indices, or NULL */
9899  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9900  * (-1: if we do not store sparsity informations) */
9901  )
9902 {
9903  assert(lp != NULL);
9904  assert(lp->flushed);
9905  assert(lp->solved);
9906  assert(lp->solisbasic);
9907  assert(0 <= r && r < lp->nrows); /* the basis matrix is nrows x nrows */
9908  assert(coef != NULL);
9909 
9910  SCIP_CALL( SCIPlpiGetBInvARow(lp->lpi, r, binvrow, coef, inds, ninds) );
9911 
9912  return SCIP_OKAY;
9913 }
9914 
9915 /** gets a column from the product of inverse basis matrix B^-1 and coefficient matrix A (i.e. from B^-1 * A),
9916  * i.e., it computes B^-1 * A_c with A_c being the c'th column of A
9917  */
9919  SCIP_LP* lp, /**< LP data */
9920  int c, /**< column number which can be accessed by SCIPcolGetLPPos() */
9921  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
9922  int* inds, /**< array to store the non-zero indices, or NULL */
9923  int* ninds /**< pointer to store the number of non-zero indices, or NULL
9924  * (-1: if we do not store sparsity informations) */
9925  )
9926 {
9927  assert(lp != NULL);
9928  assert(lp->flushed);
9929  assert(lp->solved);
9930  assert(lp->solisbasic);
9931  assert(0 <= c && c < lp->ncols);
9932  assert(coef != NULL);
9933 
9934  SCIP_CALL( SCIPlpiGetBInvACol(lp->lpi, c, coef, inds, ninds) );
9935 
9936  return SCIP_OKAY;
9937 }
9938 
9939 /** calculates a weighted sum of all LP rows; for negative weights, the left and right hand side of the corresponding
9940  * LP row are swapped in the summation
9941  */
9943  SCIP_LP* lp, /**< LP data */
9944  SCIP_SET* set, /**< global SCIP settings */
9945  SCIP_PROB* prob, /**< problem data */
9946  SCIP_Real* weights, /**< row weights in row summation */
9947  SCIP_REALARRAY* sumcoef, /**< array to store sum coefficients indexed by variables' probindex */
9948  SCIP_Real* sumlhs, /**< pointer to store the left hand side of the row summation */
9949  SCIP_Real* sumrhs /**< pointer to store the right hand side of the row summation */
9950  )
9951 {
9952  SCIP_ROW* row;
9953  int r;
9954  int i;
9955  int idx;
9956  SCIP_Bool lhsinfinite;
9957  SCIP_Bool rhsinfinite;
9958 
9959  assert(lp != NULL);
9960  assert(prob != NULL);
9961  assert(weights != NULL);
9962  assert(sumcoef != NULL);
9963  assert(sumlhs != NULL);
9964  assert(sumrhs != NULL);
9965 
9966  /**@todo test, if a column based summation is faster */
9967 
9968  SCIP_CALL( SCIPrealarrayClear(sumcoef) );
9969  SCIP_CALL( SCIPrealarrayExtend(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, 0, prob->nvars-1) );
9970  *sumlhs = 0.0;
9971  *sumrhs = 0.0;
9972  lhsinfinite = FALSE;
9973  rhsinfinite = FALSE;
9974  for( r = 0; r < lp->nrows; ++r )
9975  {
9976  if( !SCIPsetIsZero(set, weights[r]) )
9977  {
9978  row = lp->rows[r];
9979  assert(row != NULL);
9980  assert(row->len == 0 || row->cols != NULL);
9981  assert(row->len == 0 || row->cols_index != NULL);
9982  assert(row->len == 0 || row->vals != NULL);
9983 
9984  /* add the row coefficients to the sum */
9985  for( i = 0; i < row->len; ++i )
9986  {
9987  assert(row->cols[i] != NULL);
9988  assert(row->cols[i]->var != NULL);
9989  assert(SCIPvarGetStatus(row->cols[i]->var) == SCIP_VARSTATUS_COLUMN);
9990  assert(SCIPvarGetCol(row->cols[i]->var) == row->cols[i]);
9991  assert(SCIPvarGetProbindex(row->cols[i]->var) == row->cols[i]->var_probindex);
9992  idx = row->cols[i]->var_probindex;
9993  assert(0 <= idx && idx < prob->nvars);
9994  SCIP_CALL( SCIPrealarrayIncVal(sumcoef, set->mem_arraygrowinit, set->mem_arraygrowfac, idx, weights[r] * row->vals[i]) );
9995  }
9996 
9997  /* add the row sides to the sum, depending on the sign of the weight */
9998  if( weights[r] > 0.0 )
9999  {
10000  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10001  if( !lhsinfinite )
10002  (*sumlhs) += weights[r] * (row->lhs - row->constant);
10003  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10004  if( !rhsinfinite )
10005  (*sumrhs) += weights[r] * (row->rhs - row->constant);
10006  }
10007  else
10008  {
10009  lhsinfinite = lhsinfinite || SCIPsetIsInfinity(set, row->rhs);
10010  if( !lhsinfinite )
10011  (*sumlhs) += weights[r] * (row->rhs - row->constant);
10012  rhsinfinite = rhsinfinite || SCIPsetIsInfinity(set, -row->lhs);
10013  if( !rhsinfinite )
10014  (*sumrhs) += weights[r] * (row->lhs - row->constant);
10015  }
10016  }
10017  }
10018 
10019  if( lhsinfinite )
10020  *sumlhs = -SCIPsetInfinity(set);
10021  if( rhsinfinite )
10022  *sumrhs = SCIPsetInfinity(set);
10023 
10024  return SCIP_OKAY;
10025 }
10026 
10027 /** stores LP state (like basis information) into LP state object */
10029  SCIP_LP* lp, /**< LP data */
10030  BMS_BLKMEM* blkmem, /**< block memory */
10031  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10032  )
10033 {
10034  assert(lp != NULL);
10035  assert(lp->flushed);
10036  assert(lp->solved);
10037  assert(blkmem != NULL);
10038  assert(lpistate != NULL);
10039 
10040  /* check whether there is no lp */
10041  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10042  *lpistate = NULL;
10043  else
10044  {
10045  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, lpistate) );
10046  }
10047 
10048  return SCIP_OKAY;
10049 }
10050 
10051 /** loads LP state (like basis information) into solver */
10053  SCIP_LP* lp, /**< LP data */
10054  BMS_BLKMEM* blkmem, /**< block memory */
10055  SCIP_SET* set, /**< global SCIP settings */
10056  SCIP_PROB* prob, /**< problem data */
10057  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
10058  SCIP_LPISTATE* lpistate, /**< LP state information (like basis information) */
10059  SCIP_Bool wasprimfeas, /**< primal feasibility when LP state information was stored */
10060  SCIP_Bool wasprimchecked, /**< true if the LP solution has passed the primal feasibility check */
10061  SCIP_Bool wasdualfeas, /**< dual feasibility when LP state information was stored */
10062  SCIP_Bool wasdualchecked /**< true if the LP solution has passed the dual feasibility check */
10063  )
10064 {
10065  assert(lp != NULL);
10066  assert(blkmem != NULL);
10067 
10068  /* flush changes to the LP solver */
10069  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
10070  assert(lp->flushed);
10071 
10072  if( lp->solved && lp->solisbasic )
10073  return SCIP_OKAY;
10074 
10075  /* set LPI state in the LP solver */
10076  if( lpistate == NULL )
10077  lp->solisbasic = FALSE;
10078  else
10079  {
10080  SCIP_CALL( SCIPlpiSetState(lp->lpi, blkmem, lpistate) );
10081  lp->solisbasic = SCIPlpiHasStateBasis(lp->lpi, lpistate);
10082  }
10083  /* @todo: setting feasibility to TRUE might be wrong because in probing mode, the state is even saved when the LP was
10084  * flushed and solved, also, e.g., when we hit the iteration limit
10085  */
10086  lp->primalfeasible = wasprimfeas;
10087  lp->primalchecked = wasprimchecked;
10088  lp->dualfeasible = wasdualfeas;
10089  lp->dualchecked = wasdualchecked;
10090 
10091  return SCIP_OKAY;
10092 }
10093 
10094 /** frees LP state information */
10096  SCIP_LP* lp, /**< LP data */
10097  BMS_BLKMEM* blkmem, /**< block memory */
10098  SCIP_LPISTATE** lpistate /**< pointer to LP state information (like basis information) */
10099  )
10100 {
10101  assert(lp != NULL);
10102 
10103  if( *lpistate != NULL )
10104  {
10105  SCIP_CALL( SCIPlpiFreeState(lp->lpi, blkmem, lpistate) );
10106  }
10107 
10108  return SCIP_OKAY;
10109 }
10110 
10111 /** interrupts the currently ongoing lp solve, or disables the interrupt */
10113  SCIP_LP* lp, /**< LP data */
10114  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
10115  )
10116 {
10117  assert(lp != NULL);
10118 
10119  if( lp->lpi == NULL )
10120  return SCIP_OKAY;
10121 
10122  SCIP_CALL( SCIPlpiInterrupt(lp->lpi, interrupt) );
10123 
10124  return SCIP_OKAY;
10125 }
10126 
10127 /** stores pricing norms into LP norms object */
10129  SCIP_LP* lp, /**< LP data */
10130  BMS_BLKMEM* blkmem, /**< block memory */
10131  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10132  )
10133 {
10134  assert(lp != NULL);
10135  assert(lp->flushed);
10136  assert(lp->solved);
10137  assert(blkmem != NULL);
10138  assert(lpinorms != NULL);
10139 
10140  /* check whether there is no lp */
10141  if( lp->nlpicols == 0 && lp->nlpirows == 0 )
10142  *lpinorms = NULL;
10143  else
10144  {
10145  SCIP_CALL( SCIPlpiGetNorms(lp->lpi, blkmem, lpinorms) );
10146  }
10147 
10148  return SCIP_OKAY;
10149 }
10150 
10151 /** loads pricing norms from LP norms object into solver */
10153  SCIP_LP* lp, /**< LP data */
10154  BMS_BLKMEM* blkmem, /**< block memory */
10155  SCIP_LPINORMS* lpinorms /**< LP pricing norms information */
10156  )
10157 {
10158  assert(lp != NULL);
10159  assert(blkmem != NULL);
10160  assert(lp->flushed);
10161 
10162  /* set LPI norms in the LP solver */
10163  if( lpinorms != NULL )
10164  {
10165  SCIP_CALL( SCIPlpiSetNorms(lp->lpi, blkmem, lpinorms) );
10166  }
10167 
10168  return SCIP_OKAY;
10169 }
10170 
10171 /** frees pricing norms information */
10173  SCIP_LP* lp, /**< LP data */
10174  BMS_BLKMEM* blkmem, /**< block memory */
10175  SCIP_LPINORMS** lpinorms /**< pointer to LP pricing norms information */
10176  )
10177 {
10178  assert(lp != NULL);
10179 
10180  SCIP_CALL( SCIPlpiFreeNorms(lp->lpi, blkmem, lpinorms) );
10181 
10182  return SCIP_OKAY;
10183 }
10184 
10185 /** return the current cutoff bound of the lp */
10187  SCIP_LP* lp /**< current LP data */
10188  )
10189 {
10190  assert(lp != NULL);
10191 
10192  return lp->cutoffbound;
10193 }
10194 
10195 /** sets the upper objective limit of the LP solver */
10197  SCIP_LP* lp, /**< current LP data */
10198  SCIP_SET* set, /**< global SCIP settings */
10199  SCIP_PROB* prob, /**< problem data */
10200  SCIP_Real cutoffbound /**< new upper objective limit */
10201  )
10202 {
10203  assert(lp != NULL);
10204 
10205  SCIPsetDebugMsg(set, "setting LP upper objective limit from %g to %g\n", lp->cutoffbound, cutoffbound);
10206 
10207  /* if the objective function was changed in diving, the cutoff bound has no meaning (it will be set correctly
10208  * in SCIPendDive())
10209  */
10210  if( SCIPlpDivingObjChanged(lp) )
10211  {
10212  assert(SCIPsetIsInfinity(set, lp->cutoffbound));
10213  return SCIP_OKAY;
10214  }
10215 
10216  /* if the cutoff bound is increased, and the LP was proved to exceed the old cutoff, it is no longer solved */
10217  if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT && cutoffbound > lp->cutoffbound )
10218  {
10219  /* mark the current solution invalid */
10220  lp->solved = FALSE;
10221  lp->lpobjval = SCIP_INVALID;
10223  }
10224  /* if the cutoff bound is decreased below the current optimal value, the LP now exceeds the objective limit;
10225  * if the objective limit in the LP solver was disabled, the solution status of the LP is not changed
10226  */
10227  else if( !lpCutoffDisabled(set, prob) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
10228  && SCIPlpGetObjval(lp, set, prob) >= cutoffbound )
10229  {
10230  assert(lp->flushed);
10231  assert(lp->solved);
10233  }
10234 
10235  lp->cutoffbound = cutoffbound;
10236 
10237  return SCIP_OKAY;
10238 }
10239 
10240 /** gets current primal feasibility tolerance of LP solver */
10242  SCIP_LP* lp /**< current LP data */
10243  )
10244 {
10245  assert(lp != NULL);
10246 
10247  return lp->feastol;
10248 }
10249 
10250 /** sets primal feasibility tolerance of LP solver */
10252  SCIP_LP* lp, /**< current LP data */
10253  SCIP_SET* set, /**< global SCIP settings */
10254  SCIP_Real newfeastol /**< new primal feasibility tolerance for LP */
10255  )
10256 {
10257  assert(lp != NULL);
10258  assert(newfeastol > 0.0);
10259 
10260  SCIPsetDebugMsg(set, "setting LP primal feasibility tolerance from %g to %g\n", lp->feastol, newfeastol);
10261 
10262  /* mark the LP unsolved, if the primal feasibility tolerance is tightened */
10263  if( newfeastol < lp->feastol )
10264  {
10265  lp->solved = FALSE;
10267  }
10268 
10269  lp->feastol = newfeastol;
10270 }
10271 
10272 /** resets primal feasibility tolerance of LP solver
10273  *
10274  * Sets primal feasibility tolerance to min of numerics/lpfeastolfactor * numerics/feastol and relaxfeastol.
10275  */
10277  SCIP_LP* lp, /**< current LP data */
10278  SCIP_SET* set /**< global SCIP settings */
10279  )
10280 {
10281  assert(lp != NULL);
10282 
10283  SCIPsetDebugMsg(set, "reset LP primal feasibility tolerance\n");
10284 
10285  if( SCIPsetRelaxfeastol(set) != SCIP_INVALID ) /*lint !e777*/
10286  SCIPlpSetFeastol(lp, set, MIN(SCIPsetRelaxfeastol(set), SCIPsetLPFeastolFactor(set) * SCIPsetFeastol(set))); /*lint !e666*/
10287  else
10289 }
10290 
10291 /** returns the name of the given LP algorithm */
10292 static
10293 const char* lpalgoName(
10294  SCIP_LPALGO lpalgo /**< LP algorithm */
10295  )
10296 {
10297  switch( lpalgo )
10298  {
10300  return "primal simplex";
10302  return "dual simplex";
10303  case SCIP_LPALGO_BARRIER:
10304  return "barrier";
10306  return "barrier/crossover";
10307  default:
10308  SCIPerrorMessage("invalid LP algorithm\n");
10309  SCIPABORT();
10310  return "invalid"; /*lint !e527*/
10311  }
10312 }
10313 
10314 /** calls LPI to perform primal simplex, measures time and counts iterations, gets basis feasibility status */
10315 static
10317  SCIP_LP* lp, /**< current LP data */
10318  SCIP_SET* set, /**< global SCIP settings */
10319  SCIP_STAT* stat, /**< problem statistics */
10320  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10321  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10322  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10323  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10324  )
10325 {
10326  SCIP_Real timedelta;
10327  SCIP_RETCODE retcode;
10328  int iterations;
10329 
10330  assert(lp != NULL);
10331  assert(lp->flushed);
10332  assert(set != NULL);
10333  assert(stat != NULL);
10334  assert(lperror != NULL);
10335 
10336  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",
10337  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10338 
10339  *lperror = FALSE;
10340 
10341 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10342  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10343  {
10344  char fname[SCIP_MAXSTRLEN];
10345  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10346  SCIP_CALL( SCIPlpWrite(lp, fname) );
10347  SCIPsetDebugMsg(set, "wrote LP to file <%s> (primal simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10348  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10349  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10350  }
10351 #endif
10352 
10353  /* start timing */
10354  if( lp->diving || lp->probing )
10355  {
10356  if( lp->strongbranchprobing )
10357  SCIPclockStart(stat->strongbranchtime, set);
10358  else
10359  SCIPclockStart(stat->divinglptime, set);
10360 
10361  timedelta = 0.0; /* unused for diving or probing */
10362  }
10363  else
10364  {
10365  SCIPclockStart(stat->primallptime, set);
10366  timedelta = -SCIPclockGetTime(stat->primallptime);
10367  }
10368 
10369  /* if this is a call to resolve an instable LP, collect time */
10370  if( instable )
10371  {
10373  }
10374 
10375  /* call primal simplex */
10376  retcode = SCIPlpiSolvePrimal(lp->lpi);
10377  if( retcode == SCIP_LPERROR )
10378  {
10379  *lperror = TRUE;
10380  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10381  }
10382  else
10383  {
10384  SCIP_CALL( retcode );
10385  }
10387  lp->solisbasic = TRUE;
10388 
10389  /* stop timing */
10390  if( lp->diving || lp->probing )
10391  {
10392  if( lp->strongbranchprobing )
10393  SCIPclockStop(stat->strongbranchtime, set);
10394  else
10395  SCIPclockStop(stat->divinglptime, set);
10396  }
10397  else
10398  {
10399  timedelta += SCIPclockGetTime(stat->primallptime);
10400  SCIPclockStop(stat->primallptime, set);
10401  }
10402 
10403  if ( instable )
10404  {
10406  }
10407 
10408  /* count number of iterations */
10409  SCIPstatIncrement(stat, set, lpcount);
10410  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10411  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10412  {
10413  if( !lp->strongbranchprobing )
10414  {
10415  SCIPstatIncrement(stat, set, nlps);
10416  SCIPstatAdd( stat, set, nlpiterations, iterations );
10417  }
10418  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10419  {
10420  SCIPstatIncrement(stat, set, nprimalresolvelps );
10421  SCIPstatAdd(stat, set, nprimalresolvelpiterations, iterations);
10422  }
10423  if ( instable )
10424  {
10425  SCIPstatIncrement(stat, set, nresolveinstablelps);
10426  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10427  }
10428  if( lp->diving || lp->probing )
10429  {
10430  if( lp->strongbranchprobing )
10431  {
10432  SCIPstatIncrement(stat, set, nsbdivinglps);
10433  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10434  }
10435  else
10436  {
10437  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10438  SCIPstatIncrement(stat, set, ndivinglps);
10439  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10440  }
10441  }
10442  else
10443  {
10444  SCIPstatIncrement(stat, set, nprimallps);
10445  SCIPstatAdd(stat, set, nprimallpiterations, iterations);
10446  }
10447  }
10448  else
10449  {
10450  if ( ! lp->diving && ! lp->probing )
10451  {
10452  SCIPstatIncrement(stat, set, nprimalzeroitlps);
10453  SCIPstatAdd(stat, set, primalzeroittime, timedelta);
10454  }
10455 
10456  if ( keepsol && !(*lperror) )
10457  {
10458  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10459  if( lp->validsollp == stat->lpcount-1 )
10460  lp->validsollp = stat->lpcount;
10461  if( lp->validfarkaslp == stat->lpcount-1 )
10462  lp->validfarkaslp = stat->lpcount;
10463  }
10464  }
10465 
10466  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with primal simplex (diving=%d, nprimallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10467  stat->lpcount, lp->diving || lp->probing, stat->nprimallps, stat->ndivinglps);
10468 
10469  return SCIP_OKAY;
10470 }
10471 
10472 /** calls LPI to perform dual simplex, measures time and counts iterations */
10473 static
10475  SCIP_LP* lp, /**< current LP data */
10476  SCIP_SET* set, /**< global SCIP settings */
10477  SCIP_STAT* stat, /**< problem statistics */
10478  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10479  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10480  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
10481  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10482  )
10483 {
10484  SCIP_Real timedelta;
10485  SCIP_RETCODE retcode;
10486  int iterations;
10487 
10488  assert(lp != NULL);
10489  assert(lp->flushed);
10490  assert(set != NULL);
10491  assert(stat != NULL);
10492  assert(lperror != NULL);
10493 
10494  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",
10495  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10496 
10497  *lperror = FALSE;
10498 
10499 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
10500  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
10501  {
10502  char fname[SCIP_MAXSTRLEN];
10503  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
10504  SCIP_CALL( SCIPlpWrite(lp, fname) );
10505  SCIPsetDebugMsg(set, "wrote LP to file <%s> (dual simplex, objlim=%.15g, feastol=%.15g/%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
10506  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol,
10507  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
10508  }
10509 #endif
10510 
10511  /* start timing */
10512  if( lp->diving || lp->probing )
10513  {
10514  if( lp->strongbranchprobing )
10515  SCIPclockStart(stat->strongbranchtime, set);
10516  else
10517  SCIPclockStart(stat->divinglptime, set);
10518 
10519  timedelta = 0.0; /* unused for diving or probing */
10520  }
10521  else
10522  {
10523  SCIPclockStart(stat->duallptime, set);
10524  timedelta = -SCIPclockGetTime(stat->duallptime);
10525  }
10526 
10527  /* if this is a call to resolve an instable LP, collect time */
10528  if ( instable )
10529  {
10531  }
10532 
10533  /* call dual simplex */
10534  retcode = SCIPlpiSolveDual(lp->lpi);
10535  if( retcode == SCIP_LPERROR )
10536  {
10537  *lperror = TRUE;
10538  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10539  }
10540  else
10541  {
10542  SCIP_CALL( retcode );
10543  }
10545  lp->solisbasic = TRUE;
10546 
10547  /* stop timing */
10548  if( lp->diving || lp->probing )
10549  {
10550  if( lp->strongbranchprobing )
10551  SCIPclockStop(stat->strongbranchtime, set);
10552  else
10553  SCIPclockStop(stat->divinglptime, set);
10554  }
10555  else
10556  {
10557  timedelta += SCIPclockGetTime(stat->duallptime);
10558  SCIPclockStop(stat->duallptime, set);
10559  }
10560 
10561  if ( instable )
10562  {
10564  }
10565 
10566  /* count number of iterations */
10567  SCIPstatIncrement(stat, set, lpcount);
10568  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10569  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10570  {
10571  if( !lp->strongbranchprobing )
10572  {
10573  SCIPstatIncrement(stat, set, nlps);
10574  SCIPstatAdd(stat, set, nlpiterations, iterations);
10575  }
10576  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10577  {
10578  SCIPstatIncrement(stat, set, ndualresolvelps);
10579  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10580  }
10581  if ( instable )
10582  {
10583  SCIPstatIncrement(stat, set, nresolveinstablelps);
10584  SCIPstatAdd(stat, set, nresolveinstablelpiters, iterations);
10585  }
10586  if( lp->diving || lp->probing )
10587  {
10588  if( lp->strongbranchprobing )
10589  {
10590  SCIPstatIncrement(stat, set, nsbdivinglps);
10591  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10592  }
10593  else
10594  {
10595  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10596  SCIPstatIncrement(stat, set, ndivinglps);
10597  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10598  }
10599  }
10600  else
10601  {
10602  SCIPstatIncrement(stat, set, nduallps);
10603  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10604  }
10605  }
10606  else
10607  {
10608  if ( ! lp->diving && ! lp->probing )
10609  {
10610  SCIPstatIncrement(stat, set, ndualzeroitlps);
10611  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10612  }
10613 
10614  if( keepsol && !(*lperror) )
10615  {
10616  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
10617  if( lp->validsollp == stat->lpcount-1 )
10618  lp->validsollp = stat->lpcount;
10619  if( lp->validfarkaslp == stat->lpcount-1 )
10620  lp->validfarkaslp = stat->lpcount;
10621  }
10622  }
10623 
10624  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
10625  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10626 
10627  return SCIP_OKAY;
10628 }
10629 
10630 /** calls LPI to perform lexicographic dual simplex to find a lexicographically minimal optimal solution, measures time and counts iterations
10631  *
10632  * We follow the approach of the following paper to find a lexicographically minimal optimal
10633  * solution:
10634  *
10635  * Zanette, Fischetti, Balas@n
10636  * Can pure cutting plane algorithms work?@n
10637  * IPCO 2008, Bertinoro, Italy.
10638  *
10639  * We do, however, not aim for the exact lexicographically minimal optimal solutions, but perform a
10640  * heuristic, i.e., we limit the number of components which are minimized.
10641  *
10642  * More precisely, we first solve the problem with the dual simplex algorithm. Then we fix those
10643  * nonbasic variables to their current value (i.e., one of the bounds except maybe for free
10644  * variables) that have nonzero reduced cost. This fixes the objective function value, because only
10645  * pivots that will not change the objective are allowed afterwards.
10646  *
10647  * Then the not yet fixed variables are considered in turn. If they are at their lower bounds and
10648  * nonbasic, they are fixed to this bound, since their value cannot be decreased further. Once a
10649  * candidate is found, we set the objective to minimize this variable. We run the primal simplex
10650  * algorithm (since the objective is changed the solution is not dual feasible anymore; if
10651  * variables out of the basis have been fixed to their lower bound, the basis is also not primal
10652  * feasible anymore). After the optimization, we again fix nonbasic variables that have nonzero
10653  * reduced cost. We then choose the next variable and iterate.
10654  *
10655  * We stop the process once we do not find candidates or have performed a maximum number of
10656  * iterations.
10657  *
10658  * @todo Does this really produce a lexicographically minimal solution?
10659  * @todo Can we skip the consideration of basic variables that are at their lower bound? How can we
10660  * guarantee that these variables will not be changed in later stages? We can fix these variables
10661  * to their lower bound, but this destroys the basis.
10662  * @todo Should we use lexicographical minimization in diving/probing or not?
10663  */
10664 static
10666  SCIP_LP* lp, /**< current LP data */
10667  SCIP_SET* set, /**< global SCIP settings */
10668  SCIP_STAT* stat, /**< problem statistics */
10669  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
10670  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
10671  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
10672  )
10673 {
10674  SCIP_Real timedelta;
10675  SCIP_RETCODE retcode;
10676  int totalIterations;
10677  int lexIterations;
10678  int iterations;
10679  int rounds;
10680 
10681  assert(lp != NULL);
10682  assert(lp->flushed);
10683  assert(set != NULL);
10684  assert(stat != NULL);
10685  assert(lperror != NULL);
10686 
10687  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",
10688  stat->lpcount+1, lp->ncols, lp->nrows, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
10689 
10690  *lperror = FALSE;
10691 
10692  /* start timing */
10693  if( lp->diving || lp->probing )
10694  {
10695  if( lp->strongbranchprobing )
10696  SCIPclockStart(stat->strongbranchtime, set);
10697  else
10698  SCIPclockStart(stat->divinglptime, set);
10699 
10700  timedelta = 0.0; /* unused for diving or probing */
10701  }
10702  else
10703  {
10704  SCIPclockStart(stat->duallptime, set);
10705  timedelta = -SCIPclockGetTime(stat->duallptime);
10706  }
10707 
10708  /* call dual simplex for first lp */
10709  retcode = SCIPlpiSolveDual(lp->lpi);
10710  if( retcode == SCIP_LPERROR )
10711  {
10712  *lperror = TRUE;
10713  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
10714  }
10715  else
10716  {
10717  SCIP_CALL( retcode );
10718  }
10719  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
10720  totalIterations = iterations;
10721 
10722  /* stop timing */
10723  if( lp->diving || lp->probing )
10724  {
10725  if( lp->strongbranchprobing )
10726  SCIPclockStop(stat->strongbranchtime, set);
10727  else
10728  SCIPclockStop(stat->divinglptime, set);
10729  }
10730  else
10731  {
10732  timedelta += SCIPclockGetTime(stat->duallptime);
10733  SCIPclockStop(stat->duallptime, set);
10734  }
10735 
10736  /* count number of iterations */
10737  SCIPstatIncrement(stat, set, lpcount);
10738  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
10739  {
10740  if( lp->strongbranchprobing )
10741  {
10742  SCIPstatAdd(stat, set, nlpiterations, iterations);
10743  }
10744  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
10745  {
10746  SCIPstatIncrement(stat, set, ndualresolvelps);
10747  SCIPstatAdd(stat, set, ndualresolvelpiterations, iterations);
10748  }
10749  if( lp->diving || lp->probing )
10750  {
10751  if( lp->strongbranchprobing )
10752  {
10753  SCIPstatIncrement(stat, set, nsbdivinglps);
10754  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
10755  }
10756  else
10757  {
10758  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
10759  SCIPstatIncrement(stat, set, ndivinglps);
10760  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
10761  }
10762  }
10763  else
10764  {
10765  SCIPstatIncrement(stat, set, nduallps);
10766  SCIPstatAdd(stat, set, nduallpiterations, iterations);
10767  }
10768  }
10769  else
10770  {
10771  if ( ! lp->diving && ! lp->probing )
10772  {
10773  SCIPstatIncrement(stat, set, ndualzeroitlps);
10774  SCIPstatAdd(stat, set, dualzeroittime, timedelta);
10775  }
10776  }
10777  lexIterations = 0;
10778 
10779  /* search for lexicographically minimal optimal solution */
10780  if( !lp->diving && !lp->probing && SCIPlpiIsOptimal(lp->lpi) )
10781  {
10782  SCIP_Bool chooseBasic;
10783  SCIP_Real* primsol;
10784  SCIP_Real* dualsol;
10785  SCIP_Real* redcost;
10786  int* cstat;
10787  int* rstat;
10788  SCIP_Real* newobj;
10789  SCIP_Real* newlb;
10790  SCIP_Real* newub;
10791  SCIP_Real* newlhs;
10792  SCIP_Real* newrhs;
10793  SCIP_Real* oldlb;
10794  SCIP_Real* oldub;
10795  SCIP_Real* oldlhs;
10796  SCIP_Real* oldrhs;
10797  SCIP_Real* oldobj;
10798  SCIP_Bool* fixedc;
10799  SCIP_Bool* fixedr;
10800  int* indcol;
10801  int* indrow;
10802  int* indallcol;
10803  int* indallrow;
10804  int nDualDeg;
10805  int r, c;
10806  int cntcol;
10807  int cntrow;
10808  int nruns;
10809  int pos;
10810 
10811  chooseBasic = set->lp_lexdualbasic;
10812 
10813  /* start timing */
10814  SCIPclockStart(stat->lexduallptime, set);
10815 
10816  /* get all solution information */
10817  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, lp->nlpirows) );
10818  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, lp->nlpicols) );
10819  if( chooseBasic )
10820  {
10821  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10822  }
10823  else
10824  primsol = NULL;
10825 
10826  /* get basic and nonbasic information */
10827  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, lp->nlpicols) );
10828  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, lp->nlpirows) );
10829 
10830  /* save bounds, lhs/rhs, and objective */
10831  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldobj, lp->nlpicols) );
10832  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlb, lp->nlpicols) );
10833  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldub, lp->nlpicols) );
10834  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldlhs, lp->nlpirows) );
10835  SCIP_CALL( SCIPsetAllocBufferArray(set, &oldrhs, lp->nlpirows) );
10836  SCIP_CALL( SCIPlpiGetBounds(lp->lpi, 0, lp->nlpicols-1, oldlb, oldub) );
10837  SCIP_CALL( SCIPlpiGetSides(lp->lpi, 0, lp->nlpirows-1, oldlhs, oldrhs) );
10838  SCIP_CALL( SCIPlpiGetObj(lp->lpi, 0, lp->nlpicols-1, oldobj) );
10839 
10840  /* get storage for several arrays */
10841  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlb, lp->nlpicols) );
10842  SCIP_CALL( SCIPsetAllocBufferArray(set, &newub, lp->nlpicols) );
10843  SCIP_CALL( SCIPsetAllocBufferArray(set, &indcol, lp->nlpicols) );
10844 
10845  SCIP_CALL( SCIPsetAllocBufferArray(set, &newlhs, lp->nlpirows) );
10846  SCIP_CALL( SCIPsetAllocBufferArray(set, &newrhs, lp->nlpirows) );
10847  SCIP_CALL( SCIPsetAllocBufferArray(set, &indrow, lp->nlpirows) );
10848 
10849  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallcol, lp->nlpicols) );
10850  SCIP_CALL( SCIPsetAllocBufferArray(set, &indallrow, lp->nlpirows) );
10851 
10852  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedc, lp->nlpicols) );
10853  SCIP_CALL( SCIPsetAllocBufferArray(set, &fixedr, lp->nlpirows) );
10854 
10855  /* initialize: set objective to 0, get fixed variables */
10856  SCIP_CALL( SCIPsetAllocBufferArray(set, &newobj, lp->nlpicols) );
10857  for( c = 0; c < lp->nlpicols; ++c )
10858  {
10859  newobj[c] = 0.0;
10860  indallcol[c] = c;
10861  if( SCIPsetIsFeasEQ(set, oldlb[c], oldub[c]) )
10862  fixedc[c] = TRUE;
10863  else
10864  fixedc[c] = FALSE;
10865  }
10866 
10867  /* initialize: get fixed slack variables */
10868  for( r = 0; r < lp->nlpirows; ++r )
10869  {
10870  indallrow[r] = r;
10871  if( SCIPsetIsFeasEQ(set, oldlhs[r], oldrhs[r]) )
10872  fixedr[r] = TRUE;
10873  else
10874  fixedr[r] = FALSE;
10875  }
10876 
10877 #ifdef DEBUG_LEXDUAL
10878  {
10879  int j;
10880 
10881  if( !chooseBasic )
10882  {
10883  assert(primsol == NULL);
10884  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
10885  }
10886  assert(primsol != NULL);
10887  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
10888  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10889 
10890  for( j = 0; j < lp->nlpicols; ++j )
10891  {
10892  if( fixedc[j] )
10893  {
10894  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
10895  }
10896  else
10897  {
10898  char type;
10899  switch( (SCIP_BASESTAT) cstat[j] )
10900  {
10901  case SCIP_BASESTAT_LOWER:
10902  type = 'l';
10903  break;
10904  case SCIP_BASESTAT_UPPER:
10905  type = 'u';
10906  break;
10907  case SCIP_BASESTAT_ZERO:
10908  type = 'z';
10909  break;
10910  case SCIP_BASESTAT_BASIC:
10911  type = 'b';
10912  break;
10913  default:
10914  type = '?';
10915  SCIPerrorMessage("unknown base stat %d\n", cstat[j]);
10916  SCIPABORT();
10917  }
10918  SCIPsetDebugMsg(set, "%f (%d) [%c] ", primsol[j], j, type);
10919  }
10920  }
10921  SCIPsetDebugMsg(set, "\n\n");
10922 
10923  if( !chooseBasic )
10924  {
10925  SCIPsetFreeBufferArray(set, &primsol);
10926  assert(primsol == NULL);
10927  }
10928  }
10929 #endif
10930 
10931  /* perform lexicographic rounds */
10932  pos = -1;
10933  nruns = 0;
10934  rounds = 0;
10935  /* SCIP_CALL( lpSetLPInfo(lp, TRUE) ); */
10936  do
10937  {
10938  int oldpos;
10939 
10940  /* get current solution */
10941  if( chooseBasic )
10942  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, NULL, redcost) );
10943  else
10944  {
10945  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, NULL, dualsol, NULL, redcost) );
10946  assert(primsol == NULL);
10947  }
10948 
10949  /* get current basis */
10950  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
10951 
10952  /* check columns: find first candidate (either basic or nonbasic and zero reduced cost) and fix variables */
10953  nDualDeg = 0;
10954  cntcol = 0;
10955  oldpos = pos;
10956  pos = -1;
10957  for( c = 0; c < lp->nlpicols; ++c )
10958  {
10959  if( !fixedc[c] )
10960  {
10961  /* check whether variable is in basis */
10962  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_BASIC )
10963  {
10964  /* store first candidate */
10965  if( pos == -1 && c > oldpos )
10966  {
10967  if( !chooseBasic || !SCIPsetIsIntegral(set, primsol[c]) ) /*lint !e613*/
10968  pos = c;
10969  }
10970  }
10971  else
10972  {
10973  /* reduced cost == 0 -> possible candidate */
10974  if( SCIPsetIsDualfeasZero(set, redcost[c]) )
10975  {
10976  ++nDualDeg;
10977  /* only if we have not yet found a candidate */
10978  if( pos == -1 && c > oldpos )
10979  {
10980  /* if the variable is at its lower bound - fix it, because its value cannot be reduced */
10981  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10982  {
10983  newlb[cntcol] = oldlb[c];
10984  newub[cntcol] = oldlb[c];
10985  indcol[cntcol++] = c;
10986  fixedc[c] = TRUE;
10987  }
10988  else /* found a non-fixed candidate */
10989  {
10990  if( !chooseBasic )
10991  pos = c;
10992  }
10993  }
10994  }
10995  else
10996  {
10997  /* nonzero reduced cost -> variable can be fixed */
10998  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_LOWER )
10999  {
11000  newlb[cntcol] = oldlb[c];
11001  newub[cntcol] = oldlb[c];
11002  }
11003  else
11004  {
11005  if( (SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_UPPER )
11006  {
11007  newlb[cntcol] = oldub[c];
11008  newub[cntcol] = oldub[c];
11009  }
11010  else
11011  {
11012  assert((SCIP_BASESTAT) cstat[c] == SCIP_BASESTAT_ZERO);
11013  newlb[cntcol] = 0.0;
11014  newub[cntcol] = 0.0;
11015  }
11016  }
11017  indcol[cntcol++] = c;
11018  fixedc[c] = TRUE;
11019  }
11020  }
11021  }
11022  }
11023 
11024  /* check rows */
11025  cntrow = 0;
11026  for( r = 0; r < lp->nlpirows; ++r )
11027  {
11028  if( !fixedr[r] )
11029  {
11030  /* consider only nonbasic rows */
11031  if( (SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_BASIC )
11032  {
11033  assert((SCIP_BASESTAT) rstat[r] != SCIP_BASESTAT_ZERO);
11034  if( SCIPsetIsFeasZero(set, dualsol[r]) )
11035  ++nDualDeg;
11036  else
11037  {
11038  if( SCIPsetIsFeasPositive(set, dualsol[r]) )
11039  {
11040  assert(!SCIPsetIsInfinity(set, -oldlhs[r]));
11041  newlhs[cntrow] = oldlhs[r];
11042  newrhs[cntrow] = oldlhs[r];
11043  }
11044  else
11045  {
11046  assert(!SCIPsetIsInfinity(set, oldrhs[r]));
11047  newlhs[cntrow] = oldrhs[r];
11048  newrhs[cntrow] = oldrhs[r];
11049  }
11050  indrow[cntrow++] = r;
11051  fixedr[r] = TRUE;
11052  }
11053  }
11054  }
11055  }
11056 
11057  if( nDualDeg > 0 && pos >= 0 )
11058  {
11059  assert(0 <= pos && pos < lp->nlpicols && pos > oldpos);
11060 
11061  /* change objective */
11062  if( nruns == 0 )
11063  {
11064  /* set objective to appropriate unit vector for first run */
11065  newobj[pos] = 1.0;
11066  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, newobj) );
11067  }
11068  else
11069  {
11070  /* set obj. coef. to 1 for other runs (ones remain in previous positions) */
11071  SCIP_Real obj = 1.0;
11072  SCIP_CALL( SCIPlpiChgObj(lp->lpi, 1, &pos, &obj) );
11073  }
11074 
11075  /* fix variables */
11076  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, cntcol, indcol, newlb, newub) );
11077  SCIP_CALL( SCIPlpiChgSides(lp->lpi, cntrow, indrow, newlhs, newrhs) );
11078 
11079  /* solve with primal simplex, because we are primal feasible, but not necessarily dual feasible */
11080  retcode = SCIPlpiSolvePrimal(lp->lpi);
11081  if( retcode == SCIP_LPERROR )
11082  {
11083  *lperror = TRUE;
11084  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") in lex-dual: primal simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11085  }
11086  else
11087  {
11088  SCIP_CALL( retcode );
11089  }
11090  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11091  lexIterations += iterations;
11092 
11093 #ifdef DEBUG_LEXDUAL
11094  if( iterations > 0 )
11095  {
11096  int j;
11097 
11098  if( !chooseBasic )
11099  {
11100  assert(primsol == NULL);
11101  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
11102  }
11103  assert(primsol != NULL);
11104  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
11105 
11106  for( j = 0; j < lp->nlpicols; ++j )
11107  {
11108  if( fixedc[j] )
11109  {
11110  SCIPsetDebugMsg(set, "%f (%d) [f] ", primsol[j], j);
11111  }
11112  else
11113  {
11114  char cstart = '[';
11115  char cend = ']';
11116  char type;
11117 
11118  if(j == pos)
11119  {
11120  cstart = '*';
11121  cend = '*';
11122  }
11123 
11124  switch( (SCIP_BASESTAT) cstat[j] )
11125  {
11126  case SCIP_BASESTAT_LOWER:
11127  type = 'l';
11128  break;
11129  case SCIP_BASESTAT_UPPER:
11130  type = 'u';
11131  break;
11132  case SCIP_BASESTAT_ZERO:
11133  type = 'z';
11134  break;
11135  case SCIP_BASESTAT_BASIC:
11136  type = 'b';
11137  break;
11138  default:
11139  type = '?';
11140  SCIPerrorMessage("unknown base state %d\n", cstat[j]);
11141  SCIPABORT();
11142  }
11143  SCIPsetDebugMsg(set, "%f (%d) %c%c%c ", primsol[j], j, cstart, type, cend);
11144  }
11145  }
11146  SCIPsetDebugMsg(set, "\n\n");
11147 
11148  if( !chooseBasic )
11149  {
11150  SCIPsetFreeBufferArray(set, &primsol);
11151  assert(primsol == NULL);
11152  }
11153  }
11154 #endif
11155 
11156  /* count only as round if iterations have been performed */
11157  if( iterations > 0 )
11158  ++rounds;
11159  ++nruns;
11160  }
11161  }
11162  while( pos >= 0 && nDualDeg > 0 && (set->lp_lexdualmaxrounds == -1 || rounds < set->lp_lexdualmaxrounds) );
11163 
11164  /* reset bounds, lhs/rhs, and obj */
11165  SCIP_CALL( SCIPlpiChgBounds(lp->lpi, lp->nlpicols, indallcol, oldlb, oldub) );
11166  SCIP_CALL( SCIPlpiChgSides(lp->lpi, lp->nlpirows, indallrow, oldlhs, oldrhs) );
11167  SCIP_CALL( SCIPlpiChgObj(lp->lpi, lp->nlpicols, indallcol, oldobj) );
11168 
11169  /* resolve to update solvers internal data structures - should only produce few pivots - is this needed? */
11170  retcode = SCIPlpiSolveDual(lp->lpi);
11171  if( retcode == SCIP_LPERROR )
11172  {
11173  *lperror = TRUE;
11174  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") dual simplex solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11175  }
11176  else
11177  {
11178  SCIP_CALL( retcode );
11179  }
11180  assert(SCIPlpiIsOptimal(lp->lpi));
11181  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11182  lexIterations += iterations;
11183 
11184  /* SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) ); */
11185 
11186  /* count number of iterations */
11187  if( totalIterations == 0 && lexIterations > 0 && !lp->strongbranchprobing )
11188  SCIPstatIncrement(stat, set, nlps);
11189 
11190  if( lexIterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11191  {
11192  SCIPstatAdd(stat, set, nlpiterations, lexIterations);
11193  if( resolve && !lp->lpifromscratch && stat->nlps > 1 )
11194  {
11195  SCIPstatIncrement(stat, set, nlexdualresolvelps);
11196  SCIPstatAdd(stat, set, nlexdualresolvelpiterations, lexIterations);
11197  }
11198  SCIPstatIncrement(stat, set, nlexduallps);
11199  SCIPstatAdd(stat, set, nlexduallpiterations, lexIterations);
11200 
11201  totalIterations += lexIterations;
11202  }
11203 
11204  /* free space */
11205  SCIPsetFreeBufferArray(set, &newobj);
11206 
11207  SCIPsetFreeBufferArray(set, &fixedr);
11208  SCIPsetFreeBufferArray(set, &fixedc);
11209 
11210  SCIPsetFreeBufferArray(set, &indallrow);
11211  SCIPsetFreeBufferArray(set, &indallcol);
11212 
11213  SCIPsetFreeBufferArray(set, &indrow);
11214  SCIPsetFreeBufferArray(set, &newrhs);
11215  SCIPsetFreeBufferArray(set, &newlhs);
11216 
11217  SCIPsetFreeBufferArray(set, &indcol);
11218  SCIPsetFreeBufferArray(set, &newub);
11219  SCIPsetFreeBufferArray(set, &newlb);
11220 
11221  SCIPsetFreeBufferArray(set, &oldobj);
11222  SCIPsetFreeBufferArray(set, &oldrhs);
11223  SCIPsetFreeBufferArray(set, &oldlhs);
11224  SCIPsetFreeBufferArray(set, &oldub);
11225  SCIPsetFreeBufferArray(set, &oldlb);
11226 
11227  SCIPsetFreeBufferArray(set, &rstat);
11228  SCIPsetFreeBufferArray(set, &cstat);
11229 
11230  SCIPsetFreeBufferArray(set, &redcost);
11231  SCIPsetFreeBufferArray(set, &dualsol);
11232  if( chooseBasic )
11233  SCIPsetFreeBufferArray(set, &primsol);
11234 
11235  /* stop timing */
11236  SCIPclockStop(stat->lexduallptime, set);
11237 
11238  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with lex dual simplex (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", ndivinglps=%" SCIP_LONGINT_FORMAT ")\n",
11239  stat->lpcount, lp->diving || lp->probing, stat->nduallps, stat->ndivinglps);
11240  }
11242  lp->solisbasic = TRUE;
11243 
11244  if( totalIterations > 0 && !lp->strongbranchprobing )
11245  SCIPstatIncrement(stat, set, nlps);
11246  else
11247  {
11248  if( keepsol && !(*lperror) )
11249  {
11250  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11251  if( lp->validsollp == stat->lpcount-1 )
11252  lp->validsollp = stat->lpcount;
11253  if( lp->validfarkaslp == stat->lpcount-1 )
11254  lp->validfarkaslp = stat->lpcount;
11255  }
11256  }
11257 
11258  return SCIP_OKAY;
11259 }
11260 
11261 /** calls LPI to perform barrier, measures time and counts iterations, gets basis feasibility status */
11262 static
11264  SCIP_LP* lp, /**< current LP data */
11265  SCIP_SET* set, /**< global SCIP settings */
11266  SCIP_STAT* stat, /**< problem statistics */
11267  SCIP_Bool crossover, /**< should crossover be performed? */
11268  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11269  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11270  )
11271 {
11272  SCIP_Real timedelta;
11273  SCIP_RETCODE retcode;
11274  int iterations;
11275 
11276  assert(lp != NULL);
11277  assert(lp->flushed);
11278  assert(set != NULL);
11279  assert(stat != NULL);
11280  assert(lperror != NULL);
11281 
11282  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",
11283  stat->lpcount+1, lp->ncols, lp->nrows, crossover ? "/crossover" : "", lp->diving || lp->probing,
11284  stat->nbarrierlps, stat->ndivinglps);
11285 
11286  *lperror = FALSE;
11287 
11288 #ifdef SCIP_MORE_DEBUG /* for debugging: write all root node LP's */
11289  if( stat->nnodes == 1 && !lp->diving && !lp->probing )
11290  {
11291  char fname[SCIP_MAXSTRLEN];
11292  (void) SCIPsnprintf(fname, SCIP_MAXSTRLEN, "lp%" SCIP_LONGINT_FORMAT "_%" SCIP_LONGINT_FORMAT ".lp", stat->nnodes, stat->lpcount);
11293  SCIP_CALL( SCIPlpWrite(lp, fname) );
11294  SCIPsetDebugMsg(set, "wrote LP to file <%s> (barrier, objlim=%.15g, feastol=%.15g/%.15g, convtol=%.15g, fromscratch=%d, fastmip=%d, scaling=%d, presolving=%d)\n",
11295  fname, lp->lpiobjlim, lp->lpifeastol, lp->lpidualfeastol, lp->lpibarrierconvtol,
11296  lp->lpifromscratch, lp->lpifastmip, lp->lpiscaling, lp->lpipresolving);
11297  }
11298 #endif
11299 
11300  /* start timing */
11301  if( lp->diving || lp->probing )
11302  {
11303  if( lp->strongbranchprobing )
11304  SCIPclockStart(stat->strongbranchtime, set);
11305  else
11306  SCIPclockStart(stat->divinglptime, set);
11307 
11308  timedelta = 0.0; /* unused for diving or probing */
11309  }
11310  else
11311  {
11312  SCIPclockStart(stat->barrierlptime, set);
11313  timedelta = -SCIPclockGetTime(stat->barrierlptime);
11314  }
11315 
11316  /* call barrier algorithm */
11317  retcode = SCIPlpiSolveBarrier(lp->lpi, crossover);
11318  if( retcode == SCIP_LPERROR )
11319  {
11320  *lperror = TRUE;
11321  SCIPsetDebugMsg(set, "(node %" SCIP_LONGINT_FORMAT ") barrier solving error in LP %" SCIP_LONGINT_FORMAT "\n", stat->nnodes, stat->nlps);
11322  }
11323  else
11324  {
11325  SCIP_CALL( retcode );
11326  }
11328  lp->solisbasic = crossover;
11329 
11330  /* stop timing */
11331  if( lp->diving || lp->probing )
11332  {
11333  if( lp->strongbranchprobing )
11334  SCIPclockStop(stat->strongbranchtime, set);
11335  else
11336  SCIPclockStop(stat->divinglptime, set);
11337  }
11338  else
11339  {
11340  SCIPclockStop(stat->barrierlptime, set);
11341  timedelta += SCIPclockGetTime(stat->barrierlptime);
11342  }
11343 
11344  /* count number of iterations */
11345  SCIPstatIncrement(stat, set, lpcount);
11346  SCIP_CALL( SCIPlpGetIterations(lp, &iterations) );
11347  if( iterations > 0 ) /* don't count the resolves after removing unused columns/rows */
11348  {
11349  if( !lp->strongbranchprobing )
11350  {
11351  SCIPstatIncrement(stat, set, nlps);
11352  SCIPstatAdd(stat, set, nlpiterations, iterations);
11353  }
11354  if( lp->diving || lp->probing )
11355  {
11356  if( lp->strongbranchprobing )
11357  {
11358  SCIPstatIncrement(stat, set, nsbdivinglps);
11359  SCIPstatAdd(stat, set, nsbdivinglpiterations, iterations);
11360  }
11361  else
11362  {
11363  SCIPstatUpdate(stat, set, lastdivenode, stat->nnodes);
11364  SCIPstatIncrement(stat, set, ndivinglps);
11365  SCIPstatAdd(stat, set, ndivinglpiterations, iterations);
11366  }
11367  }
11368  else
11369  {
11370  SCIPstatIncrement(stat, set, nbarrierlps);
11371  SCIPstatAdd(stat, set, nbarrierlpiterations, iterations);
11372  }
11373  }
11374  else
11375  {
11376  if ( ! lp->diving && ! lp->probing )
11377  {
11378  SCIPstatIncrement(stat, set, nbarrierzeroitlps);
11379  SCIPstatAdd(stat, set, barrierzeroittime, timedelta);
11380  }
11381 
11382  if( keepsol && !(*lperror) )
11383  {
11384  /* the solution didn't change: if the solution was valid before resolve, it is still valid */
11385  if( lp->validsollp == stat->lpcount-1 )
11386  lp->validsollp = stat->lpcount;
11387  if( lp->validfarkaslp == stat->lpcount-1 )
11388  lp->validfarkaslp = stat->lpcount;
11389  }
11390  }
11391 
11392  SCIPsetDebugMsg(set, "solved LP %" SCIP_LONGINT_FORMAT " with barrier%s (diving=%d, nduallps=%" SCIP_LONGINT_FORMAT ", nbarrierlps=%" SCIP_LONGINT_FORMAT ")\n",
11393  stat->lpcount, crossover ? "/crossover" : "", lp->diving || lp->probing, stat->nbarrierlps, stat->ndivinglps);
11394 
11395  return SCIP_OKAY;
11396 }
11397 
11398 /** solves the LP with the given algorithm */
11399 static
11401  SCIP_LP* lp, /**< current LP data */
11402  SCIP_SET* set, /**< global SCIP settings */
11403  SCIP_STAT* stat, /**< problem statistics */
11404  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11405  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11406  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11407  SCIP_Bool instable, /**< is this a resolving call to avoid instable LPs? */
11408  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11409  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11410  )
11411 {
11412  SCIP_Real lptimelimit;
11413  SCIP_Bool success;
11414 
11415  assert(lp != NULL);
11416  assert(lp->flushed);
11417  assert(lperror != NULL);
11418 
11419  /* check if a time limit is set, and set time limit for LP solver accordingly */
11420  lptimelimit = SCIPlpiInfinity(lp->lpi);
11421  if( set->istimelimitfinite )
11422  lptimelimit = set->limit_time - SCIPclockGetTime(stat->solvingtime);
11423 
11424  success = FALSE;
11425  if( lptimelimit > 0.0 )
11426  SCIP_CALL( lpSetRealpar(lp, SCIP_LPPAR_LPTILIM, lptimelimit, &success) );
11427 
11428  if( lptimelimit <= 0.0 || !success )
11429  {
11430  SCIPsetDebugMsg(set, "time limit of %f seconds could not be set\n", lptimelimit);
11431  *lperror = ((lptimelimit > 0.0) ? TRUE : FALSE);
11432  *timelimit = TRUE;
11433  return SCIP_OKAY;
11434  }
11435  SCIPsetDebugMsg(set, "calling LP algorithm <%s> with a time limit of %g seconds\n", lpalgoName(lpalgo), lptimelimit);
11436 
11437  /* call appropriate LP algorithm */
11438  switch( lpalgo )
11439  {
11441  SCIP_CALL( lpPrimalSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11442  break;
11443 
11445  /* run dual lexicographic simplex if required */
11446  if( set->lp_lexdualalgo && (!set->lp_lexdualrootonly || stat->maxdepth == 0) && (!set->lp_lexdualstalling || lp->installing) )
11447  {
11448  SCIP_CALL( lpLexDualSimplex(lp, set, stat, resolve, keepsol, lperror) );
11449  }
11450  else
11451  {
11452  SCIP_CALL( lpDualSimplex(lp, set, stat, resolve, keepsol, instable, lperror) );
11453  }
11454  break;
11455 
11456  case SCIP_LPALGO_BARRIER:
11457  SCIP_CALL( lpBarrier(lp, set, stat, FALSE, keepsol, lperror) );
11458  break;
11459 
11461  SCIP_CALL( lpBarrier(lp, set, stat, TRUE, keepsol, lperror) );
11462  break;
11463 
11464  default:
11465  SCIPerrorMessage("invalid LP algorithm\n");
11466  return SCIP_INVALIDDATA;
11467  }
11468 
11469  if( !(*lperror) )
11470  {
11471  /* check for primal and dual feasibility */
11473 
11474  SCIPsetDebugMsg(set, "LP feasibility: primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
11475  }
11476 
11477  return SCIP_OKAY;
11478 }
11479 
11480 /** maximal number of verblevel-high messages about numerical trouble in LP that will be printed
11481  * when this number is reached and display/verblevel is not full, then further messages are suppressed in this run
11482  */
11483 #define MAXNUMTROUBLELPMSGS 10
11484 
11485 /** prints message about numerical trouble
11486  *
11487  * If message has verblevel at most high and display/verblevel is not full,
11488  * then the message is not printed if already MAXNUMTROUBLELPMSGS messages
11489  * were printed before in the current run.
11490  */
11491 static
11493  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11494  SCIP_SET* set, /**< global SCIP settings */
11495  SCIP_STAT* stat, /**< problem statistics */
11496  SCIP_VERBLEVEL verblevel, /**< verbosity level of message */
11497  const char* formatstr, /**< message format string */
11498  ... /**< arguments to format string */
11499  )
11500 {
11501  va_list ap;
11502 
11503  assert(verblevel > SCIP_VERBLEVEL_NONE);
11504  assert(verblevel <= SCIP_VERBLEVEL_FULL);
11505  assert(set->disp_verblevel <= SCIP_VERBLEVEL_FULL);
11506 
11507  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL )
11508  {
11509  if( verblevel <= SCIP_VERBLEVEL_HIGH )
11510  {
11511  /* if already max number of messages about numerical trouble in LP on verblevel at most high, then skip message */
11513  return;
11514 
11515  /* increase count on messages with verblevel high */
11516  ++stat->nnumtroublelpmsgs ;
11517  }
11518 
11519  /* if messages wouldn't be printed, then return already */
11520  if( verblevel > set->disp_verblevel )
11521  return;
11522  }
11523 
11524  /* print common begin of message */
11525  SCIPmessagePrintInfo(messagehdlr,
11526  "(node %" SCIP_LONGINT_FORMAT ") numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- ",
11527  stat->nnodes, stat->nlps);
11528 
11529  /* print individual part of message */
11530  va_start(ap, formatstr); /*lint !e838*/
11531  SCIPmessageVFPrintInfo(messagehdlr, NULL, formatstr, ap);
11532  va_end(ap);
11533 
11534  /* warn that further messages will be suppressed */
11535  if( set->disp_verblevel < SCIP_VERBLEVEL_FULL && verblevel <= SCIP_VERBLEVEL_HIGH && stat->nnumtroublelpmsgs > MAXNUMTROUBLELPMSGS )
11536  {
11537  SCIPmessagePrintInfo(messagehdlr, " -- further messages will be suppressed (use display/verblevel=5 to see all)");
11538  }
11539 
11540  /* print closing new-line */
11541  SCIPmessagePrintInfo(messagehdlr, "\n");
11542 }
11543 
11544 static
11546  SCIP_LP* lp, /**< current LP data */
11547  SCIP_SET* set, /**< global SCIP settings */
11548  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11549  SCIP_STAT* stat, /**< problem statistics */
11550  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11551  SCIP_Bool* success /**< was instability successfully ignored */
11552  )
11553 {
11554  assert(lp != NULL);
11555  assert(set != NULL);
11556 
11557  SCIP_CALL( SCIPlpiIgnoreInstability(lp->lpi, success) );
11558 
11559  if( *success )
11560  {
11561  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "ignoring instability of %s", lpalgoName(lpalgo));
11562  if( !set->lp_checkdualfeas )
11563  lp->dualfeasible = TRUE;
11564  if( !set->lp_checkprimfeas )
11565  lp->primalchecked = TRUE;
11566  }
11567 
11568  return SCIP_OKAY;
11569 }
11570 
11571 #define FEASTOLTIGHTFAC 0.001
11572 /** solves the LP with the given LP algorithm, and tries to resolve numerical problems */
11573 static
11575  SCIP_LP* lp, /**< current LP data */
11576  SCIP_SET* set, /**< global SCIP settings */
11577  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
11578  SCIP_STAT* stat, /**< problem statistics */
11579  SCIP_PROB* prob, /**< problem data */
11580  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
11581  int itlim, /**< maximal number of LP iterations to perform in first LP calls (before solving from scratch), or -1 for no limit */
11582  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
11583  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
11584  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
11585  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
11586  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
11587  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
11588  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
11589  SCIP_Bool* timelimit, /**< pointer to store whether the time limit was hit */
11590  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
11591  )
11592 {
11593  SCIP_Bool success;
11594  SCIP_Bool success2;
11595  SCIP_Bool success3;
11596  SCIP_Bool simplex;
11597  SCIP_Bool itlimishard;
11598  SCIP_Bool usepolishing;
11599 
11600  assert(lp != NULL);
11601  assert(lp->flushed);
11602  assert(set != NULL);
11603  assert(stat != NULL);
11604  assert(lperror != NULL);
11605  assert(timelimit != NULL);
11606 
11607  *lperror = FALSE;
11608 
11609  /**@todo implement solving the LP when loose variables with infinite best bound are present; for this, we need to
11610  * solve with deactivated objective limit in order to determine whether we are (a) infeasible or (b) feasible
11611  * and hence unbounded; to handle case (b) we need to store an array of loose variables with best bound in
11612  * SCIP_LP such that we can return a primal ray
11613  */
11614  if( lp->looseobjvalinf > 0 )
11615  {
11616  SCIPerrorMessage("cannot solve LP when loose variable with infinite best bound is present\n");
11617  return SCIP_ERROR;
11618  }
11619 
11620  /* check, whether we solve with a simplex algorithm */
11621  simplex = (lpalgo == SCIP_LPALGO_PRIMALSIMPLEX || lpalgo == SCIP_LPALGO_DUALSIMPLEX);
11622 
11623  /* check whether the iteration limit is a hard one */
11624  itlimishard = (itlim == harditlim);
11625 
11626  /* check whether solution polishing should be used */
11627  if( lp->lpihaspolishing && (set->lp_solutionpolishing == 2 || (set->lp_solutionpolishing == 1 && stat->nnodes == 1 && !lp->probing)
11628  || (set->lp_solutionpolishing == 3 && ((lp->probing && !lp->strongbranchprobing) || lp->diving))) )
11629  {
11630  usepolishing = TRUE;
11631  if( lp->updateintegrality )
11632  {
11633  SCIP_CALL( lpCopyIntegrality(lp, set) );
11634  }
11635  }
11636  else
11637  usepolishing = FALSE;
11638 
11639  /* solve with given settings (usually fast but imprecise) */
11640  if( SCIPsetIsInfinity(set, lp->cutoffbound) )
11641  {
11642  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound, &success) );
11643  }
11644  else
11645  {
11646  SCIP_CALL( lpSetObjlim(lp, set, prob, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob), &success) );
11647  }
11648  SCIP_CALL( lpSetIterationLimit(lp, itlim) );
11649  SCIP_CALL( lpSetFeastol(lp, tightprimfeastol ? FEASTOLTIGHTFAC * lp->feastol : lp->feastol, &success) );
11650  SCIP_CALL( lpSetDualfeastol(lp, tightdualfeastol ? FEASTOLTIGHTFAC * SCIPsetDualfeastol(set) : SCIPsetDualfeastol(set),
11651  &success) );
11652  SCIP_CALL( lpSetBarrierconvtol(lp, (tightprimfeastol || tightdualfeastol) ? FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set)
11653  : SCIPsetBarrierconvtol(set), &success) );
11654  SCIP_CALL( lpSetFromscratch(lp, fromscratch, &success) );
11655  SCIP_CALL( lpSetFastmip(lp, fastmip, &success) );
11656  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11657  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11658  SCIP_CALL( lpSetRowrepswitch(lp, set->lp_rowrepswitch, &success) );
11659  SCIP_CALL( lpSetPricingChar(lp, set->lp_pricing) );
11660  SCIP_CALL( lpSetThreads(lp, set->lp_threads, &success) );
11661  SCIP_CALL( lpSetLPInfo(lp, set->disp_lpinfo) );
11662  SCIP_CALL( lpSetConditionLimit(lp, set->lp_conditionlimit, &success) );
11663  SCIP_CALL( lpSetMarkowitz(lp, set->lp_markowitz, &success) );
11664  SCIP_CALL( lpSetTiming(lp, set->time_clocktype, set->time_enabled, &success) );
11665  SCIP_CALL( lpSetRandomseed(lp, (int) SCIPsetInitializeRandomSeed(set, (unsigned) set->random_randomseed), &success) );
11666  SCIP_CALL( lpSetSolutionPolishing(lp, usepolishing, &success) );
11667  SCIP_CALL( lpSetRefactorInterval(lp, set->lp_refactorinterval, &success) );
11668 
11669  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, FALSE, timelimit, lperror) );
11670 
11671  /* after the first solve, do not use starting basis, since otherwise the solver will probably think the basis is
11672  * optimal without preforming scaling/change tolerances/presolving */
11673  resolve = FALSE;
11674 
11675  /* check for stability; iteration limit exceeded is also treated like instability if the iteration limit is soft */
11676  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11677  return SCIP_OKAY;
11678 
11679  if( !set->lp_checkstability )
11680  {
11681  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11682 
11683  if( success )
11684  return SCIP_OKAY;
11685  }
11686 
11687  /* In the following, whenever the LP iteration limit is exceeded in an LP solving call, we leave out the
11688  * remaining resolving calls with changed settings and go directly to solving the LP from scratch.
11689  */
11690 
11691  /* if FASTMIP is turned on, solve again without FASTMIP (starts from the solution of the last LP solving call);
11692  * do this only if the iteration limit was not exceeded in the last LP solving call
11693  */
11694  if( fastmip > 0 && simplex && ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11695  {
11696  SCIP_CALL( lpSetFastmip(lp, 0, &success) );
11697  if( success )
11698  {
11699  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s without FASTMIP", lpalgoName(lpalgo));
11700  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11701 
11702  /* check for stability */
11703  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11704  return SCIP_OKAY;
11705 
11706  if( !set->lp_checkstability )
11707  {
11708  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11709 
11710  if( success )
11711  return SCIP_OKAY;
11712  }
11713  }
11714  }
11715 
11716  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11717  * and go directly to solving the LP from scratch
11718  */
11719  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11720  {
11721  /* solve again with opposite scaling setting (starts from the solution of the last LP solving call) */
11722  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11723  if( success )
11724  {
11725  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s scaling",
11726  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11727  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11728 
11729  /* check for stability */
11730  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11731  return SCIP_OKAY;
11732 
11733  if( !set->lp_checkstability )
11734  {
11735  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11736 
11737  if( success )
11738  return SCIP_OKAY;
11739  }
11740 
11741  /* reset scaling */
11742  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11743  assert(success);
11744  }
11745  }
11746 
11747  /* if the iteration limit was exceeded in the last LP solving call, we leave out the remaining resolving calls with changed settings
11748  * and go directly to solving the LP from scratch */
11749  if( (*lperror) || !SCIPlpiIsIterlimExc(lp->lpi) )
11750  {
11751  /* solve again with opposite presolving setting (starts from the solution of the last LP solving call) */
11752  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11753  if( success )
11754  {
11755  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s %s presolving",
11756  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11757  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11758 
11759  /* check for stability */
11760  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11761  return SCIP_OKAY;
11762 
11763  if( !set->lp_checkstability )
11764  {
11765  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11766 
11767  if( success )
11768  return SCIP_OKAY;
11769  }
11770 
11771  /* reset presolving */
11772  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11773  assert(success);
11774  }
11775  }
11776 
11777  /* solve again with a tighter feasibility tolerance (starts from the solution of the last LP solving call);
11778  * do this only if the iteration limit was not exceeded in the last LP solving call
11779  */
11780  if( ((simplex && (!tightprimfeastol || !tightdualfeastol)) || (!tightprimfeastol && !tightdualfeastol)) &&
11781  ((*lperror) || !SCIPlpiIsIterlimExc(lp->lpi)) )
11782  {
11783  success = FALSE;
11784  if( !tightprimfeastol )
11785  {
11786  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11787  }
11788 
11789  success2 = FALSE;
11790  if( !tightdualfeastol )
11791  {
11792  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11793  }
11794 
11795  success3 = FALSE;
11796  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11797  {
11798  SCIP_CALL( lpSetBarrierconvtol(lp, FEASTOLTIGHTFAC * SCIPsetBarrierconvtol(set), &success3) );
11799  }
11800 
11801  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11802  if( success || success2 || success3 )
11803  {
11804  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again with %s with tighter primal and dual feasibility tolerance",
11805  lpalgoName(lpalgo));
11806  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11807 
11808  /* check for stability */
11809  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi) && (itlimishard || !SCIPlpiIsIterlimExc(lp->lpi))) )
11810  return SCIP_OKAY;
11811 
11812  if( !set->lp_checkstability )
11813  {
11814  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11815 
11816  if( success )
11817  return SCIP_OKAY;
11818  }
11819 
11820  /* reset feasibility tolerance */
11821  if( !tightprimfeastol )
11822  {
11823  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11824  }
11825  if( !tightdualfeastol )
11826  {
11827  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11828  }
11829  if( !simplex && !tightprimfeastol && !tightdualfeastol )
11830  {
11831  SCIP_CALL( lpSetBarrierconvtol(lp, SCIPsetBarrierconvtol(set), &success) );
11832  }
11833  }
11834  }
11835 
11836  /* all LPs solved after this point are solved from scratch, so set the LP iteration limit to the hard limit;
11837  * the given iteration limit might be a soft one to restrict resolving calls only */
11838  SCIP_CALL( lpSetIterationLimit(lp, harditlim) );
11839 
11840  /* if not already done, solve again from scratch */
11841  if( !fromscratch && simplex )
11842  {
11843  SCIP_CALL( lpSetFromscratch(lp, TRUE, &success) );
11844  if( success )
11845  {
11846  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11847  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11848 
11849  /* check for stability */
11850  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11851  return SCIP_OKAY;
11852 
11853  if( !set->lp_checkstability )
11854  {
11855  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11856 
11857  if( success )
11858  return SCIP_OKAY;
11859  }
11860  }
11861  }
11862 
11863  /* solve again, use other simplex this time */
11864  if( simplex )
11865  {
11867  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s", lpalgoName(lpalgo));
11868  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11869 
11870  /* check for stability */
11871  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11872  return SCIP_OKAY;
11873 
11874  if( !set->lp_checkstability )
11875  {
11876  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11877 
11878  if( success )
11879  return SCIP_OKAY;
11880  }
11881 
11882  /* solve again with opposite scaling and other simplex */
11883  SCIP_CALL( lpSetScaling(lp, (set->lp_scaling > 0) ? 0 : 1, &success) );
11884  if( success )
11885  {
11886  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s scaling",
11887  lpalgoName(lpalgo), (set->lp_scaling == 0) ? "with" : "without");
11888  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11889 
11890  /* check for stability */
11891  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11892  return SCIP_OKAY;
11893 
11894  if( !set->lp_checkstability )
11895  {
11896  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11897 
11898  if( success )
11899  return SCIP_OKAY;
11900  }
11901 
11902  /* reset scaling */
11903  SCIP_CALL( lpSetScaling(lp, set->lp_scaling, &success) );
11904  assert(success);
11905  }
11906 
11907  /* solve again with opposite presolving and other simplex */
11908  SCIP_CALL( lpSetPresolving(lp, !set->lp_presolving, &success) );
11909  if( success )
11910  {
11911  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s %s presolving",
11912  lpalgoName(lpalgo), !set->lp_presolving ? "with" : "without");
11913  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11914 
11915  /* check for stability */
11916  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11917  return SCIP_OKAY;
11918 
11919  if( !set->lp_checkstability )
11920  {
11921  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11922 
11923  if( success )
11924  return SCIP_OKAY;
11925  }
11926 
11927  /* reset presolving */
11928  SCIP_CALL( lpSetPresolving(lp, set->lp_presolving, &success) );
11929  assert(success);
11930  }
11931 
11932  /* solve again with tighter feasibility tolerance, use other simplex this time */
11933  if( !tightprimfeastol || !tightdualfeastol )
11934  {
11935  success = FALSE;
11936  if( !tightprimfeastol )
11937  {
11938  SCIP_CALL( lpSetFeastol(lp, FEASTOLTIGHTFAC * lp->feastol, &success) );
11939  }
11940 
11941  success2 = FALSE;
11942  if( !tightdualfeastol )
11943  {
11944  SCIP_CALL( lpSetDualfeastol(lp, FEASTOLTIGHTFAC * SCIPsetDualfeastol(set), &success2) );
11945  }
11946 
11947  /* only resolve if at least one of the parameters was actually changed in the LP solver */
11948  if( success || success2 )
11949  {
11950  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "solve again from scratch with %s with tighter feasibility tolerance",
11951  lpalgoName(lpalgo));
11952  SCIP_CALL( lpAlgorithm(lp, set, stat, lpalgo, resolve, keepsol, TRUE, timelimit, lperror) );
11953 
11954  /* check for stability */
11955  if( *timelimit || (!(*lperror) && SCIPlpiIsStable(lp->lpi)) )
11956  return SCIP_OKAY;
11957 
11958  if( !set->lp_checkstability )
11959  {
11960  SCIP_CALL( ignoreInstability(lp, set, messagehdlr, stat, lpalgo, &success) );
11961 
11962  if( success )
11963  return SCIP_OKAY;
11964  }
11965 
11966  /* reset feasibility tolerance */
11967  if( !tightprimfeastol )
11968  {
11969  SCIP_CALL( lpSetFeastol(lp, lp->feastol, &success) );
11970  }
11971  if( !tightdualfeastol )
11972  {
11973  SCIP_CALL( lpSetDualfeastol(lp, SCIPsetDualfeastol(set), &success) );
11974  }
11975  SCIP_UNUSED(success);
11976  }
11977  }
11978  }
11979 
11980  /* nothing worked -- exit with an LPERROR */
11981  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
11982  *lperror = TRUE;
11983 
11984  return SCIP_OKAY;
11985 }
11986 
11987 /** adjust the LP objective value if it is greater/less than +/- SCIPsetInfinity() */
11988 static
11990  SCIP_LP* lp, /**< current LP data */
11991  SCIP_SET* set, /**< global SCIP settings */
11992  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
11993  )
11994 {
11995  assert(lp != NULL);
11996  assert(set != NULL);
11997 
11998  if( SCIPsetIsInfinity(set, lp->lpobjval) && lp->lpobjval != SCIPsetInfinity(set) ) /*lint !e777*/
11999  {
12000  if( !lp->adjustlpval && messagehdlr != NULL )
12001  {
12002  SCIPmessagePrintWarning(messagehdlr, "LP solution value is above SCIP's infinity value\n");
12003  lp->adjustlpval = TRUE;
12004  }
12005  lp->lpobjval = SCIPsetInfinity(set);
12006  }
12007  else if( SCIPsetIsInfinity(set, -lp->lpobjval) && lp->lpobjval != -SCIPsetInfinity(set) ) /*lint !e777*/
12008  {
12009  if( !lp->adjustlpval && messagehdlr != NULL )
12010  {
12011  SCIPmessagePrintWarning(messagehdlr, "LP solution value is below SCIP's -infinity value\n");
12012  lp->adjustlpval = TRUE;
12013  }
12014  lp->lpobjval = -SCIPsetInfinity(set);
12015  }
12016 }
12017 
12018 /** solves the LP with the given algorithm and evaluates return status */
12019 static
12021  SCIP_LP* lp, /**< current LP data */
12022  SCIP_SET* set, /**< global SCIP settings */
12023  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12024  SCIP_STAT* stat, /**< problem statistics */
12025  SCIP_PROB* prob, /**< problem data */
12026  SCIP_LPALGO lpalgo, /**< LP algorithm that should be applied */
12027  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12028  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12029  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12030  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12031  SCIP_Bool resolve, /**< is this a resolving call (starting with feasible basis)? */
12032  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12033  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12034  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12035  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12036  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12037  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12038  )
12039 {
12040  SCIP_Bool solvedprimal;
12041  SCIP_Bool solveddual;
12042  SCIP_Bool timelimit;
12043  int itlim;
12044 
12045  assert(lp != NULL);
12046  assert(lp->flushed);
12047  assert(set != NULL);
12048  assert(stat != NULL);
12049  assert(lperror != NULL);
12050 
12051  checkLinks(lp);
12052 
12053  solvedprimal = FALSE;
12054  solveddual = FALSE;
12055  timelimit = FALSE;
12056 
12057  /* select the basic iteration limit depending on whether this is a resolving call or not */
12058  itlim = ( resolve ? resolveitlim : harditlim );
12059 
12060  SOLVEAGAIN:
12061  /* call simplex */
12062  SCIP_CALL( lpSolveStable(lp, set, messagehdlr, stat, prob, lpalgo, itlim, harditlim, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch,
12063  keepsol, &timelimit, lperror) );
12064  resolve = FALSE; /* only the first solve should be counted as resolving call */
12065  solvedprimal = solvedprimal || (lp->lastlpalgo == SCIP_LPALGO_PRIMALSIMPLEX);
12066  solveddual = solveddual || (lp->lastlpalgo == SCIP_LPALGO_DUALSIMPLEX);
12067 
12068  /* check, if an error occurred */
12069  if( *lperror )
12070  {
12071  SCIPsetDebugMsg(set, "unresolved error while solving LP with %s\n", lpalgoName(lp->lastlpalgo));
12072  lp->solved = FALSE;
12074  return SCIP_OKAY;
12075  }
12076 
12077  /* check, if a time limit was exceeded */
12078  if( timelimit )
12079  {
12080  SCIPsetDebugMsg(set, "time limit exceeded before solving LP\n");
12081  lp->solved = TRUE;
12083  lp->lpobjval = -SCIPsetInfinity(set);
12084  return SCIP_OKAY;
12085  }
12086 
12087  /* only one should return true */
12088  assert(!(SCIPlpiIsOptimal(lp->lpi) && SCIPlpiIsObjlimExc(lp->lpi) && SCIPlpiIsPrimalInfeasible(lp->lpi) &&
12090 
12091  /* evaluate solution status */
12092  if( SCIPlpiIsOptimal(lp->lpi) )
12093  {
12094  assert(lp->primalfeasible);
12095  assert(lp->dualfeasible);
12097  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12098  adjustLPobjval(lp, set, messagehdlr);
12099 
12100  if( !SCIPsetIsInfinity(set, lp->lpiobjlim) && SCIPsetIsGE(set, lp->lpobjval, lp->lpiobjlim) )
12101  {
12102  /* the solver may return the optimal value, even if this is greater or equal than the upper bound */
12103  SCIPsetDebugMsg(set, "optimal solution %.15g exceeds objective limit %.15g\n", lp->lpobjval, lp->lpiobjlim);
12105  lp->lpobjval = SCIPsetInfinity(set);
12106  }
12107  /* if we did not disable the cutoff bound in the LP solver, the LP solution status should be objective limit
12108  * reached if the LP objective value is greater than the cutoff bound
12109  */
12110  assert(lpCutoffDisabled(set, prob) || lp->lpsolstat == SCIP_LPSOLSTAT_OBJLIMIT || SCIPsetIsInfinity(set, lp->cutoffbound)
12111  || SCIPsetIsLE(set, lp->lpobjval + getFiniteLooseObjval(lp, set, prob), lp->cutoffbound));
12112  }
12113  else if( SCIPlpiIsObjlimExc(lp->lpi) )
12114  {
12115  assert(!lpCutoffDisabled(set, prob));
12116 
12117 #ifndef NDEBUG
12118  /* the LP solution objective should exceed the limit in this case */
12119  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12120  assert(SCIPsetIsRelGE(set, lp->lpobjval, lp->lpiobjlim));
12121 #endif
12122 
12124  lp->lpobjval = SCIPsetInfinity(set);
12125  }
12126  else if( SCIPlpiIsPrimalInfeasible(lp->lpi) )
12127  {
12128  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12129  if( needdualray && !SCIPlpiHasDualRay(lp->lpi) && !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX )
12130  {
12131  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12132  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12133  goto SOLVEAGAIN;
12134  }
12136  lp->lpobjval = SCIPsetInfinity(set);
12137  }
12138  else if( SCIPlpiExistsPrimalRay(lp->lpi) )
12139  {
12140  /* because of numerical instability lpalgo != lp->lastlpalgo might happen - hence, we have to check both */
12141  if( needprimalray && !SCIPlpiIsPrimalUnbounded(lp->lpi) && !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX )
12142  {
12143  /* unboundedness includes that the primal is feasible: ensure a primal solution here */
12144  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12145  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12146  goto SOLVEAGAIN;
12147  }
12149  lp->lpobjval = -SCIPsetInfinity(set);
12150  }
12151  else if( SCIPlpiIsIterlimExc(lp->lpi) )
12152  {
12153  SCIP_CALL( SCIPlpiGetObjval(lp->lpi, &lp->lpobjval) );
12154 
12155  /* The lpobjval might be infinite, e.g. if the LP solver was not able to produce a valid bound while reaching the
12156  iteration limit. In this case, we avoid the warning in adjustLPobjval() by setting the messagehdlr to NULL. */
12157  if ( REALABS(lp->lpobjval) == SCIPlpiInfinity(lp->lpi) ) /*lint !e777*/
12158  adjustLPobjval(lp, set, NULL);
12159  else
12160  adjustLPobjval(lp, set, messagehdlr);
12161 
12163  }
12164  else if( SCIPlpiIsTimelimExc(lp->lpi) )
12165  {
12166  lp->lpobjval = -SCIPsetInfinity(set);
12168  }
12169  else if( !solveddual && lpalgo != SCIP_LPALGO_DUALSIMPLEX)
12170  {
12171  assert(lp->lastlpalgo != SCIP_LPALGO_DUALSIMPLEX);
12172  lpalgo = SCIP_LPALGO_DUALSIMPLEX;
12173  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12174  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12175  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12176  goto SOLVEAGAIN;
12177  }
12178  else if( !solvedprimal && lpalgo != SCIP_LPALGO_PRIMALSIMPLEX)
12179  {
12180  assert(lp->lastlpalgo != SCIP_LPALGO_PRIMALSIMPLEX);
12181  lpalgo = SCIP_LPALGO_PRIMALSIMPLEX;
12182  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12183  "(node %" SCIP_LONGINT_FORMAT ") solution status of LP %" SCIP_LONGINT_FORMAT " could not be proven (internal status:%d) -- solve again with %s\n",
12184  stat->nnodes, stat->nlps, SCIPlpiGetInternalStatus(lp->lpi), lpalgoName(lpalgo));
12185  goto SOLVEAGAIN;
12186  }
12187  else
12188  {
12189  SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") error or unknown return status of %s in LP %" SCIP_LONGINT_FORMAT " (internal status: %d)\n",
12190  stat->nnodes, lpalgoName(lp->lastlpalgo), stat->nlps, SCIPlpiGetInternalStatus(lp->lpi));
12192  return SCIP_LPERROR;
12193  }
12194 
12195  lp->solved = TRUE;
12196 
12197  SCIPsetDebugMsg(set, "solving LP with %s returned solstat=%d (internal status: %d, primalfeasible=%u, dualfeasible=%u)\n",
12200 
12201  return SCIP_OKAY;
12202 }
12203 
12204 /** flushes the LP and solves it with the primal or dual simplex algorithm, depending on the current basis feasibility */
12205 static
12207  SCIP_LP* lp, /**< current LP data */
12208  BMS_BLKMEM* blkmem, /**< block memory */
12209  SCIP_SET* set, /**< global SCIP settings */
12210  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12211  SCIP_STAT* stat, /**< problem statistics */
12212  SCIP_PROB* prob, /**< problem data */
12213  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12214  int resolveitlim, /**< maximal number of LP iterations to perform in resolving calls, or -1 for no limit */
12215  int harditlim, /**< maximal number of LP iterations to perform (hard limit for all LP calls), or -1 for no limit */
12216  SCIP_Bool needprimalray, /**< if the LP is unbounded, do we need a primal ray? */
12217  SCIP_Bool needdualray, /**< if the LP is infeasible, do we need a dual ray? */
12218  int fastmip, /**< which FASTMIP setting of LP solver should be used? */
12219  SCIP_Bool tightprimfeastol, /**< should a tighter primal feasibility tolerance be used? */
12220  SCIP_Bool tightdualfeastol, /**< should a tighter dual feasibility tolerance be used? */
12221  SCIP_Bool fromscratch, /**< should the LP be solved from scratch without using current basis? */
12222  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12223  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12224  )
12225 {
12226  SCIP_Bool resolve;
12227  char algo;
12228 
12229  assert(lp != NULL);
12230  assert(set != NULL);
12231  assert(lperror != NULL);
12232 
12233  /* flush changes to the LP solver */
12234  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12235  fastmip = ((!lp->flushaddedcols && !lp->flushdeletedcols) ? fastmip : 0); /* turn off FASTMIP if columns were changed */
12236 
12237  /* select LP algorithm to apply */
12238  resolve = lp->solisbasic && (lp->dualfeasible || lp->primalfeasible) && !fromscratch;
12239  algo = resolve ? set->lp_resolvealgorithm : set->lp_initalgorithm;
12240 
12241  switch( algo )
12242  {
12243  case 's':
12244  /* select simplex method */
12245  if( lp->dualfeasible || !lp->primalfeasible )
12246  {
12247  SCIPsetDebugMsg(set, "solving dual LP\n");
12248  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12249  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12250  }
12251  else
12252  {
12253  SCIPsetDebugMsg(set, "solving primal LP\n");
12254  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12255  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12256  }
12257  break;
12258 
12259  case 'p':
12260  SCIPsetDebugMsg(set, "solving primal LP\n");
12261  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_PRIMALSIMPLEX, resolveitlim, harditlim, needprimalray,
12262  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12263  break;
12264 
12265  case 'd':
12266  SCIPsetDebugMsg(set, "solving dual LP\n");
12267  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, resolveitlim, harditlim, needprimalray,
12268  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12269  break;
12270 
12271  case 'b':
12272  SCIPsetDebugMsg(set, "solving barrier LP\n");
12273  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIER, resolveitlim, harditlim, needprimalray,
12274  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12275  break;
12276 
12277  case 'c':
12278  SCIPsetDebugMsg(set, "solving barrier LP with crossover\n");
12279  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_BARRIERCROSSOVER, resolveitlim, harditlim, needprimalray,
12280  needdualray, resolve, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12281  break;
12282 
12283  default:
12284  SCIPerrorMessage("invalid parameter setting <%c> for LP algorithm\n", algo);
12285  return SCIP_PARAMETERWRONGVAL;
12286  }
12287  assert(!(*lperror) || !lp->solved);
12288 
12289  return SCIP_OKAY;
12290 }
12291 
12292 #ifndef NDEBUG
12293 /** checks if the lazy bounds are valid */
12294 static
12296  SCIP_LP* lp, /**< LP data */
12297  SCIP_SET* set /**< global SCIP settings */
12298  )
12299 {
12300  SCIP_COL* col;
12301  int c;
12302 
12303  assert(lp->flushed);
12304 
12305  for( c = 0; c < lp->nlazycols; ++c )
12306  {
12307  col = lp->lazycols[c];
12308 
12309  /* in case lazy bounds are given, check that the primal solution satisfies them */
12310  assert(SCIPsetIsInfinity(set, -col->lazylb) || SCIPsetIsFeasGE(set, col->primsol, col->lazylb));
12311  assert(SCIPsetIsInfinity(set, col->lazyub) || SCIPsetIsFeasLE(set, col->primsol, col->lazyub));
12312  }
12313 }
12314 #else
12315 #define checkLazyBounds(lp, set) /**/
12316 #endif
12317 
12318 /** marks all lazy columns to be changed; this is needed for reloading/removing bounds of these columns before and after
12319  * diving
12320  */
12321 static
12323  SCIP_LP* lp, /**< LP data */
12324  SCIP_SET* set /**< global SCIP settings */
12325  )
12326 {
12327  SCIP_COL* col;
12328  int c;
12329 
12330  assert(lp->nlazycols > 0);
12331 
12332  /* return, if we are in diving, and bounds were already applied
12333  * or if we are not in diving and bounds were not applied
12334  */
12335  if( lp->diving == lp->divinglazyapplied )
12336  return SCIP_OKAY;
12337 
12338  SCIPsetDebugMsg(set, "mark all lazy columns as changed in order to reload bounds (diving=%u, applied=%u)\n",
12339  lp->diving, lp->divinglazyapplied);
12340 
12341  for( c = 0; c < lp->nlazycols; ++c )
12342  {
12343  col = lp->lazycols[c];
12344 
12345  /* if the column has a lazy lower bound, mark its lower bounds as changed */
12346  if( !SCIPsetIsInfinity(set, -col->lazylb) )
12347  {
12348  assert((!(lp->divinglazyapplied)) || (col->flushedlb == col->lb) || col->lbchanged); /*lint !e777*/
12349  assert(lp->divinglazyapplied || SCIPsetIsGT(set, col->lb, col->lazylb)
12350  || (col->flushedlb == -SCIPlpiInfinity(lp->lpi)) || col->lbchanged); /*lint !e777*/
12351 
12352  /* insert column in the chgcols list (if not already there) */
12353  SCIP_CALL( insertColChgcols(col, set, lp) );
12354 
12355  /* mark bound change in the column */
12356  col->lbchanged = TRUE;
12357  }
12358 
12359  /* if the column has a lazy upper bound, mark its upper bounds as changed */
12360  if( !SCIPsetIsInfinity(set, col->lazyub) )
12361  {
12362  assert((!(lp->divinglazyapplied)) || (col->flushedub == col->ub) || col->ubchanged); /*lint !e777*/
12363  assert(lp->divinglazyapplied || SCIPsetIsLT(set, col->ub, col->lazyub)
12364  || (col->flushedub == SCIPlpiInfinity(lp->lpi)) || col->ubchanged); /*lint !e777*/
12365 
12366  /* insert column in the chgcols list (if not already there) */
12367  SCIP_CALL( insertColChgcols(col, set, lp) );
12368 
12369  /* mark bound change in the column */
12370  col->ubchanged = TRUE;
12371  }
12372  }
12373 
12374  /* update lp->divinglazyapplied flag: if we are in diving mode, we just applied the lazy bounds,
12375  * if not, we just removed them
12376  */
12377  lp->divinglazyapplied = lp->diving;
12378 
12379  return SCIP_OKAY;
12380 }
12381 
12382 /** returns the iteration limit for an LP resolving call */
12383 static
12385  SCIP_SET* set, /**< global SCIP settings */
12386  SCIP_STAT* stat, /**< dynamic problem statistics */
12387  int itlim /**< hard iteration limit */
12388  )
12389 {
12390  /* no limit set or average not yet reliable */
12391  if( (set->lp_resolveiterfac == -1) || stat->nlps - stat->nrootlps < 5 )
12392  return itlim;
12393  /* set itlim to INT_MAX if it is -1 to reduce the number of cases to be regarded in the following */
12394  if( itlim == -1 )
12395  itlim = INT_MAX;
12396  /* return resolveiterfac * average iteration number per call after root, but at least resolveitermin and at most the hard iteration limit */
12397  return (int) MIN(itlim, MAX(set->lp_resolveitermin, \
12398  (set->lp_resolveiterfac * (stat->nlpiterations - stat->nrootlpiterations) / (SCIP_Real)(stat->nlps - stat->nrootlps))));
12399 }
12400 
12401 
12402 
12403 /** solves the LP with simplex algorithm, and copy the solution into the column's data */
12405  SCIP_LP* lp, /**< LP data */
12406  SCIP_SET* set, /**< global SCIP settings */
12407  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
12408  BMS_BLKMEM* blkmem, /**< block memory buffers */
12409  SCIP_STAT* stat, /**< problem statistics */
12410  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
12411  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
12412  SCIP_PROB* prob, /**< problem data */
12413  SCIP_Longint itlim, /**< maximal number of LP iterations to perform, or -1 for no limit */
12414  SCIP_Bool limitresolveiters, /**< should LP iterations for resolving calls be limited?
12415  * (limit is computed within the method w.r.t. the average LP iterations) */
12416  SCIP_Bool aging, /**< should aging and removal of obsolete cols/rows be applied? */
12417  SCIP_Bool keepsol, /**< should the old LP solution be kept if no iterations were performed? */
12418  SCIP_Bool* lperror /**< pointer to store whether an unresolved LP error occurred */
12419  )
12420 {
12421  SCIP_RETCODE retcode;
12422  SCIP_Bool needprimalray;
12423  SCIP_Bool needdualray;
12424  int harditlim;
12425  int resolveitlim;
12426 
12427  assert(lp != NULL);
12428  assert(prob != NULL);
12429  assert(prob->nvars >= lp->ncols);
12430  assert(lperror != NULL);
12431 
12432  retcode = SCIP_OKAY;
12433  *lperror = FALSE;
12434 
12435  if( lp->flushed && lp->solved )
12436  {
12437  SCIPsetDebugMsg(set, "skipping LP solve: already flushed and solved)\n");
12438  return SCIP_OKAY;
12439  }
12440 
12441  SCIPsetDebugMsg(set, "solving LP: %d rows, %d cols, primalfeasible=%u, dualfeasible=%u, solved=%u, diving=%u, probing=%u, cutoffbnd=%g\n",
12442  lp->nrows, lp->ncols, lp->primalfeasible, lp->dualfeasible, lp->solved, lp->diving, lp->probing, lp->cutoffbound);
12443 
12444  /* check whether we need a proof of unboundedness or infeasibility by a primal or dual ray */
12445  needprimalray = TRUE;
12446  needdualray = (!SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve
12447  || (set->conf_enable && set->conf_useinflp != 'o'));
12448 
12449  /* compute the limit for the number of LP resolving iterations, if needed (i.e. if limitresolveiters == TRUE) */
12450  harditlim = (int) MIN(itlim, INT_MAX);
12451  resolveitlim = ( limitresolveiters ? lpGetResolveItlim(set, stat, harditlim) : harditlim );
12452  assert(harditlim == -1 || (resolveitlim <= harditlim));
12453 
12454  /* if there are lazy bounds, check whether the bounds should explicitly be put into the LP (diving was started)
12455  * or removed from the LP (diving was ended)
12456  */
12457  if( lp->nlazycols > 0 )
12458  {
12459  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
12460  * first resolve LP?
12461  */
12462  SCIP_CALL( updateLazyBounds(lp, set) );
12463  assert(lp->diving == lp->divinglazyapplied);
12464  }
12465 
12466  /* flush changes to the LP solver */
12467  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
12468  assert(lp->flushed);
12469 
12470  /* 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
12471  * to run again anyway, since there seems to be some time left / the time limit was increased
12472  */
12473  if( !lp->solved || (lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT && stat->status != SCIP_STATUS_TIMELIMIT) )
12474  {
12475  SCIP_Bool* primalfeaspointer;
12476  SCIP_Bool* dualfeaspointer;
12477  SCIP_Bool primalfeasible;
12478  SCIP_Bool dualfeasible;
12479  SCIP_Bool farkasvalid;
12480  SCIP_Bool rayfeasible;
12481  SCIP_Bool tightprimfeastol;
12482  SCIP_Bool tightdualfeastol;
12483  SCIP_Bool fromscratch;
12484  SCIP_Bool wasfromscratch;
12485  SCIP_Longint oldnlps;
12486  int fastmip;
12487 
12488  /* set initial LP solver settings */
12489  fastmip = ((lp->lpihasfastmip && !lp->flushaddedcols && !lp->flushdeletedcols && stat->nnodes > 1) ? set->lp_fastmip : 0);
12490  tightprimfeastol = FALSE;
12491  tightdualfeastol = FALSE;
12492  fromscratch = FALSE;
12493  primalfeasible = FALSE;
12494  dualfeasible = FALSE;
12495  wasfromscratch = (stat->nlps == 0);
12496 
12497  SOLVEAGAIN:
12498  /* solve the LP */
12499  oldnlps = stat->nlps;
12500  SCIP_CALL( lpFlushAndSolve(lp, blkmem, set, messagehdlr, stat, prob, eventqueue, resolveitlim, harditlim, needprimalray,
12501  needdualray, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12502  SCIPsetDebugMsg(set, "lpFlushAndSolve() returned solstat %d (error=%u)\n", SCIPlpGetSolstat(lp), *lperror);
12503  assert(!(*lperror) || !lp->solved);
12504 
12505  /* check for error */
12506  if( *lperror )
12507  {
12508  retcode = SCIP_OKAY;
12509  goto TERMINATE;
12510  }
12511 
12512  /* evaluate solution status */
12513  switch( SCIPlpGetSolstat(lp) )
12514  {
12516  /* get LP solution and possibly check the solution's feasibility again */
12517  if( set->lp_checkprimfeas )
12518  {
12519  primalfeaspointer = &primalfeasible;
12520  lp->primalchecked = TRUE;
12521  }
12522  else
12523  {
12524  /* believe in the primal feasibility of the LP solution */
12525  primalfeasible = TRUE;
12526  primalfeaspointer = NULL;
12527  lp->primalchecked = FALSE;
12528  }
12529  if( set->lp_checkdualfeas )
12530  {
12531  dualfeaspointer = &dualfeasible;
12532  lp->dualchecked = TRUE;
12533  }
12534  else
12535  {
12536  /* believe in the dual feasibility of the LP solution */
12537  dualfeasible = TRUE;
12538  dualfeaspointer = NULL;
12539  lp->dualchecked = FALSE;
12540  }
12541 
12542  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12543 
12544  /* in debug mode, check that lazy bounds (if present) are not violated */
12545  checkLazyBounds(lp, set);
12546 
12547  if( primalfeasible && dualfeasible && aging && !lp->diving && stat->nlps > oldnlps )
12548  {
12549  /* update ages and remove obsolete columns and rows from LP */
12550  SCIP_CALL( SCIPlpUpdateAges(lp, stat) );
12551  if( stat->nlps % ((set->lp_rowagelimit+1)/2 + 1) == 0 ) /*lint !e776*/
12552  {
12553  SCIP_CALL( SCIPlpRemoveNewObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
12554  }
12555 
12556  if( !lp->solved )
12557  {
12558  /* resolve LP after removing obsolete columns and rows */
12559  SCIPsetDebugMsg(set, "removed obsoletes - resolve LP again: %d rows, %d cols\n", lp->nrows, lp->ncols);
12560  aging = FALSE; /* to prevent infinite loops */
12561  goto SOLVEAGAIN;
12562  }
12563  }
12564  if( !primalfeasible || !dualfeasible )
12565  {
12567 
12568  if( (fastmip > 0) && simplex )
12569  {
12570  /* solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12571  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12572  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again without FASTMIP\n",
12573  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12574  fastmip = 0;
12575  goto SOLVEAGAIN;
12576  }
12577  else if( (!primalfeasible && !tightprimfeastol) || (!dualfeasible && !tightdualfeastol) )
12578  {
12579  /* solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12580  * tolerance
12581  */
12582  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12583  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again with tighter feasibility tolerance\n",
12584  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12585  tightprimfeastol = tightprimfeastol || !primalfeasible;
12586  tightdualfeastol = tightdualfeastol || !dualfeasible;
12587  goto SOLVEAGAIN;
12588  }
12589  else if( !fromscratch && !wasfromscratch && simplex )
12590  {
12591  /* solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12592  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12593  "(node %" SCIP_LONGINT_FORMAT ") solution of LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, dfeas=%u) -- solving again from scratch\n",
12594  stat->nnodes, stat->nlps, primalfeasible, dualfeasible);
12595  fromscratch = TRUE;
12596  goto SOLVEAGAIN;
12597  }
12598  else
12599  {
12600  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved");
12601  lp->solved = FALSE;
12603  *lperror = TRUE;
12604  }
12605  }
12606  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12607  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12608  lp->lpsolstat, lp->cutoffbound);
12609  break;
12610 
12612  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12613  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve || set->lp_alwaysgetduals )
12614  {
12615  if( SCIPlpiHasDualRay(lp->lpi) )
12616  {
12617  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12618  }
12619  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12620  * with the primal simplex due to numerical problems) - treat this case like an LP error
12621  */
12622  else
12623  {
12624  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12625  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12626  lp->solved = FALSE;
12628  farkasvalid = FALSE;
12629  *lperror = TRUE;
12630  }
12631  }
12632  else
12633  farkasvalid = TRUE;
12634 
12635  /* if the LP solver does not provide a Farkas proof we don't want to resolve the LP */
12636  if( !farkasvalid && !(*lperror) )
12637  {
12639 
12640  if( (fastmip > 0) && simplex )
12641  {
12642  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12643  * without FASTMIP
12644  */
12645  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12646  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again without FASTMIP\n",
12647  stat->nnodes, stat->nlps);
12648  fastmip = 0;
12649  goto SOLVEAGAIN;
12650  }
12651  else if( !tightdualfeastol )
12652  {
12653  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12654  * solve again with tighter feasibility tolerance
12655  */
12656  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12657  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter dual feasibility tolerance\n",
12658  stat->nnodes, stat->nlps);
12659  tightdualfeastol = TRUE;
12660  goto SOLVEAGAIN;
12661  }
12662  else if( !fromscratch && simplex )
12663  {
12664  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12665  * from scratch
12666  */
12667  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12668  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12669  stat->nnodes, stat->nlps);
12670  fromscratch = TRUE;
12671  goto SOLVEAGAIN;
12672  }
12673  else
12674  {
12675  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12676  * helped forget about the LP at this node and mark it to be unsolved
12677  */
12678  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12679  lp->solved = FALSE;
12681  *lperror = TRUE;
12682  }
12683  }
12684 
12685  break;
12686 
12688  if( set->lp_checkprimfeas )
12689  {
12690  /* get unbounded LP solution and check the solution's feasibility again */
12691  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12692 
12693  lp->primalchecked = TRUE;
12694  }
12695  else
12696  {
12697  /* get unbounded LP solution believing in the feasibility of the LP solution */
12698  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12699 
12700  primalfeasible = TRUE;
12701  rayfeasible = TRUE;
12702  lp->primalchecked = FALSE;
12703  }
12704 
12705  /* in debug mode, check that lazy bounds (if present) are not violated */
12706  checkLazyBounds(lp, set);
12707 
12708  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray (primalfeas=%u, rayfeas=%u)\n",
12709  primalfeasible, rayfeasible);
12710 
12711  if( !primalfeasible || !rayfeasible )
12712  {
12714 
12715  if( (fastmip > 0) && simplex )
12716  {
12717  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again without FASTMIP */
12718  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12719  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again without FASTMIP\n",
12720  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12721  fastmip = 0;
12722  goto SOLVEAGAIN;
12723  }
12724  else if( !tightprimfeastol )
12725  {
12726  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again with tighter feasibility
12727  * tolerance
12728  */
12729  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12730  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again with tighter primal feasibility tolerance\n",
12731  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12732  tightprimfeastol = TRUE;
12733  goto SOLVEAGAIN;
12734  }
12735  else if( !fromscratch && simplex )
12736  {
12737  /* unbounded solution is infeasible (this can happen due to numerical problems): solve again from scratch */
12738  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12739  "(node %" SCIP_LONGINT_FORMAT ") solution of unbounded LP %" SCIP_LONGINT_FORMAT " not optimal (pfeas=%u, rfeas=%u) -- solving again from scratch\n",
12740  stat->nnodes, stat->nlps, primalfeasible, rayfeasible);
12741  fromscratch = TRUE;
12742  goto SOLVEAGAIN;
12743  }
12744  else
12745  {
12746  /* unbounded solution is infeasible (this can happen due to numerical problems) and nothing helped:
12747  * forget about the LP at this node and mark it to be unsolved
12748  */
12749  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP unbounded");
12750  lp->solved = FALSE;
12752  *lperror = TRUE;
12753  }
12754  }
12755 
12756  break;
12757 
12759  assert(!lpCutoffDisabled(set, prob));
12760  /* Some LP solvers, e.g. CPLEX With FASTMIP setting, do not apply the final pivot to reach the dual solution
12761  * exceeding the objective limit. In some cases like branch-and-price, however, we must make sure that a dual
12762  * feasible solution exists that exceeds the objective limit. Therefore, we have to continue solving it without
12763  * objective limit for at least one iteration. We first try to continue with FASTMIP for one additional simplex
12764  * iteration using the steepest edge pricing rule. If this does not fix the problem, we temporarily disable
12765  * FASTMIP and solve again. */
12766  if( !SCIPprobAllColsInLP(prob, set, lp) || set->misc_exactsolve )
12767  {
12768  SCIP_LPI* lpi;
12769  SCIP_Real objval;
12770 
12771  lpi = SCIPlpGetLPI(lp);
12772 
12773  assert(lpi != NULL);
12774  /* actually, SCIPsetIsGE(set, lp->lpobjval, lp->lpiuobjlim) should hold, but we are a bit less strict in
12775  * the assert by using !SCIPsetIsFeasNegative()
12776  */
12777  assert(SCIPlpiIsObjlimExc(lpi) || !SCIPsetIsFeasNegative(set, lp->lpobjval - lp->lpiobjlim));
12778 
12779  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12780 
12781  /* do one additional simplex step if the computed dual solution doesn't exceed the objective limit */
12782  if( SCIPsetIsLT(set, objval, lp->lpiobjlim) )
12783  {
12784  SCIP_Real tmpcutoff;
12785  char tmppricingchar;
12786  SCIP_LPSOLSTAT solstat;
12787 
12788  SCIPsetDebugMsg(set, "objval = %f < %f = lp->lpiobjlim, but status objlimit\n", objval, lp->lpiobjlim);
12789 
12790  /* we want to resolve from the current basis (also if the LP had to be solved from scratch) */
12791  fromscratch = FALSE;
12792 
12793  /* temporarily disable cutoffbound, which also disables the objective limit */
12794  tmpcutoff = lp->cutoffbound;
12795  lp->cutoffbound = SCIPlpiInfinity(lpi);
12796 
12797  /* set lp pricing strategy to steepest edge */
12798  SCIP_CALL( SCIPsetGetCharParam(set, "lp/pricing", &tmppricingchar) );
12799  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", 's') );
12800 
12801  /* resolve LP with an iteration limit of 1 */
12802  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, 1, 1,
12803  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12804 
12805  /* reinstall old cutoff bound and lp pricing strategy */
12806  lp->cutoffbound = tmpcutoff;
12807  SCIP_CALL( SCIPsetSetCharParam(set, messagehdlr, "lp/pricing", tmppricingchar) );
12808 
12809  /* get objective value */
12810  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12811 
12812  /* get solution status for the lp */
12813  solstat = SCIPlpGetSolstat(lp);
12814  assert(solstat != SCIP_LPSOLSTAT_OBJLIMIT);
12815 
12816  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, 1 add. step)\n", objval, solstat);
12817 
12818  /* the solution is still not exceeding the objective limit and the solving process
12819  * was stopped due to time or iteration limit, solve again with fastmip turned off
12820  */
12821  if( solstat == SCIP_LPSOLSTAT_ITERLIMIT &&
12822  SCIPsetIsLT(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12823  {
12825  if( !(lperror) && (fastmip > 0) && simplex )
12826  {
12827  fastmip = 0;
12828  SCIP_CALL( lpSolve(lp, set, messagehdlr, stat, prob, SCIP_LPALGO_DUALSIMPLEX, -1, -1,
12829  FALSE, FALSE, TRUE, fastmip, tightprimfeastol, tightdualfeastol, fromscratch, keepsol, lperror) );
12830 
12831  /* get objective value */
12832  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
12833 
12834  /* get solution status for the lp */
12835  solstat = SCIPlpGetSolstat(lp);
12836 
12837  SCIPsetDebugMsg(set, " ---> new objval = %f (solstat: %d, without fastmip)\n", objval, solstat);
12838  }
12839  }/*lint !e438*/
12840 
12841  /* check for lp errors */
12842  if( *lperror || solstat == SCIP_LPSOLSTAT_ERROR || solstat == SCIP_LPSOLSTAT_NOTSOLVED )
12843  {
12844  SCIPsetDebugMsg(set, "unresolved error while resolving LP in order to exceed the objlimit\n");
12845  lp->solved = FALSE;
12847 
12848  retcode = *lperror ? SCIP_OKAY : SCIP_LPERROR;
12849  goto TERMINATE;
12850  }
12851 
12852  lp->solved = TRUE;
12853 
12854  /* optimal solution / objlimit / itlimit or timelimit, but objlimit exceeded */
12855  if( solstat == SCIP_LPSOLSTAT_OPTIMAL || solstat == SCIP_LPSOLSTAT_OBJLIMIT
12856  || ( (solstat == SCIP_LPSOLSTAT_ITERLIMIT || solstat == SCIP_LPSOLSTAT_TIMELIMIT)
12857  && SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) ) )
12858  {
12859  /* get LP solution and possibly check the solution's feasibility again */
12860  if( set->lp_checkprimfeas )
12861  {
12862  primalfeaspointer = &primalfeasible;
12863  lp->primalchecked = TRUE;
12864  }
12865  else
12866  {
12867  /* believe in the primal feasibility of the LP solution */
12868  primalfeasible = TRUE;
12869  primalfeaspointer = NULL;
12870  lp->primalchecked = FALSE;
12871  }
12872  if( set->lp_checkdualfeas )
12873  {
12874  dualfeaspointer = &dualfeasible;
12875  lp->dualchecked = TRUE;
12876  }
12877  else
12878  {
12879  /* believe in the dual feasibility of the LP solution */
12880  dualfeasible = TRUE;
12881  dualfeaspointer = NULL;
12882  lp->dualchecked = FALSE;
12883  }
12884 
12885  SCIP_CALL( SCIPlpGetSol(lp, set, stat, primalfeaspointer, dualfeaspointer) );
12886 
12887  /* in debug mode, check that lazy bounds (if present) are not violated by an optimal LP solution */
12888  if( solstat == SCIP_LPSOLSTAT_OPTIMAL )
12889  {
12890  checkLazyBounds(lp, set);
12891  }
12892 
12893  /* if objective value is larger than the cutoff bound, set solution status to objective
12894  * limit reached and objective value to infinity, in case solstat = SCIP_LPSOLSTAT_OBJLIMIT,
12895  * this was already done in the lpSolve() method
12896  */
12897  if( SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob)) )
12898  {
12900  lp->lpobjval = SCIPsetInfinity(set);
12901  }
12902 
12903  /* LP solution is not feasible or objective limit was reached without the LP value really exceeding
12904  * the cutoffbound; mark the LP to be unsolved
12905  */
12906  if( !primalfeasible || !dualfeasible
12907  || (solstat == SCIP_LPSOLSTAT_OBJLIMIT &&
12908  !SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))) )
12909  {
12910  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_HIGH, "unresolved");
12911  lp->solved = FALSE;
12913  *lperror = TRUE;
12914  }
12915 
12916  SCIPsetDebugMsg(set, " -> LP objective value: %g + %g = %g (solstat=%d, cutoff=%g)\n",
12917  lp->lpobjval, getFiniteLooseObjval(lp, set, prob), lp->lpobjval + getFiniteLooseObjval(lp, set, prob),
12918  lp->lpsolstat, lp->cutoffbound);
12919  }
12920  /* infeasible solution */
12921  else if( solstat == SCIP_LPSOLSTAT_INFEASIBLE )
12922  {
12923  SCIPsetDebugMsg(set, " -> LP infeasible\n");
12924 
12925  if( !SCIPprobAllColsInLP(prob, set, lp) || set->lp_checkfarkas || set->misc_exactsolve )
12926  {
12927  if( SCIPlpiHasDualRay(lp->lpi) )
12928  {
12929  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, &farkasvalid) );
12930  }
12931  /* it might happen that we have no infeasibility proof for the current LP (e.g. if the LP was always solved
12932  * with the primal simplex due to numerical problems) - treat this case like an LP error
12933  */
12934  else
12935  {
12936  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12937  "(node %" SCIP_LONGINT_FORMAT ") infeasibility of LP %" SCIP_LONGINT_FORMAT " could not be proven by dual ray\n", stat->nnodes, stat->nlps);
12938  lp->solved = FALSE;
12940  farkasvalid = FALSE;
12941  *lperror = TRUE;
12942  }
12943  }
12944  else
12945  farkasvalid = TRUE;
12946 
12947  if( !farkasvalid )
12948  {
12950 
12951  if( !tightprimfeastol )
12952  {
12953  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems):
12954  * solve again with tighter feasibility tolerance
12955  */
12956  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12957  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again with tighter primal feasibility tolerance\n",
12958  stat->nnodes, stat->nlps);
12959  tightprimfeastol = TRUE;
12960  goto SOLVEAGAIN;
12961  }
12962  else if( simplex )
12963  {
12964  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems): solve again
12965  * from scratch
12966  */
12967  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
12968  "(node %" SCIP_LONGINT_FORMAT ") proof of infeasible LP %" SCIP_LONGINT_FORMAT " not valid -- solving again from scratch\n",
12969  stat->nnodes, stat->nlps);
12970  fromscratch = TRUE;
12971  goto SOLVEAGAIN;
12972  }
12973  else
12974  {
12975  /* the Farkas proof does not prove infeasibility (this can happen due to numerical problems) and nothing
12976  * helped forget about the LP at this node and mark it to be unsolved
12977  */
12978  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, LP infeasible");
12979  lp->solved = FALSE;
12981  *lperror = TRUE;
12982  }
12983  }
12984  }
12985  /* unbounded solution */
12986  else if( solstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY )
12987  {
12988  if( set->lp_checkprimfeas )
12989  {
12990  /* get unbounded LP solution and check the solution's feasibility again */
12991  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, &primalfeasible, &rayfeasible) );
12992 
12993  lp->primalchecked = TRUE;
12994  }
12995  else
12996  {
12997  /* get unbounded LP solution believing in its feasibility */
12998  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
12999 
13000  primalfeasible = TRUE;
13001  rayfeasible = TRUE;
13002  lp->primalchecked = FALSE;
13003  }
13004 
13005  SCIPsetDebugMsg(set, " -> LP has unbounded primal ray\n");
13006 
13007  /* in debug mode, check that lazy bounds (if present) are not violated */
13008  checkLazyBounds(lp, set);
13009 
13010  if( !primalfeasible || !rayfeasible )
13011  {
13012  /* unbounded solution is infeasible (this can happen due to numerical problems):
13013  * forget about the LP at this node and mark it to be unsolved
13014  *
13015  * @todo: like in the default LP solving evaluation, solve without fastmip,
13016  * with tighter feasibility tolerance and from scratch
13017  */
13018  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved, unbounded LP");
13019  lp->solved = FALSE;
13021  *lperror = TRUE;
13022  }
13023  }
13024 
13025  assert(lp->lpsolstat != SCIP_LPSOLSTAT_ITERLIMIT);
13026  assert(SCIPsetIsGE(set, objval, lp->cutoffbound - getFiniteLooseObjval(lp, set, prob))
13028  }
13029  else
13030  {
13031  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
13032  }
13033  }
13034  SCIPsetDebugMsg(set, " -> LP objective limit reached\n");
13035  break;
13036 
13038  SCIPsetDebugMsg(set, " -> LP iteration limit exceeded\n");
13039  break;
13040 
13042  SCIPsetDebugMsg(set, " -> LP time limit exceeded\n");
13043 
13044  /* make sure that we evaluate the time limit exactly in order to avoid erroneous warning */
13045  stat->nclockskipsleft = 0;
13046  if( !stat->userinterrupt && !SCIPsolveIsStopped(set, stat, FALSE) )
13047  {
13048  SCIPmessagePrintWarning(messagehdlr, "LP solver reached time limit, but SCIP time limit is not exceeded yet; "
13049  "you might consider switching the clock type of SCIP\n");
13050  stat->status = SCIP_STATUS_TIMELIMIT;
13051  }
13052  break;
13053 
13054  case SCIP_LPSOLSTAT_ERROR:
13056  SCIPerrorMessage("error in LP solver\n");
13057  retcode = SCIP_LPERROR;
13058  goto TERMINATE;
13059 
13060  default:
13061  SCIPerrorMessage("unknown LP solution status\n");
13062  retcode = SCIP_ERROR;
13063  goto TERMINATE;
13064  }
13065  }
13066  assert(!(*lperror) || !lp->solved);
13067 
13068  TERMINATE:
13069  /* if the LP had to be solved from scratch, we have to reset this flag since it is stored in the LPI; otherwise it
13070  * may happen that we continue to solve from scratch during strong branching */
13071  if( lp->lpifromscratch )
13072  {
13073  SCIP_Bool success;
13074  (void) lpSetFromscratch(lp, FALSE, &success);
13075  SCIPsetDebugMsg(set, "resetting parameter SCIP_LPPARAM_FROMSCRATCH to FALSE %s\n", success ? "" : "failed");
13076  SCIP_UNUSED(success);
13077  }
13078 
13079  return retcode;
13080 }
13081 
13082 /** gets solution status of current LP */
13084  SCIP_LP* lp /**< current LP data */
13085  )
13086 {
13087  assert(lp != NULL);
13088  assert(lp->solved || lp->lpsolstat == SCIP_LPSOLSTAT_NOTSOLVED);
13089 
13090  return (lp->flushed ? lp->lpsolstat : SCIP_LPSOLSTAT_NOTSOLVED);
13091 }
13092 
13093 /** gets objective value of current LP
13094  *
13095  * @note This method returns the objective value of the current LP solution, which might be primal or dual infeasible
13096  * if a limit was hit during solving. It must not be used as a dual bound if the LP solution status is
13097  * SCIP_LPSOLSTAT_ITERLIMIT or SCIP_LPSOLSTAT_TIMELIMIT.
13098  */
13100  SCIP_LP* lp, /**< current LP data */
13101  SCIP_SET* set, /**< global SCIP settings */
13102  SCIP_PROB* prob /**< problem data */
13103  )
13104 {
13105  assert(lp != NULL);
13106  assert(lp->solved);
13107  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13108  assert(set != NULL);
13109 
13110  if( !lp->flushed )
13111  return SCIP_INVALID;
13112  else if( SCIPsetIsInfinity(set, lp->lpobjval) || SCIPsetIsInfinity(set, -lp->lpobjval))
13113  return lp->lpobjval;
13114  else if( lp->looseobjvalinf > 0 )
13115  return -SCIPsetInfinity(set);
13116  else
13117  {
13118  /* recalculate the loose objective value, if needed */
13119  if( !lp->looseobjvalid )
13120  recomputeLooseObjectiveValue(lp, set, prob);
13121 
13122  return lp->lpobjval + lp->looseobjval;
13123  }
13124 }
13125 
13126 /** gets part of objective value of current LP that results from COLUMN variables only */
13128  SCIP_LP* lp /**< current LP data */
13129  )
13130 {
13131  assert(lp != NULL);
13132  assert(lp->solved);
13133 
13134  return (lp->flushed ? lp->lpobjval : SCIP_INVALID);
13135 }
13136 
13137 /** gets part of objective value of current LP that results from LOOSE variables only */
13139  SCIP_LP* lp, /**< current LP data */
13140  SCIP_SET* set, /**< global SCIP settings */
13141  SCIP_PROB* prob /**< problem data */
13142  )
13143 {
13144  assert(lp != NULL);
13145  assert(lp->solved);
13146  assert((lp->nloosevars > 0) || (lp->looseobjvalinf == 0 && lp->looseobjval == 0.0));
13147  assert(set != NULL);
13148 
13149  if( !lp->flushed )
13150  return SCIP_INVALID;
13151  else if( lp->looseobjvalinf > 0 )
13152  return -SCIPsetInfinity(set);
13153  else
13154  return getFiniteLooseObjval(lp, set, prob);
13155 }
13156 
13157 /** remembers the current LP objective value as root solution value */
13159  SCIP_LP* lp, /**< current LP data */
13160  SCIP_SET* set, /**< global SCIP settings */
13161  SCIP_PROB* prob /**< problem data */
13162  )
13163 {
13164  assert(lp != NULL);
13165 
13167  lp->rootlooseobjval = SCIPlpGetLooseObjval(lp, set, prob);
13168 }
13169 
13170 /** invalidates the root LP solution value */
13172  SCIP_LP* lp /**< current LP data */
13173  )
13174 {
13175  assert(lp != NULL);
13176 
13177  lp->rootlpobjval = SCIP_INVALID;
13179 }
13180 
13181 /** recomputes local and global pseudo objective values */
13183  SCIP_LP* lp, /**< current LP data */
13184  SCIP_SET* set, /**< global SCIP settings */
13185  SCIP_PROB* prob /**< problem data */
13186  )
13187 {
13188  SCIP_VAR** vars;
13189  int nvars;
13190  int v;
13191 
13192  assert(lp != NULL);
13193  assert(set != NULL);
13194  assert(prob != NULL);
13195 
13196  vars = prob->vars;
13197  nvars = prob->nvars;
13198 
13199  lp->glbpseudoobjvalinf = 0;
13200  lp->glbpseudoobjval = 0.0;
13201 
13202  lp->pseudoobjvalinf = 0;
13203  lp->pseudoobjval = 0.0;
13204 
13205  for( v = 0; v < nvars; ++v )
13206  {
13207  SCIP_Real obj = SCIPvarGetObj(vars[v]);
13208 
13209  if( SCIPsetIsPositive(set, obj) )
13210  {
13211  /* update the global pseudo objective value */
13212  if( SCIPsetIsInfinity(set, -SCIPvarGetLbGlobal(vars[v])) )
13213  ++(lp->glbpseudoobjvalinf);
13214  else
13215  lp->glbpseudoobjval += obj * SCIPvarGetLbGlobal(vars[v]);
13216 
13217  /* update the local pseudo objective value */
13218  if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(vars[v])) )
13219  ++(lp->pseudoobjvalinf);
13220  else
13221  lp->pseudoobjval += obj * SCIPvarGetLbLocal(vars[v]);
13222  }
13223 
13224  if( SCIPsetIsNegative(set, obj) )
13225  {
13226  /* update the global pseudo objective value */
13227  if( SCIPsetIsInfinity(set, SCIPvarGetUbGlobal(vars[v])) )
13228  ++(lp->glbpseudoobjvalinf);
13229  else
13230  lp->glbpseudoobjval += obj * SCIPvarGetUbGlobal(vars[v]);
13231 
13232  /* update the local pseudo objective value */
13233  if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(vars[v])) )
13234  ++(lp->pseudoobjvalinf);
13235  else
13236  lp->pseudoobjval += obj * SCIPvarGetUbLocal(vars[v]);
13237  }
13238  }
13239 
13240  /* the recomputed values are reliable */
13242  lp->glbpseudoobjvalid = TRUE;
13243  lp->relpseudoobjval = lp->pseudoobjval;
13244  lp->pseudoobjvalid = TRUE;
13245 }
13246 
13247 /** gets the global pseudo objective value; that is all variables set to their best (w.r.t. the objective function)
13248  * global bound
13249  */
13251  SCIP_LP* lp, /**< current LP data */
13252  SCIP_SET* set, /**< global SCIP settings */
13253  SCIP_PROB* prob /**< problem data */
13254  )
13255 {
13256  assert(lp != NULL);
13257  assert(lp->glbpseudoobjvalinf >= 0);
13258  assert(set != NULL);
13259 
13260  if( lp->glbpseudoobjvalinf > 0 || set->nactivepricers > 0 )
13261  return -SCIPsetInfinity(set);
13262  else
13263  {
13264  /* recalculate the global pseudo solution value, if needed */
13265  if( !lp->glbpseudoobjvalid )
13266  recomputeGlbPseudoObjectiveValue(lp, set, prob);
13267 
13268  /* if the global pseudo objective value is smaller than -infinity, we just return -infinity */
13269  if( SCIPsetIsInfinity(set, -lp->glbpseudoobjval) )
13270  return -SCIPsetInfinity(set);
13271 
13272  if( SCIPsetIsInfinity(set, lp->glbpseudoobjval) )
13273  return SCIPsetInfinity(set);
13274 
13275  return lp->glbpseudoobjval;
13276  }
13277 }
13278 
13279 /** gets the pseudo objective value for the current search node; that is all variables set to their best (w.r.t. the
13280  * objective function) local bound
13281  */
13283  SCIP_LP* lp, /**< current LP data */
13284  SCIP_SET* set, /**< global SCIP settings */
13285  SCIP_PROB* prob /**< problem data */
13286  )
13287 {
13288  assert(lp != NULL);
13289  assert(lp->pseudoobjvalinf >= 0);
13290  assert(set != NULL);
13291 
13292  if( lp->pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13293  return -SCIPsetInfinity(set);
13294  else
13295  {
13296  /* recalculate the pseudo solution value, if needed */
13297  if( !lp->pseudoobjvalid )
13298  recomputePseudoObjectiveValue(lp, set, prob);
13299 
13300  /* if the pseudo objective value is smaller than -infinity, we just return -infinity */
13301  if( SCIPsetIsInfinity(set, -lp->pseudoobjval) )
13302  return -SCIPsetInfinity(set);
13303 
13304  if( SCIPsetIsInfinity(set, lp->pseudoobjval) )
13305  return SCIPsetInfinity(set);
13306 
13307  return lp->pseudoobjval;
13308  }
13309 }
13310 
13311 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way */
13313  SCIP_LP* lp, /**< current LP data */
13314  SCIP_SET* set, /**< global SCIP settings */
13315  SCIP_PROB* prob, /**< problem data */
13316  SCIP_VAR* var, /**< problem variable */
13317  SCIP_Real oldbound, /**< old value for bound */
13318  SCIP_Real newbound, /**< new value for bound */
13319  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13320  )
13321 {
13322  SCIP_Real pseudoobjval;
13323  int pseudoobjvalinf;
13324  SCIP_Real obj;
13325 
13326  pseudoobjval = getFinitePseudoObjval(lp, set, prob);
13327  pseudoobjvalinf = lp->pseudoobjvalinf;
13328  obj = SCIPvarGetObj(var);
13329  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13330  {
13331  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13332  pseudoobjvalinf--;
13333  else
13334  pseudoobjval -= oldbound * obj;
13335  assert(pseudoobjvalinf >= 0);
13336  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13337  pseudoobjvalinf++;
13338  else
13339  pseudoobjval += newbound * obj;
13340  }
13341  assert(pseudoobjvalinf >= 0);
13342 
13343  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13344  return -SCIPsetInfinity(set);
13345  else
13346  return pseudoobjval;
13347 }
13348 
13349 /** gets pseudo objective value, if a bound of the given variable would be modified in the given way;
13350  * perform calculations with interval arithmetic to get an exact lower bound
13351  */
13353  SCIP_LP* lp, /**< current LP data */
13354  SCIP_SET* set, /**< global SCIP settings */
13355  SCIP_VAR* var, /**< problem variable */
13356  SCIP_Real oldbound, /**< old value for bound */
13357  SCIP_Real newbound, /**< new value for bound */
13358  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
13359  )
13360 {
13361  SCIP_Real pseudoobjval;
13362  int pseudoobjvalinf;
13363  SCIP_Real obj;
13364 
13365  assert(lp->pseudoobjvalid);
13366 
13367  pseudoobjval = lp->pseudoobjval;
13368  pseudoobjvalinf = lp->pseudoobjvalinf;
13369  obj = SCIPvarGetObj(var);
13370  if( !SCIPsetIsZero(set, obj) && boundtype == SCIPvarGetBestBoundType(var) )
13371  {
13372  SCIP_INTERVAL objint;
13373  SCIP_INTERVAL bd;
13374  SCIP_INTERVAL prod;
13375  SCIP_INTERVAL psval;
13376 
13377  SCIPintervalSet(&psval, pseudoobjval);
13378  SCIPintervalSet(&objint, SCIPvarGetObj(var));
13379 
13380  if( SCIPsetIsInfinity(set, REALABS(oldbound)) )
13381  pseudoobjvalinf--;
13382  else
13383  {
13384  SCIPintervalSet(&bd, oldbound);
13385  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13386  SCIPintervalSub(SCIPsetInfinity(set), &psval, psval, prod);
13387  }
13388  assert(pseudoobjvalinf >= 0);
13389  if( SCIPsetIsInfinity(set, REALABS(newbound)) )
13390  pseudoobjvalinf++;
13391  else
13392  {
13393  SCIPintervalSet(&bd, newbound);
13394  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, objint);
13395  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, prod);
13396  }
13397 
13398  pseudoobjval = SCIPintervalGetInf(psval);
13399  }
13400  assert(pseudoobjvalinf >= 0);
13401 
13402  if( pseudoobjvalinf > 0 || set->nactivepricers > 0 )
13403  return -SCIPsetInfinity(set);
13404  else
13405  return pseudoobjval;
13406 }
13407 
13408 /** compute the objective delta due the new objective coefficient */
13409 static
13411  SCIP_SET* set, /**< global SCIP settings */
13412  SCIP_Real oldobj, /**< old objective value of variable */
13413  SCIP_Real newobj, /**< new objective value of variable */
13414  SCIP_Real lb, /**< lower bound of variable */
13415  SCIP_Real ub, /**< upper bound of variable */
13416  SCIP_Real* deltaval, /**< pointer to store the delta value */
13417  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13418  )
13419 {
13420  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13421  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13422  assert(!SCIPsetIsInfinity(set, lb));
13423  assert(!SCIPsetIsInfinity(set, -ub));
13424  assert(!SCIPsetIsEQ(set, oldobj, newobj));
13425 
13426  (*deltaval) = 0.0;
13427  (*deltainf) = 0;
13428 
13429  if( SCIPsetIsPositive(set, oldobj) )
13430  {
13431  /* sign of objective did not change */
13432  if( SCIPsetIsPositive(set, newobj) )
13433  {
13434  /* if the bound is finite, calculate the deltaval */
13435  if( !SCIPsetIsInfinity(set, -lb) )
13436  (*deltaval) = lb * (newobj - oldobj);
13437  }
13438  /* sign of objective did change, so the best bound does change */
13439  else if( SCIPsetIsNegative(set, newobj) )
13440  {
13441  if( SCIPsetIsInfinity(set, -lb) )
13442  {
13443  /* old best bound was infinite while new one is not */
13444  if( !SCIPsetIsInfinity(set, ub) )
13445  {
13446  (*deltainf) = -1;
13447  (*deltaval) = ub * newobj;
13448  }
13449  }
13450  else
13451  {
13452  /* new best bound is infinite while old one was not */
13453  if( SCIPsetIsInfinity(set, ub) )
13454  {
13455  (*deltainf) = 1;
13456  (*deltaval) = -lb * oldobj;
13457  }
13458  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13459  else
13460  {
13461  (*deltaval) = (ub * newobj) - (lb * oldobj);
13462  }
13463  }
13464  }
13465  /* new objective is 0.0 */
13466  else
13467  {
13468  if( SCIPsetIsInfinity(set, -lb) )
13469  (*deltainf) = -1;
13470  else
13471  (*deltaval) = -lb * oldobj;
13472  }
13473  }
13474  else if( SCIPsetIsNegative(set, oldobj) )
13475  {
13476  /* sign of objective did not change */
13477  if( SCIPsetIsNegative(set, newobj) )
13478  {
13479  /* if the bound is finite, calculate the deltaval */
13480  if( !SCIPsetIsInfinity(set, ub) )
13481  (*deltaval) = ub * (newobj - oldobj);
13482  }
13483  /* sign of objective did change, so the best bound does change */
13484  else if( SCIPsetIsPositive(set, newobj) )
13485  {
13486  if( SCIPsetIsInfinity(set, ub) )
13487  {
13488  /* old best bound was infinite while new one is not */
13489  if( !SCIPsetIsInfinity(set, -lb) )
13490  {
13491  (*deltainf) = -1;
13492  (*deltaval) = lb * newobj;
13493  }
13494  }
13495  else
13496  {
13497  /* new best bound is infinite while old one was not */
13498  if( SCIPsetIsInfinity(set, -lb) )
13499  {
13500  (*deltainf) = 1;
13501  (*deltaval) = -ub * oldobj;
13502  }
13503  /* neither old nor new best bound is infinite, so just calculate the deltaval */
13504  else
13505  {
13506  (*deltaval) = (lb * newobj) - (ub * oldobj);
13507  }
13508  }
13509  }
13510  /* new objective is 0.0 */
13511  else
13512  {
13513  if( SCIPsetIsInfinity(set, ub) )
13514  (*deltainf) = -1;
13515  else
13516  (*deltaval) = -ub * oldobj;
13517  }
13518  }
13519  /* old objective was 0.0 */
13520  else
13521  {
13522  if( SCIPsetIsNegative(set, newobj) )
13523  {
13524  if( SCIPsetIsInfinity(set, ub) )
13525  (*deltainf) = 1;
13526  else
13527  (*deltaval) = ub * newobj;
13528  }
13529  else if( SCIPsetIsPositive(set, newobj) )
13530  {
13531  if( SCIPsetIsInfinity(set, -lb) )
13532  (*deltainf) = 1;
13533  else
13534  (*deltaval) = lb * newobj;
13535  }
13536  }
13537 }
13538 
13539 /** compute the objective delta due the new lower bound */
13540 static
13542  SCIP_SET* set, /**< global SCIP settings */
13543  SCIP_Real obj, /**< objective value of variable */
13544  SCIP_Real oldlb, /**< old lower bound of variable */
13545  SCIP_Real newlb, /**< new lower bound of variable */
13546  SCIP_Real* deltaval, /**< pointer to store the delta value */
13547  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13548  )
13549 {
13550  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13551  assert(!SCIPsetIsInfinity(set, oldlb));
13552  assert(!SCIPsetIsInfinity(set, -oldlb) || !SCIPsetIsInfinity(set, -newlb));
13553  assert(SCIPsetIsPositive(set, obj)); /* we only need to update if the objective is positive */
13554 
13555  if( SCIPsetIsInfinity(set, -oldlb) )
13556  {
13557  if( !SCIPsetIsInfinity(set, newlb) )
13558  {
13559  (*deltainf) = -1;
13560  (*deltaval) = newlb * obj;
13561  }
13562  else
13563  {
13564  (*deltainf) = 0;
13565  (*deltaval) = 0.0;
13566  }
13567  }
13568  else if( SCIPsetIsInfinity(set, REALABS(newlb)) )
13569  {
13570  (*deltainf) = 1;
13571  (*deltaval) = -oldlb * obj;
13572  }
13573  else
13574  {
13575  (*deltainf) = 0;
13576  (*deltaval) = obj * (newlb - oldlb);
13577  }
13578 }
13579 
13580 /** compute the objective delta due the new upper bound */
13581 static
13583  SCIP_SET* set, /**< global SCIP settings */
13584  SCIP_Real obj, /**< objective value of variable */
13585  SCIP_Real oldub, /**< old upper bound of variable */
13586  SCIP_Real newub, /**< new upper bound of variable */
13587  SCIP_Real* deltaval, /**< pointer to store the delta value */
13588  int* deltainf /**< pointer to store the number of variables with infinite best bound */
13589  )
13590 {
13591  assert(!SCIPsetIsInfinity(set, REALABS(obj)));
13592  assert(!SCIPsetIsInfinity(set, -oldub));
13593  assert(!SCIPsetIsInfinity(set, oldub) || !SCIPsetIsInfinity(set, newub));
13594  assert(SCIPsetIsNegative(set, obj)); /* we only need to update if the objective is negative */
13595 
13596  if( SCIPsetIsInfinity(set, oldub) )
13597  {
13598  if( !SCIPsetIsInfinity(set, -newub) )
13599  {
13600  (*deltainf) = -1;
13601  (*deltaval) = newub * obj;
13602  }
13603  else
13604  {
13605  (*deltainf) = 0;
13606  (*deltaval) = 0.0;
13607  }
13608  }
13609  else if( SCIPsetIsInfinity(set, REALABS(newub)) )
13610  {
13611  (*deltainf) = 1;
13612  (*deltaval) = -oldub * obj;
13613  }
13614  else
13615  {
13616  (*deltainf) = 0;
13617  (*deltaval) = obj * (newub - oldub);
13618  }
13619 }
13620 
13621 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds */
13622 static
13624  SCIP_LP* lp, /**< current LP data */
13625  SCIP_SET* set, /**< global SCIP settings */
13626  SCIP_VAR* var, /**< problem variable that changed */
13627  SCIP_Real deltaval, /**< delta value in the objective function */
13628  int deltainf, /**< delta value for the number of variables with infinite best bound */
13629  SCIP_Bool local, /**< should the local pseudo objective value be updated? */
13630  SCIP_Bool loose, /**< should the loose objective value be updated? */
13631  SCIP_Bool global /**< should the global pseudo objective value be updated? */
13632  )
13633 {
13634  assert(lp != NULL);
13635  assert(lp->looseobjvalinf >= 0);
13636  assert(lp->pseudoobjvalinf >= 0);
13637  assert(lp->glbpseudoobjvalinf >= 0);
13638 
13639  /* update the pseudo objective value */
13640  if( local )
13641  {
13642  lp->pseudoobjvalinf += deltainf;
13643  if( lp->pseudoobjvalid )
13644  {
13645  lp->pseudoobjval += deltaval;
13646 
13647  /* if the absolute value was increased, this is regarded as reliable,
13648  * otherwise, we check whether we can still trust the updated value
13649  */
13650  if( REALABS(lp->relpseudoobjval) < REALABS(lp->pseudoobjval) )
13651  lp->relpseudoobjval = lp->pseudoobjval;
13652  else if( SCIPsetIsUpdateUnreliable(set, lp->pseudoobjval, lp->relpseudoobjval) )
13653  lp->pseudoobjvalid = FALSE;
13654  }
13655 
13656  /* after changing a local bound on a LOOSE variable, we have to update the loose objective value, too */
13658  loose = TRUE;
13659  }
13660  /* update the loose objective value */
13661  if( loose )
13662  {
13663  lp->looseobjvalinf += deltainf;
13664 
13665  if( deltaval != 0.0 && lp->looseobjvalid )
13666  {
13667  lp->looseobjval += deltaval;
13668 
13669  /* if the absolute value was increased, this is regarded as reliable,
13670  * otherwise, we check whether we can still trust the updated value
13671  */
13672  if( REALABS(lp->rellooseobjval) < REALABS(lp->looseobjval) )
13673  lp->rellooseobjval = lp->looseobjval;
13674  else if( SCIPsetIsUpdateUnreliable(set, lp->looseobjval, lp->rellooseobjval) )
13675  lp->looseobjvalid = FALSE;
13676  }
13677  }
13678  /* update the root pseudo objective values */
13679  if( global )
13680  {
13681  lp->glbpseudoobjvalinf += deltainf;
13682  if( lp->glbpseudoobjvalid )
13683  {
13684  lp->glbpseudoobjval += deltaval;
13685 
13686  /* if the absolute value was increased, this is regarded as reliable,
13687  * otherwise, we check whether we can still trust the updated value
13688  */
13692  lp->glbpseudoobjvalid = FALSE;
13693  }
13694  }
13695 
13696  assert(lp->looseobjvalinf >= 0);
13697  assert(lp->pseudoobjvalinf >= 0);
13698  assert(lp->glbpseudoobjvalinf >= 0);
13699 }
13700 
13701 /** updates current pseudo and loose objective values for a change in a variable's objective value or bounds;
13702  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
13703  */
13704 static
13706  SCIP_LP* lp, /**< current LP data */
13707  SCIP_SET* set, /**< global SCIP settings */
13708  SCIP_VAR* var, /**< problem variable that changed */
13709  SCIP_Real oldobj, /**< old objective value of variable */
13710  SCIP_Real oldlb, /**< old objective value of variable */
13711  SCIP_Real oldub, /**< old objective value of variable */
13712  SCIP_Real newobj, /**< new objective value of variable */
13713  SCIP_Real newlb, /**< new objective value of variable */
13714  SCIP_Real newub /**< new objective value of variable */
13715  )
13716 {
13717  SCIP_INTERVAL deltaval;
13718  SCIP_INTERVAL bd;
13719  SCIP_INTERVAL obj;
13720  SCIP_INTERVAL prod;
13721  SCIP_INTERVAL psval;
13722  int deltainf;
13723 
13724  assert(lp != NULL);
13725  assert(lp->pseudoobjvalinf >= 0);
13726  assert(lp->looseobjvalinf >= 0);
13727  assert(!SCIPsetIsInfinity(set, REALABS(oldobj)));
13728  assert(!SCIPsetIsInfinity(set, oldlb));
13729  assert(!SCIPsetIsInfinity(set, -oldub));
13730  assert(!SCIPsetIsInfinity(set, REALABS(newobj)));
13731  assert(!SCIPsetIsInfinity(set, newlb));
13732  assert(!SCIPsetIsInfinity(set, -newub));
13733  assert(var != NULL);
13734 
13736  {
13737  SCIPerrorMessage("LP was informed of an objective change of a non-active variable\n");
13738  return SCIP_INVALIDDATA;
13739  }
13740 
13741  assert(SCIPvarGetProbindex(var) >= 0);
13742 
13743  SCIPintervalSet(&deltaval, 0.0);
13744  deltainf = 0;
13745 
13746  /* subtract old pseudo objective value */
13747  if( oldobj > 0.0 )
13748  {
13749  if( SCIPsetIsInfinity(set, -oldlb) )
13750  deltainf--;
13751  else
13752  {
13753  SCIPintervalSet(&bd, oldlb);
13754  SCIPintervalSet(&obj, oldobj);
13755  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13756  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldlb * oldobj; */
13757  }
13758  }
13759  else if( oldobj < 0.0 )
13760  {
13761  if( SCIPsetIsInfinity(set, oldub) )
13762  deltainf--;
13763  else
13764  {
13765  SCIPintervalSet(&bd, oldub);
13766  SCIPintervalSet(&obj, oldobj);
13767  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13768  SCIPintervalSub(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval -= oldub * oldobj; */
13769  }
13770  }
13771 
13772  /* add new pseudo objective value */
13773  if( newobj > 0.0 )
13774  {
13775  if( SCIPsetIsInfinity(set, -newlb) )
13776  deltainf++;
13777  else
13778  {
13779  SCIPintervalSet(&bd, newlb);
13780  SCIPintervalSet(&obj, newobj);
13781  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13782  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newlb * newobj; */
13783  }
13784  }
13785  else if( newobj < 0.0 )
13786  {
13787  if( SCIPsetIsInfinity(set, newub) )
13788  deltainf++;
13789  else
13790  {
13791  SCIPintervalSet(&bd, newub);
13792  SCIPintervalSet(&obj, newobj);
13793  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, obj);
13794  SCIPintervalAdd(SCIPsetInfinity(set), &deltaval, deltaval, prod); /* deltaval += newub * newobj; */
13795  }
13796  }
13797 
13798  /* update the pseudo and loose objective values */
13799  SCIPintervalSet(&psval, lp->pseudoobjval);
13800  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13801  lp->pseudoobjval = SCIPintervalGetInf(psval);
13802  lp->pseudoobjvalinf += deltainf;
13804  {
13805  SCIPintervalSet(&psval, lp->looseobjval);
13806  SCIPintervalAdd(SCIPsetInfinity(set), &psval, psval, deltaval);
13807  lp->looseobjval = SCIPintervalGetInf(psval);
13808  lp->looseobjvalinf += deltainf;
13809  }
13810 
13811  assert(lp->pseudoobjvalinf >= 0);
13812  assert(lp->looseobjvalinf >= 0);
13813 
13814  return SCIP_OKAY;
13815 }
13816 
13817 /** updates current pseudo and loose objective value for a change in a variable's objective coefficient */
13819  SCIP_LP* lp, /**< current LP data */
13820  SCIP_SET* set, /**< global SCIP settings */
13821  SCIP_VAR* var, /**< problem variable that changed */
13822  SCIP_Real oldobj, /**< old objective coefficient of variable */
13823  SCIP_Real newobj /**< new objective coefficient of variable */
13824  )
13825 {
13826  assert(set != NULL);
13827  assert(var != NULL);
13828 
13829  if( set->misc_exactsolve )
13830  {
13831  if( oldobj != newobj ) /*lint !e777*/
13832  {
13833  SCIP_CALL( lpUpdateVarProved(lp, set, var, oldobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
13834  newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) );
13835  }
13836  }
13837  else
13838  {
13839  if( !SCIPsetIsEQ(set, oldobj, newobj) )
13840  {
13841  SCIP_Real deltaval;
13842  int deltainf;
13843 
13845  assert(SCIPvarGetProbindex(var) >= 0);
13846 
13847  /* the objective coefficient can only be changed during presolving, that implies that the global and local
13848  * domain of the variable are the same
13849  */
13850  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetLbGlobal(var), SCIPvarGetLbLocal(var)));
13851  assert(lp->probing || SCIPsetIsEQ(set, SCIPvarGetUbGlobal(var), SCIPvarGetUbLocal(var)));
13852 
13853  /* compute the pseudo objective delta due the new objective coefficient */
13854  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), &deltaval, &deltainf);
13855 
13856  /* update the local pseudo objective value */
13857  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13858 
13859  /* compute the pseudo objective delta due the new objective coefficient */
13860  getObjvalDeltaObj(set, oldobj, newobj, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), &deltaval, &deltainf);
13861 
13862  /* update the global pseudo objective value */
13863  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13864  }
13865  }
13866 
13867  return SCIP_OKAY;
13868 }
13869 
13870 
13871 /** updates current root pseudo objective value for a global change in a variable's lower bound */
13873  SCIP_LP* lp, /**< current LP data */
13874  SCIP_SET* set, /**< global SCIP settings */
13875  SCIP_VAR* var, /**< problem variable that changed */
13876  SCIP_Real oldlb, /**< old lower bound of variable */
13877  SCIP_Real newlb /**< new lower bound of variable */
13878  )
13879 {
13880  assert(set != NULL);
13881  assert(var != NULL);
13882 
13883  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13884  {
13885  SCIP_Real deltaval;
13886  int deltainf;
13887 
13888  /* compute the pseudo objective delta due the new lower bound */
13889  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13890 
13891  /* update the root pseudo objective values */
13892  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13893  }
13894 
13895  return SCIP_OKAY;
13896 }
13897 
13898 /** updates current pseudo and loose objective value for a change in a variable's lower bound */
13900  SCIP_LP* lp, /**< current LP data */
13901  SCIP_SET* set, /**< global SCIP settings */
13902  SCIP_VAR* var, /**< problem variable that changed */
13903  SCIP_Real oldlb, /**< old lower bound of variable */
13904  SCIP_Real newlb /**< new lower bound of variable */
13905  )
13906 {
13907  assert(set != NULL);
13908  assert(var != NULL);
13909 
13910  if( set->misc_exactsolve )
13911  {
13912  if( oldlb != newlb && SCIPvarGetObj(var) > 0.0 ) /*lint !e777*/
13913  {
13914  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), oldlb, SCIPvarGetUbLocal(var),
13915  SCIPvarGetObj(var), newlb, SCIPvarGetUbLocal(var)) );
13916  }
13917  }
13918  else
13919  {
13920  if( !SCIPsetIsEQ(set, oldlb, newlb) && SCIPsetIsPositive(set, SCIPvarGetObj(var)) )
13921  {
13922  SCIP_Real deltaval;
13923  int deltainf;
13924 
13926  assert(SCIPvarGetProbindex(var) >= 0);
13927 
13928  /* compute the pseudo objective delta due the new lower bound */
13929  getObjvalDeltaLb(set, SCIPvarGetObj(var), oldlb, newlb, &deltaval, &deltainf);
13930 
13931  /* update the pseudo and loose objective values */
13932  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
13933  }
13934  }
13935 
13936  return SCIP_OKAY;
13937 }
13938 
13939 /** updates current root pseudo objective value for a global change in a variable's upper bound */
13941  SCIP_LP* lp, /**< current LP data */
13942  SCIP_SET* set, /**< global SCIP settings */
13943  SCIP_VAR* var, /**< problem variable that changed */
13944  SCIP_Real oldub, /**< old upper bound of variable */
13945  SCIP_Real newub /**< new upper bound of variable */
13946  )
13947 {
13948  assert(set != NULL);
13949  assert(var != NULL);
13950 
13951  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13952  {
13953  SCIP_Real deltaval;
13954  int deltainf;
13955 
13956  /* compute the pseudo objective delta due the new upper bound */
13957  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13958 
13959  /* update the root pseudo objective values */
13960  lpUpdateObjval(lp, set, var, deltaval, deltainf, FALSE, FALSE, TRUE);
13961  }
13962 
13963  return SCIP_OKAY;
13964 }
13965 
13966 /** updates current pseudo objective value for a change in a variable's upper bound */
13968  SCIP_LP* lp, /**< current LP data */
13969  SCIP_SET* set, /**< global SCIP settings */
13970  SCIP_VAR* var, /**< problem variable that changed */
13971  SCIP_Real oldub, /**< old upper bound of variable */
13972  SCIP_Real newub /**< new upper bound of variable */
13973  )
13974 {
13975  assert(set != NULL);
13976  assert(var != NULL);
13977 
13978  if( set->misc_exactsolve )
13979  {
13980  if( oldub != newub && SCIPvarGetObj(var) < 0.0 ) /*lint !e777*/
13981  {
13982  SCIP_CALL( lpUpdateVarProved(lp, set, var, SCIPvarGetObj(var), SCIPvarGetLbLocal(var), oldub,
13983  SCIPvarGetObj(var), SCIPvarGetLbLocal(var), newub) );
13984  }
13985  }
13986  else
13987  {
13988  if( !SCIPsetIsEQ(set, oldub, newub) && SCIPsetIsNegative(set, SCIPvarGetObj(var)) )
13989  {
13990  SCIP_Real deltaval;
13991  int deltainf;
13992 
13994  assert(SCIPvarGetProbindex(var) >= 0);
13995 
13996  /* compute the pseudo objective delta due the new upper bound */
13997  getObjvalDeltaUb(set, SCIPvarGetObj(var), oldub, newub, &deltaval, &deltainf);
13998 
13999  /* update the pseudo and loose objective values */
14000  lpUpdateObjval(lp, set, var, deltaval, deltainf, TRUE, FALSE, FALSE);
14001  }
14002  }
14003 
14004  return SCIP_OKAY;
14005 }
14006 
14007 /** informs LP, that given variable was added to the problem */
14009  SCIP_LP* lp, /**< current LP data */
14010  SCIP_SET* set, /**< global SCIP settings */
14011  SCIP_VAR* var /**< variable that is now a LOOSE problem variable */
14012  )
14013 {
14014  assert(lp != NULL);
14016  assert(SCIPvarGetProbindex(var) >= 0);
14017 
14018  /* add the variable to the loose objective value sum */
14019  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, 0.0, SCIPvarGetObj(var)) );
14020 
14021  /* update the loose variables counter */
14023  lp->nloosevars++;
14024 
14025  return SCIP_OKAY;
14026 }
14027 
14028 /** informs LP, that given variable is to be deleted from the problem */
14030  SCIP_LP* lp, /**< current LP data */
14031  SCIP_SET* set, /**< global SCIP settings */
14032  SCIP_VAR* var /**< variable that will be deleted from the problem */
14033  )
14034 {
14035  assert(lp != NULL);
14037  assert(SCIPvarGetProbindex(var) >= 0);
14038 
14039  /* subtract the variable from the loose objective value sum */
14040  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, SCIPvarGetObj(var), 0.0) );
14041 
14042  /* update the loose variables counter */
14044  {
14045  SCIPlpDecNLoosevars(lp);
14046  }
14047 
14048  return SCIP_OKAY;
14049 }
14050 
14051 /** informs LP, that given formerly loose problem variable is now a column variable */
14052 static
14054  SCIP_LP* lp, /**< current LP data */
14055  SCIP_SET* set, /**< global SCIP settings */
14056  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14057  )
14058 {
14059  SCIP_Real obj;
14060  SCIP_Real lb;
14061  SCIP_Real ub;
14062 
14063  assert(lp != NULL);
14064  assert(lp->nloosevars > 0);
14065  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14066  assert(SCIPvarGetProbindex(var) >= 0);
14067  assert(lp->looseobjvalinf >= 0);
14068 
14069  obj = SCIPvarGetObj(var);
14070 
14071  /* update loose objective value */
14072  if( SCIPsetIsPositive(set, obj) )
14073  {
14074  lb = SCIPvarGetLbLocal(var);
14075  if( SCIPsetIsInfinity(set, -lb) )
14076  lp->looseobjvalinf--;
14077  else
14078  lpUpdateObjval(lp, set, var, -lb * obj, 0, FALSE, TRUE, FALSE);
14079  }
14080  else if( SCIPsetIsNegative(set, obj) )
14081  {
14082  ub = SCIPvarGetUbLocal(var);
14083  if( SCIPsetIsInfinity(set, ub) )
14084  lp->looseobjvalinf--;
14085  else
14086  lpUpdateObjval(lp, set, var, -ub * obj, 0, FALSE, TRUE, FALSE);
14087  }
14088 
14089  SCIPlpDecNLoosevars(lp);
14090 
14091  assert(lp->looseobjvalinf >= 0);
14092 
14093  return SCIP_OKAY;
14094 }
14095 
14096 /** informs LP, that given formerly loose problem variable is now a column variable
14097  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14098  */
14099 static
14101  SCIP_LP* lp, /**< current LP data */
14102  SCIP_SET* set, /**< global SCIP settings */
14103  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14104  )
14105 {
14106  SCIP_INTERVAL bd;
14107  SCIP_INTERVAL ob;
14108  SCIP_INTERVAL prod;
14109  SCIP_INTERVAL loose;
14110  SCIP_Real obj;
14111  SCIP_Real lb;
14112  SCIP_Real ub;
14113 
14114  assert(lp != NULL);
14115  assert(lp->nloosevars > 0);
14116  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
14117  assert(SCIPvarGetProbindex(var) >= 0);
14118 
14119  obj = SCIPvarGetObj(var);
14120 
14121  SCIPintervalSet(&loose, lp->looseobjval);
14122 
14123  /* update loose objective value corresponding to the deletion of variable */
14124  if( obj > 0.0 )
14125  {
14126  lb = SCIPvarGetLbLocal(var);
14127  if( SCIPsetIsInfinity(set, -lb) )
14128  lp->looseobjvalinf--;
14129  else
14130  {
14131  SCIPintervalSet(&bd, lb);
14132  SCIPintervalSet(&ob, obj);
14133  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14134  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= lb * obj; */
14135  }
14136  }
14137  else if( SCIPsetIsNegative(set, obj) )
14138  {
14139  ub = SCIPvarGetUbLocal(var);
14140  if( SCIPsetIsInfinity(set, ub) )
14141  lp->looseobjvalinf--;
14142  else
14143  {
14144  SCIPintervalSet(&bd, ub);
14145  SCIPintervalSet(&ob, obj);
14146  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14147  SCIPintervalSub(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval -= ub * obj; */
14148  }
14149  }
14150  lp->nloosevars--;
14151 
14152  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14153  if( lp->nloosevars == 0 )
14154  {
14155  assert(lp->looseobjvalinf == 0);
14156  lp->looseobjval = 0.0;
14157  }
14158  else
14159  lp->looseobjval = SCIPintervalGetInf(loose);
14160 
14161  return SCIP_OKAY;
14162 }
14163 
14164 /** informs LP, that given formerly loose problem variable is now a column variable */
14166  SCIP_LP* lp, /**< current LP data */
14167  SCIP_SET* set, /**< global SCIP settings */
14168  SCIP_VAR* var /**< problem variable that changed from LOOSE to COLUMN */
14169  )
14170 {
14171  assert(set != NULL);
14172 
14173  if( set->misc_exactsolve )
14174  {
14175  SCIP_CALL( lpUpdateVarColumnProved(lp, set, var) );
14176  }
14177  else
14178  {
14179  SCIP_CALL( lpUpdateVarColumn(lp, set, var) );
14180  }
14181 
14182  return SCIP_OKAY;
14183 }
14184 
14185 /** informs LP, that given formerly column problem variable is now again a loose variable */
14186 static
14188  SCIP_LP* lp, /**< current LP data */
14189  SCIP_SET* set, /**< global SCIP settings */
14190  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14191  )
14192 {
14193  SCIP_Real obj;
14194  SCIP_Real lb;
14195  SCIP_Real ub;
14196 
14197  assert(lp != NULL);
14198  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14199  assert(SCIPvarGetProbindex(var) >= 0);
14200  assert(lp->looseobjvalinf >= 0);
14201 
14202  obj = SCIPvarGetObj(var);
14203 
14204  /* update loose objective value corresponding to the addition of variable */
14205  if( SCIPsetIsPositive(set, obj) )
14206  {
14207  lb = SCIPvarGetLbLocal(var);
14208  if( SCIPsetIsInfinity(set, -lb) )
14209  lp->looseobjvalinf++;
14210  else
14211  lpUpdateObjval(lp, set, var, lb * obj, 0, FALSE, TRUE, FALSE);
14212  }
14213  else if( SCIPsetIsNegative(set, obj) )
14214  {
14215  ub = SCIPvarGetUbLocal(var);
14216  if( SCIPsetIsInfinity(set, ub) )
14217  lp->looseobjvalinf++;
14218  else
14219  lpUpdateObjval(lp, set, var, ub * obj, 0, FALSE, TRUE, FALSE);
14220  }
14221  lp->nloosevars++;
14222 
14223  assert(lp->looseobjvalinf >= 0);
14224 
14225  return SCIP_OKAY;
14226 }
14227 
14228 /** informs LP, that given formerly column problem variable is now again a loose variable
14229  * pseudo objective value is calculated with interval arithmetics to get a proved lower bound
14230  */
14231 static
14233  SCIP_LP* lp, /**< current LP data */
14234  SCIP_SET* set, /**< global SCIP settings */
14235  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14236  )
14237 {
14238  SCIP_INTERVAL bd;
14239  SCIP_INTERVAL ob;
14240  SCIP_INTERVAL prod;
14241  SCIP_INTERVAL loose;
14242  SCIP_Real obj;
14243  SCIP_Real lb;
14244  SCIP_Real ub;
14245 
14246  assert(lp != NULL);
14247  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE);
14248  assert(SCIPvarGetProbindex(var) >= 0);
14249 
14250  obj = SCIPvarGetObj(var);
14251 
14252  SCIPintervalSet(&loose, lp->looseobjval);
14253 
14254  /* update loose objective value corresponding to the deletion of variable */
14255  if( obj > 0.0 )
14256  {
14257  lb = SCIPvarGetLbLocal(var);
14258  if( SCIPsetIsInfinity(set, -lb) )
14259  lp->looseobjvalinf++;
14260  else
14261  {
14262  SCIPintervalSet(&bd, lb);
14263  SCIPintervalSet(&ob, obj);
14264  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14265  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += lb * obj; */
14266  }
14267  }
14268  else if( SCIPsetIsNegative(set, obj) )
14269  {
14270  ub = SCIPvarGetUbLocal(var);
14271  if( SCIPsetIsInfinity(set, ub) )
14272  lp->looseobjvalinf++;
14273  else
14274  {
14275  SCIPintervalSet(&bd, ub);
14276  SCIPintervalSet(&ob, obj);
14277  SCIPintervalMul(SCIPsetInfinity(set), &prod, bd, ob);
14278  SCIPintervalAdd(SCIPsetInfinity(set), &loose, loose, prod); /* lp->looseobjval += ub * obj; */
14279  }
14280  }
14281  lp->nloosevars++;
14282 
14283  lp->looseobjval = SCIPintervalGetInf(loose);
14284 
14285  return SCIP_OKAY;
14286 }
14287 
14288 /** informs LP, that given formerly column problem variable is now again a loose variable */
14290  SCIP_LP* lp, /**< current LP data */
14291  SCIP_SET* set, /**< global SCIP settings */
14292  SCIP_VAR* var /**< problem variable that changed from COLUMN to LOOSE */
14293  )
14294 {
14295  assert(set != NULL);
14296 
14297  if( set->misc_exactsolve )
14298  {
14299  SCIP_CALL( lpUpdateVarLooseProved(lp, set, var) );
14300  }
14301  else
14302  {
14303  SCIP_CALL( lpUpdateVarLoose(lp, set, var) );
14304  }
14305 
14306  return SCIP_OKAY;
14307 }
14308 
14309 /** decrease the number of loose variables by one */
14311  SCIP_LP* lp /**< current LP data */
14312  )
14313 {
14314  assert(lp != NULL);
14315  assert(lp->nloosevars > 0);
14316 
14317  lp->nloosevars--;
14318 
14319  /* get rid of numerical problems: set loose objective value explicitly to zero, if no loose variables remain */
14320  if( lp->nloosevars == 0 )
14321  {
14322  assert(lp->looseobjvalinf == 0);
14323  lp->looseobjval = 0.0;
14324  }
14325 }
14326 
14327 /** stores the LP solution in the columns and rows */
14329  SCIP_LP* lp, /**< current LP data */
14330  SCIP_SET* set, /**< global SCIP settings */
14331  SCIP_STAT* stat, /**< problem statistics */
14332  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14333  SCIP_Bool* dualfeasible /**< pointer to store whether the solution is dual feasible, or NULL */
14334  )
14335 {
14336  SCIP_COL** lpicols;
14337  SCIP_ROW** lpirows;
14338  SCIP_Real* primsol;
14339  SCIP_Real* dualsol;
14340  SCIP_Real* activity = NULL;
14341  SCIP_Real* redcost;
14342  SCIP_Real primalbound;
14343  SCIP_Real dualbound;
14344  SCIP_Bool stillprimalfeasible;
14345  SCIP_Bool stilldualfeasible;
14346  int* cstat;
14347  int* rstat;
14348  SCIP_Longint lpcount;
14349  int nlpicols;
14350  int nlpirows;
14351  int c;
14352  int r;
14353 
14354  assert(lp != NULL);
14355  assert(lp->flushed);
14356  assert(lp->solved);
14357  assert(set != NULL);
14358  assert(stat != NULL);
14359  assert(lp->validsollp <= stat->lpcount);
14360 
14361  assert(lp->lpsolstat == SCIP_LPSOLSTAT_OPTIMAL);
14362 
14363  /* initialize return and feasibility flags; if primal oder dual feasibility shall not be checked, we set the
14364  * corresponding flag immediately to FALSE to skip all checks
14365  */
14366  if( primalfeasible == NULL )
14367  stillprimalfeasible = FALSE;
14368  else
14369  {
14370  *primalfeasible = TRUE;
14371  stillprimalfeasible = TRUE;
14372  }
14373  if( dualfeasible == NULL )
14374  stilldualfeasible = FALSE;
14375  else
14376  {
14377  *dualfeasible = TRUE;
14378  stilldualfeasible = TRUE;
14379  }
14380 
14381  /* check if the values are already calculated */
14382  if( lp->validsollp == stat->lpcount )
14383  return SCIP_OKAY;
14384  lp->validsollp = stat->lpcount;
14385 
14386  SCIPsetDebugMsg(set, "getting new LP solution %" SCIP_LONGINT_FORMAT " for solstat %d\n",
14387  stat->lpcount, SCIPlpGetSolstat(lp));
14388 
14389  lpicols = lp->lpicols;
14390  lpirows = lp->lpirows;
14391  nlpicols = lp->nlpicols;
14392  nlpirows = lp->nlpirows;
14393  lpcount = stat->lpcount;
14394 
14395  /* get temporary memory */
14396  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, nlpicols) );
14397  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualsol, nlpirows) );
14398 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14399  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, nlpirows) );
14400 #endif
14401  SCIP_CALL( SCIPsetAllocBufferArray(set, &redcost, nlpicols) );
14402  SCIP_CALL( SCIPsetAllocBufferArray(set, &cstat, nlpicols) );
14403  SCIP_CALL( SCIPsetAllocBufferArray(set, &rstat, nlpirows) );
14404 
14405  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, dualsol, activity, redcost) );
14406  if( lp->solisbasic )
14407  {
14408  SCIP_CALL( SCIPlpiGetBase(lp->lpi, cstat, rstat) );
14409  }
14410  else
14411  {
14412  BMSclearMemoryArray(cstat, nlpicols);
14413  BMSclearMemoryArray(rstat, nlpirows);
14414  }
14415 
14416  primalbound = 0.0;
14417  dualbound = 0.0;
14418 
14419  /* copy primal solution and reduced costs into columns */
14420  for( c = 0; c < nlpicols; ++c )
14421  {
14422  assert( 0 <= cstat[c] && cstat[c] < 4 );
14423  lpicols[c]->primsol = primsol[c];
14424  lpicols[c]->minprimsol = MIN(lpicols[c]->minprimsol, primsol[c]);
14425  lpicols[c]->maxprimsol = MAX(lpicols[c]->maxprimsol, primsol[c]);
14426  lpicols[c]->redcost = redcost[c];
14427  lpicols[c]->basisstatus = (unsigned int) cstat[c];
14428  lpicols[c]->validredcostlp = lpcount;
14429  if( stillprimalfeasible )
14430  {
14431  stillprimalfeasible =
14432  (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb))
14433  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub));
14434  primalbound += (lpicols[c]->primsol * lpicols[c]->obj);
14435  }
14436  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14437  {
14438  double compslack;
14439 
14440  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14441  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinty() for unbounded
14442  * variables, which would magnify even the tiniest violation in the dual multiplier
14443  */
14444  if( stilldualfeasible )
14445  {
14446  compslack = MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost;
14447  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14448  }
14449  if( stilldualfeasible )
14450  {
14451  compslack = MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost;
14452  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14453  }
14454 
14455  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14456  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14457  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14458  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14459  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14460  !SCIPsetIsDualfeasPositive(set, MIN((lpicols[c]->primsol - lpicols[c]->lb), 1.0) * lpicols[c]->redcost),
14461  !SCIPsetIsDualfeasNegative(set, MIN((lpicols[c]->ub - lpicols[c]->primsol), 1.0) * lpicols[c]->redcost),
14462  dualfeasible != NULL ? stilldualfeasible : TRUE);
14463  }
14464  else
14465  {
14466  /* if dual feasibility check is disabled, set reduced costs of basic variables to 0 */
14467  if( dualfeasible == NULL && lpicols[c]->basisstatus == (unsigned int) SCIP_BASESTAT_BASIC )
14468  {
14469  lpicols[c]->redcost = 0.0;
14470  }
14471 
14472  /* complementary slackness means that if a variable is not at its lower or upper bound, its reduced costs
14473  * must be non-positive or non-negative, respectively; in particular, if a variable is strictly within its
14474  * bounds, its reduced cost must be zero
14475  */
14476  if( stilldualfeasible
14477  && (SCIPsetIsInfinity(set, -lpicols[c]->lb) || SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb)) )
14478  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost);
14479  if( stilldualfeasible
14480  && (SCIPsetIsInfinity(set, lpicols[c]->ub) || SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub)) )
14481  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost);
14482 
14483  SCIPsetDebugMsg(set, " col <%s> [%.9g,%.9g]: primsol=%.9f, redcost=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14484  SCIPvarGetName(lpicols[c]->var), lpicols[c]->lb, lpicols[c]->ub, lpicols[c]->primsol, lpicols[c]->redcost,
14485  SCIPlpIsFeasGE(set, lp, lpicols[c]->primsol, lpicols[c]->lb),
14486  SCIPlpIsFeasLE(set, lp, lpicols[c]->primsol, lpicols[c]->ub),
14487  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14488  !SCIPlpIsFeasGT(set, lp, lpicols[c]->primsol, lpicols[c]->lb) || !SCIPsetIsDualfeasPositive(set, lpicols[c]->redcost),
14489  !SCIPlpIsFeasLT(set, lp, lpicols[c]->primsol, lpicols[c]->ub) || !SCIPsetIsDualfeasNegative(set, lpicols[c]->redcost),
14490  dualfeasible != NULL ? stilldualfeasible : TRUE);
14491  }
14492 
14493  /* we intentionally use an exact positive/negative check because ignoring small reduced cost values may lead to a
14494  * wrong bound value; if the corresponding bound is +/-infinity, we use zero reduced cost (if stilldualfeasible is
14495  * TRUE, we are in the case that the reduced cost is tiny with wrong sign)
14496  */
14497  if( stilldualfeasible )
14498  {
14499  if( lpicols[c]->redcost > 0.0 && !SCIPsetIsInfinity(set, -lpicols[c]->lb) )
14500  dualbound += (lpicols[c]->redcost * lpicols[c]->lb);
14501  else if( lpicols[c]->redcost < 0.0 && !SCIPsetIsInfinity(set, lpicols[c]->ub) )
14502  dualbound += (lpicols[c]->redcost * lpicols[c]->ub);
14503  }
14504  }
14505 
14506  /* copy dual solution and activities into rows */
14507  for( r = 0; r < nlpirows; ++r )
14508  {
14509  assert( 0 <= rstat[r] && rstat[r] < 4 );
14510  lpirows[r]->dualsol = dualsol[r];
14511 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14512  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14513 #else
14514  /* calculate row activity if invalid */
14515  if( lpirows[r]->validactivitylp != stat->lpcount )
14516  SCIProwRecalcLPActivity(lpirows[r], stat);
14517 #endif
14518  lpirows[r]->basisstatus = (unsigned int) rstat[r]; /*lint !e732*/
14519  lpirows[r]->validactivitylp = lpcount;
14520  if( stillprimalfeasible )
14521  {
14522  stillprimalfeasible =
14523  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs))
14524  && (SCIPsetIsInfinity(set, lpirows[r]->rhs) || SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs));
14525  }
14526  if( lp->lastlpalgo == SCIP_LPALGO_BARRIER )
14527  {
14528  double compslack;
14529 
14530  /* complementary slackness in barrier solutions is measured as product of primal slack and dual multiplier;
14531  * we use a slack of at most 1, because otherwise we multiply by something like SCIPinfinity() for unbounded
14532  * variables, which would magnify even the tiniest violation in the dual multiplier
14533  */
14534  if( stilldualfeasible )
14535  {
14536  compslack = MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol;
14537  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, compslack);
14538  }
14539  if( stilldualfeasible )
14540  {
14541  compslack = MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol;
14542  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, compslack);
14543  }
14544 
14545  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g]: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14546  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->activity, lpirows[r]->dualsol,
14547  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14548  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14549  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14550  !SCIPsetIsDualfeasPositive(set, MIN((lpirows[r]->activity - lpirows[r]->lhs), 1.0) * lpirows[r]->dualsol),
14551  !SCIPsetIsDualfeasNegative(set, MIN((lpirows[r]->rhs - lpirows[r]->activity), 1.0) * lpirows[r]->dualsol),
14552  dualfeasible != NULL ? stilldualfeasible : TRUE);
14553  }
14554  else
14555  {
14556  /* complementary slackness means that if the activity of a row is not at its left-hand or right-hand side,
14557  * its dual multiplier must be non-positive or non-negative, respectively; in particular, if the activity is
14558  * strictly within left-hand and right-hand side, its dual multiplier must be zero
14559  */
14560  if( stilldualfeasible &&
14561  (SCIPsetIsInfinity(set, -lpirows[r]->lhs) || SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs)) )
14562  stilldualfeasible = !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol);
14563  if( stilldualfeasible &&
14564  (SCIPsetIsInfinity(set,lpirows[r]->rhs) || SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs)) )
14565  stilldualfeasible = !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol);
14566 
14567  SCIPsetDebugMsg(set, " row <%s> [%.9g,%.9g] + %.9g: activity=%.9f, dualsol=%.9f, pfeas=%u/%u(%u), dfeas=%d/%d(%u)\n",
14568  lpirows[r]->name, lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, lpirows[r]->activity, lpirows[r]->dualsol,
14569  SCIPlpIsFeasGE(set, lp, lpirows[r]->activity, lpirows[r]->lhs),
14570  SCIPlpIsFeasLE(set, lp, lpirows[r]->activity, lpirows[r]->rhs),
14571  primalfeasible != NULL ? stillprimalfeasible : TRUE,
14572  !SCIPlpIsFeasGT(set, lp, lpirows[r]->activity, lpirows[r]->lhs) || !SCIPsetIsDualfeasPositive(set, lpirows[r]->dualsol),
14573  !SCIPlpIsFeasLT(set, lp, lpirows[r]->activity, lpirows[r]->rhs) || !SCIPsetIsDualfeasNegative(set, lpirows[r]->dualsol),
14574  dualfeasible != NULL ? stilldualfeasible : TRUE);
14575  }
14576 
14577  /* we intentionally use an exact positive/negative check because ignoring small dual multipliers may lead to a
14578  * wrong bound value; if the corresponding side is +/-infinity, we use a zero dual multiplier (if
14579  * stilldualfeasible is TRUE, we are in the case that the dual multiplier is tiny with wrong sign)
14580  */
14581  if( stilldualfeasible )
14582  {
14583  if( lpirows[r]->dualsol > 0.0 && !SCIPsetIsInfinity(set, -lpirows[r]->lhs) )
14584  dualbound += (lpirows[r]->dualsol * (lpirows[r]->lhs - lpirows[r]->constant));
14585  else if( lpirows[r]->dualsol < 0.0 && !SCIPsetIsInfinity(set, lpirows[r]->rhs) )
14586  dualbound += (lpirows[r]->dualsol * (lpirows[r]->rhs - lpirows[r]->constant));
14587  }
14588  }
14589 
14590  /* if the objective value returned by the LP solver is smaller than the internally computed primal bound, then we
14591  * declare the solution primal infeasible; we assume primalbound and lp->lpobjval to be equal if they are both +/-
14592  * infinity
14593  */
14594  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14595  if( stillprimalfeasible && !(SCIPsetIsInfinity(set, primalbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14596  && !(SCIPsetIsInfinity(set, -primalbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14597  {
14598  stillprimalfeasible = SCIPsetIsFeasLE(set, primalbound, lp->lpobjval);
14599  SCIPsetDebugMsg(set, " primalbound=%.9f, lpbound=%.9g, pfeas=%u(%u)\n", primalbound, lp->lpobjval,
14600  SCIPsetIsFeasLE(set, primalbound, lp->lpobjval), primalfeasible != NULL ? stillprimalfeasible : TRUE);
14601  }
14602 
14603  /* if the objective value returned by the LP solver is smaller than the internally computed dual bound, we declare
14604  * the solution dual infeasible; we assume dualbound and lp->lpobjval to be equal if they are both +/- infinity
14605  */
14606  /**@todo alternatively, if otherwise the LP solution is feasible, we could simply update the objective value */
14607  if( stilldualfeasible && !(SCIPsetIsInfinity(set, dualbound) && SCIPsetIsInfinity(set, lp->lpobjval))
14608  && !(SCIPsetIsInfinity(set, -dualbound) && SCIPsetIsInfinity(set, -lp->lpobjval)) )
14609  {
14610  stilldualfeasible = SCIPsetIsFeasGE(set, dualbound, lp->lpobjval);
14611  SCIPsetDebugMsg(set, " dualbound=%.9f, lpbound=%.9g, dfeas=%u(%u)\n", dualbound, lp->lpobjval,
14612  SCIPsetIsFeasGE(set, dualbound, lp->lpobjval), dualfeasible != NULL ? stilldualfeasible : TRUE);
14613  }
14614 
14615  if( primalfeasible != NULL )
14616  *primalfeasible = stillprimalfeasible;
14617  if( dualfeasible != NULL )
14618  *dualfeasible = stilldualfeasible;
14619 
14620  /* free temporary memory */
14621  SCIPsetFreeBufferArray(set, &rstat);
14622  SCIPsetFreeBufferArray(set, &cstat);
14623  SCIPsetFreeBufferArray(set, &redcost);
14624 #ifdef SCIP_USE_LPSOLVER_ACTIVITY
14625  SCIPsetFreeBufferArray(set, &activity);
14626 #endif
14627  SCIPsetFreeBufferArray(set, &dualsol);
14628  SCIPsetFreeBufferArray(set, &primsol);
14629 
14630  return SCIP_OKAY;
14631 }
14632 
14633 /** stores LP solution with infinite objective value in the columns and rows */
14635  SCIP_LP* lp, /**< current LP data */
14636  SCIP_SET* set, /**< global SCIP settings */
14637  SCIP_STAT* stat, /**< problem statistics */
14638  SCIP_Bool* primalfeasible, /**< pointer to store whether the solution is primal feasible, or NULL */
14639  SCIP_Bool* rayfeasible /**< pointer to store whether the primal ray is a feasible unboundedness proof, or NULL */
14640  )
14641 {
14642  SCIP_COL** lpicols;
14643  SCIP_ROW** lpirows;
14644  SCIP_Real* primsol;
14645  SCIP_Real* activity;
14646  SCIP_Real* ray;
14647  SCIP_Real rayobjval;
14648  SCIP_Real rayscale;
14649  SCIP_Longint lpcount;
14650  SCIP_COL* col;
14651  int nlpicols;
14652  int nlpirows;
14653  int c;
14654  int r;
14655 
14656  assert(lp != NULL);
14657  assert(lp->flushed);
14658  assert(lp->solved);
14659  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14660  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14661  assert(set != NULL);
14662  assert(stat != NULL);
14663  assert(lp->validsollp <= stat->lpcount);
14664 
14665  if( primalfeasible != NULL )
14666  *primalfeasible = TRUE;
14667  if( rayfeasible != NULL )
14668  *rayfeasible = TRUE;
14669 
14670  /* check if the values are already calculated */
14671  if( lp->validsollp == stat->lpcount )
14672  return SCIP_OKAY;
14673  lp->validsollp = stat->lpcount;
14674 
14675  /* check if the LP solver is able to provide a primal unbounded ray */
14676  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14677  {
14678  SCIPerrorMessage("LP solver has no primal ray to prove unboundedness.\n");
14679  return SCIP_LPERROR;
14680  }
14681 
14682  SCIPsetDebugMsg(set, "getting new unbounded LP solution %" SCIP_LONGINT_FORMAT "\n", stat->lpcount);
14683 
14684  /* get temporary memory */
14685  SCIP_CALL( SCIPsetAllocBufferArray(set, &primsol, lp->nlpicols) );
14686  SCIP_CALL( SCIPsetAllocBufferArray(set, &activity, lp->nlpirows) );
14687  SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, lp->nlpicols) );
14688 
14689  /* get primal unbounded ray */
14690  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, ray) );
14691 
14692  lpicols = lp->lpicols;
14693  lpirows = lp->lpirows;
14694  nlpicols = lp->nlpicols;
14695  nlpirows = lp->nlpirows;
14696  lpcount = stat->lpcount;
14697 
14698  /* calculate the objective value decrease of the ray and heuristically try to construct primal solution */
14699  rayobjval = 0.0;
14700  for( c = 0; c < nlpicols; ++c )
14701  {
14702  assert(lpicols[c] != NULL);
14703  assert(lpicols[c]->var != NULL);
14704 
14705  col = lpicols[c];
14706 
14707  /* there should only be a nonzero value in the ray if there is no finite bound in this direction */
14708  if( rayfeasible != NULL )
14709  {
14710  *rayfeasible = *rayfeasible
14711  && (!SCIPsetIsNegative(set, ray[c]) || SCIPsetIsInfinity(set, -col->lb))
14712  && (!SCIPsetIsPositive(set, ray[c]) || SCIPsetIsInfinity(set, col->ub));
14713  }
14714 
14715  if( ! SCIPsetIsZero(set, ray[c]) )
14716  rayobjval += ray[c] * col->obj;
14717 
14718  /* Many LP solvers cannot directly provide a feasible solution if they detected unboundedness. We therefore first
14719  * heuristically try to construct a primal solution.
14720  */
14721  primsol[c] = 0.0;
14722  if( SCIPsetIsFeasZero(set, ray[c]) )
14723  {
14724  /* if the ray component is 0, we try to satisfy as many rows as possible */
14725  if( SCIPvarGetNLocksDown(col->var) == 0 && ! SCIPsetIsInfinity(set, -col->lb) )
14726  primsol[c] = col->lb;
14727  else if( SCIPvarGetNLocksUp(col->var) == 0 && ! SCIPsetIsInfinity(set, col->ub) )
14728  primsol[c] = col->ub;
14729  }
14730 
14731  /* make sure we respect the bounds */
14732  primsol[c] = MAX(primsol[c], col->lb);
14733  primsol[c] = MIN(primsol[c], col->ub);
14734 
14735  assert( SCIPlpIsFeasGE(set, lp, primsol[c], col->lb) && SCIPlpIsFeasLE(set, lp, primsol[c], col->ub) );
14736  }
14737 
14738  /* check feasibility of heuristic primal solution */
14739  for( r = 0; r < nlpirows; ++r )
14740  {
14741  SCIP_Real act = 0.0;
14742  SCIP_ROW* row;
14743 
14744  row = lpirows[r];
14745  assert( row != NULL );
14746 
14747  for( c = 0; c < row->nlpcols; ++c )
14748  {
14749  col = row->cols[c];
14750 
14751  assert( col != NULL );
14752  assert( col->lppos >= 0 );
14753  assert( row->linkpos[c] >= 0 );
14754  assert( primsol[col->lppos] < SCIP_INVALID );
14755 
14756  act += row->vals[c] * primsol[col->lppos];
14757  }
14758 
14759  if( row->nunlinked > 0 )
14760  {
14761  for( c = row->nlpcols; c < row->len; ++c )
14762  {
14763  col = row->cols[c];
14764  assert( col != NULL );
14765 
14766  if( col->lppos >= 0 )
14767  act += row->vals[c] * primsol[col->lppos];
14768  }
14769  }
14770 
14771  /* check feasibility */
14772  if( (! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, act, row->lhs) ) ||
14773  (! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, act, row->rhs) ) )
14774  break;
14775  }
14776 
14777  /* if heuristic primal solution is not feasible, try to obtain solution from LPI */
14778  if( r < nlpirows )
14779  {
14780  /* get primal feasible point */
14781  SCIP_CALL( SCIPlpiGetSol(lp->lpi, NULL, primsol, NULL, NULL, NULL) );
14782 
14783  /* check bounds of primal solution */
14784  if( primalfeasible != NULL )
14785  {
14786  assert( *primalfeasible );
14787  for( c = 0; c < nlpicols; ++c )
14788  {
14789  assert( lpicols[c] != NULL );
14790  assert( lpicols[c]->var != NULL );
14791 
14792  /* check whether primal solution satisfies the bounds; note that we also ensure that the primal
14793  * solution is within SCIP's infinity bounds; otherwise the rayscale below is not well-defined */
14794  if( SCIPsetIsInfinity(set, REALABS(primsol[c])) || SCIPlpIsFeasLT(set, lp, primsol[c], lpicols[c]->lb) ||
14795  SCIPlpIsFeasGT(set, lp, primsol[c], lpicols[c]->ub) )
14796  {
14797  *primalfeasible = FALSE;
14798  break;
14799  }
14800  }
14801  }
14802  }
14803 
14804  /* compute activity and check feasibility of primal solution and ray */
14805  for( r = 0; r < nlpirows; ++r )
14806  {
14807  SCIP_Real primact = 0.0;
14808  SCIP_Real rayact = 0.0;
14809  SCIP_ROW* row;
14810 
14811  row = lpirows[r];
14812  assert( row != NULL );
14813 
14814  for( c = 0; c < row->nlpcols; ++c )
14815  {
14816  col = row->cols[c];
14817 
14818  assert( col != NULL );
14819  assert( col->lppos >= 0 );
14820  assert( row->linkpos[c] >= 0 );
14821  assert( primsol[col->lppos] < SCIP_INVALID );
14822 
14823  primact += row->vals[c] * primsol[col->lppos];
14824  rayact += row->vals[c] * ray[col->lppos];
14825  }
14826 
14827  if( row->nunlinked > 0 )
14828  {
14829  for( c = row->nlpcols; c < row->len; ++c )
14830  {
14831  col = row->cols[c];
14832  assert( col != NULL );
14833 
14834  if( col->lppos >= 0 )
14835  {
14836  primact += row->vals[c] * primsol[col->lppos];
14837  rayact += row->vals[c] * ray[col->lppos];
14838  }
14839  }
14840  }
14841 
14842  /* check feasibility of primal solution */
14843  if( primalfeasible != NULL && *primalfeasible )
14844  {
14845  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, primact, row->lhs) ) ||
14846  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, primact, row->rhs) ) )
14847  *primalfeasible = FALSE;
14848  }
14849 
14850  /* check feasibility of ray */
14851  if( rayfeasible != NULL && *rayfeasible )
14852  {
14853  if(( ! SCIPsetIsInfinity(set, -row->lhs) && SCIPlpIsFeasLT(set, lp, rayact, 0.0) ) ||
14854  ( ! SCIPsetIsInfinity(set, row->rhs) && SCIPlpIsFeasGT(set, lp, rayact, 0.0) ) )
14855  *rayfeasible = FALSE;
14856  }
14857 
14858  /* store activity of primal solution */
14859  activity[r] = primact;
14860  }
14861 
14862  if( primalfeasible != NULL && !(*primalfeasible) )
14863  {
14864  /* if the finite point is already infeasible, we do not have to add the ray */
14865  rayscale = 0.0;
14866  }
14867  else if( rayfeasible != NULL && !(*rayfeasible) )
14868  {
14869  /* if the ray is already infeasible (due to numerics), we do not want to add the ray */
14870  rayscale = 0.0;
14871  }
14872  else if( !SCIPsetIsNegative(set, rayobjval) )
14873  {
14874  /* due to numerical problems, the objective of the ray might be nonnegative
14875  *
14876  * @todo How to check for negative objective value here?
14877  */
14878  if( rayfeasible != NULL )
14879  *rayfeasible = FALSE;
14880 
14881  rayscale = 0.0;
14882  }
14883  else
14884  {
14885  assert(rayobjval != 0.0);
14886 
14887  /* scale the ray, such that the resulting point has infinite objective value */
14888  rayscale = -2.0 * SCIPsetInfinity(set) / rayobjval;
14889  assert(SCIPsetIsFeasPositive(set, rayscale));
14890 
14891  /* ensure that unbounded point does not violate the bounds of the variables */
14892  for( c = 0; c < nlpicols; ++c )
14893  {
14894  if( SCIPsetIsPositive(set, ray[c]) )
14895  {
14896  if( !SCIPsetIsInfinity(set, primsol[c]) )
14897  rayscale = MIN(rayscale, (lpicols[c]->ub - primsol[c]) / ray[c]);
14898  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14899  else
14900  {
14901  assert(SCIPsetIsInfinity(set, lpicols[c]->ub));
14902  rayscale = MIN(rayscale, 1.0 / ray[c]);
14903  }
14904  }
14905  else if( SCIPsetIsNegative(set, ray[c]) )
14906  {
14907  if( !SCIPsetIsInfinity(set, -primsol[c]) )
14908  rayscale = MIN(rayscale, (lpicols[c]->lb - primsol[c]) / ray[c]);
14909  /* if primsol is infinity, as well as the bound, don't scale the ray to 0 */
14910  else
14911  {
14912  assert(SCIPsetIsInfinity(set, -lpicols[c]->lb));
14913  rayscale = MIN(rayscale, -1.0 / ray[c]);
14914  }
14915  }
14916 
14917  assert(SCIPsetIsFeasPositive(set, rayscale));
14918  }
14919  }
14920 
14921  SCIPsetDebugMsg(set, "unbounded LP solution: rayobjval=%f, rayscale=%f\n", rayobjval, rayscale);
14922 
14923  /* calculate the unbounded point: x' = x + rayscale * ray */
14924  /* Note: We do not check the feasibility of the unbounded solution, because it will likely be infeasible due to the
14925  * typically large values in scaling. */
14926  for( c = 0; c < nlpicols; ++c )
14927  {
14928  if( SCIPsetIsZero(set, ray[c]) )
14929  lpicols[c]->primsol = primsol[c];
14930  else
14931  {
14932  SCIP_Real primsolval;
14933  primsolval = primsol[c] + rayscale * ray[c];
14934  lpicols[c]->primsol = MAX(-SCIPsetInfinity(set), MIN(SCIPsetInfinity(set), primsolval)); /*lint !e666*/
14935  }
14936  lpicols[c]->redcost = SCIP_INVALID;
14937  lpicols[c]->validredcostlp = -1;
14938  }
14939 
14940  /* transfer solution */
14941  for( r = 0; r < nlpirows; ++r )
14942  {
14943  lpirows[r]->dualsol = SCIP_INVALID;
14944  lpirows[r]->activity = activity[r] + lpirows[r]->constant;
14945  lpirows[r]->validactivitylp = lpcount;
14946  }
14947 
14948  /* free temporary memory */
14949  SCIPsetFreeBufferArray(set, &ray);
14950  SCIPsetFreeBufferArray(set, &activity);
14951  SCIPsetFreeBufferArray(set, &primsol);
14952 
14953  return SCIP_OKAY;
14954 }
14955 
14956 /** returns primal ray proving the unboundedness of the current LP */
14958  SCIP_LP* lp, /**< current LP data */
14959  SCIP_SET* set, /**< global SCIP settings */
14960  SCIP_Real* ray /**< array for storing primal ray values, they are stored w.r.t. the problem index of the variables,
14961  * so the size of this array should be at least number of active variables
14962  * (all entries have to be initialized to 0 before) */
14963  )
14964 {
14965  SCIP_COL** lpicols;
14966  SCIP_Real* lpiray;
14967  SCIP_VAR* var;
14968  int nlpicols;
14969  int c;
14970 
14971  assert(lp != NULL);
14972  assert(set != NULL);
14973  assert(ray != NULL);
14974  assert(lp->flushed);
14975  assert(lp->solved);
14976  assert(lp->lpsolstat == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
14977  assert(SCIPsetIsInfinity(set, -lp->lpobjval));
14978 
14979  /* check if the LP solver is able to provide a primal unbounded ray */
14980  if( !SCIPlpiHasPrimalRay(lp->lpi) )
14981  {
14982  SCIPerrorMessage("LP solver has no primal ray for unbounded LP\n");
14983  return SCIP_LPERROR;
14984  }
14985 
14986  /* get temporary memory */
14987  SCIP_CALL( SCIPsetAllocBufferArray(set, &lpiray, lp->nlpicols) );
14988 
14989  SCIPsetDebugMsg(set, "getting primal ray values\n");
14990 
14991  /* get primal unbounded ray */
14992  SCIP_CALL( SCIPlpiGetPrimalRay(lp->lpi, lpiray) );
14993 
14994  lpicols = lp->lpicols;
14995  nlpicols = lp->nlpicols;
14996 
14997  /* store the ray values of active problem variables */
14998  for( c = 0; c < nlpicols; c++ )
14999  {
15000  assert(lpicols[c] != NULL);
15001 
15002  var = lpicols[c]->var;
15003  assert(var != NULL);
15004  assert(SCIPvarGetProbindex(var) != -1);
15005  ray[SCIPvarGetProbindex(var)] = lpiray[c];
15006  }
15007 
15008  SCIPsetFreeBufferArray(set, &lpiray);
15009 
15010  return SCIP_OKAY;
15011 }
15012 
15013 /** stores the dual Farkas multipliers for infeasibility proof in rows. besides, the proof is checked for validity if
15014  * lp/checkfarkas = TRUE.
15015  *
15016  * @note the check will not be performed if @p valid is NULL.
15017  */
15019  SCIP_LP* lp, /**< current LP data */
15020  SCIP_SET* set, /**< global SCIP settings */
15021  SCIP_STAT* stat, /**< problem statistics */
15022  SCIP_Bool* valid /**< pointer to store whether the Farkas proof is valid or NULL */
15023  )
15024 {
15025  SCIP_COL** lpicols;
15026  SCIP_ROW** lpirows;
15027  SCIP_Real* dualfarkas;
15028  SCIP_Real* farkascoefs;
15029  SCIP_Real farkaslhs;
15030  SCIP_Real maxactivity;
15031  SCIP_Bool checkfarkas;
15032  int nlpicols;
15033  int nlpirows;
15034  int c;
15035  int r;
15036 
15037  assert(lp != NULL);
15038  assert(lp->flushed);
15039  assert(lp->solved);
15040  assert(lp->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE);
15041  assert(set != NULL);
15042  assert(stat != NULL);
15043  assert(lp->validfarkaslp <= stat->lpcount);
15044 
15045  if( valid != NULL )
15046  *valid = TRUE;
15047 
15048  /* check if the values are already calculated */
15049  if( lp->validfarkaslp == stat->lpcount )
15050  return SCIP_OKAY;
15051  lp->validfarkaslp = stat->lpcount;
15052 
15053  farkascoefs = NULL;
15054  maxactivity = 0.0;
15055  farkaslhs = 0.0;
15056 
15057  checkfarkas = (set->lp_checkfarkas && valid != NULL);
15058 
15059  /* get temporary memory */
15060  SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, lp->nlpirows) );
15061 
15062  if( checkfarkas )
15063  {
15064  SCIP_CALL( SCIPsetAllocBufferArray(set, &farkascoefs, lp->nlpicols) );
15065  BMSclearMemoryArray(farkascoefs, lp->nlpicols);
15066  }
15067 
15068  /* get dual Farkas infeasibility proof */
15069  SCIP_CALL( SCIPlpiGetDualfarkas(lp->lpi, dualfarkas) );
15070 
15071  lpicols = lp->lpicols;
15072  lpirows = lp->lpirows;
15073  nlpicols = lp->nlpicols;
15074  nlpirows = lp->nlpirows;
15075 
15076  /* store infeasibility proof in rows */
15077  SCIPsetDebugMsg(set, "LP is infeasible:\n");
15078  for( r = 0; r < nlpirows; ++r )
15079  {
15080  SCIPsetDebugMsg(set, " row <%s>: dualfarkas=%f\n", lpirows[r]->name, dualfarkas[r]);
15081  lpirows[r]->dualfarkas = dualfarkas[r];
15082  lpirows[r]->dualsol = SCIP_INVALID;
15083  lpirows[r]->activity = 0.0;
15084  lpirows[r]->validactivitylp = -1L;
15085  lpirows[r]->basisstatus = (unsigned int) SCIP_BASESTAT_BASIC;
15086 
15087  if( checkfarkas )
15088  {
15089  assert(farkascoefs != NULL);
15090 
15091  /* the infeasibility proof would be invalid if
15092  * (i) dualfarkas[r] > 0 and lhs = -inf
15093  * (ii) dualfarkas[r] < 0 and rhs = inf
15094  * however, due to numerics we accept slightly negative / positive values
15095  */
15096  if( (SCIPsetIsDualfeasGT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15097  || (SCIPsetIsDualfeasLT(set, dualfarkas[r], 0.0) && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15098  {
15099  SCIPsetDebugMsg(set, "farkas proof is invalid: row <%s>[lhs=%g,rhs=%g,c=%g] has multiplier %g\n",
15100  SCIProwGetName(lpirows[r]), lpirows[r]->lhs, lpirows[r]->rhs, lpirows[r]->constant, dualfarkas[r]);
15101 
15102  if( valid != NULL )
15103  *valid = FALSE;
15104 
15105  goto TERMINATE;
15106  }
15107 
15108  /* dual multipliers, for which the corresponding row side in infinite, are treated as zero if they are zero
15109  * within tolerances (see above) but slighty positive / negative
15110  */
15111  if( (dualfarkas[r] > 0.0 && SCIPsetIsInfinity(set, -lpirows[r]->lhs))
15112  || (dualfarkas[r] < 0.0 && SCIPsetIsInfinity(set, lpirows[r]->rhs)) )
15113  continue;
15114 
15115  /* iterate over all columns and scale with dual solution */
15116  for( c = 0; c < lpirows[r]->len; c++ )
15117  {
15118  int pos = SCIPcolGetLPPos(lpirows[r]->cols[c]);
15119 
15120  if( pos == -1 )
15121  continue;
15122 
15123  assert(pos >= 0 && pos < nlpicols);
15124 
15125  farkascoefs[pos] += dualfarkas[r] * lpirows[r]->vals[c];
15126  }
15127 
15128  /* the row contributes with its left-hand side to the proof */
15129  if( dualfarkas[r] > 0.0 )
15130  {
15131  assert(!SCIPsetIsInfinity(set, -lpirows[r]->lhs));
15132 
15133  farkaslhs += dualfarkas[r] * (lpirows[r]->lhs - lpirows[r]->constant);
15134  }
15135  /* the row contributes with its right-hand side to the proof */
15136  else if( dualfarkas[r] < 0.0 )
15137  {
15138  assert(!SCIPsetIsInfinity(set, lpirows[r]->rhs));
15139 
15140  farkaslhs += dualfarkas[r] * (lpirows[r]->rhs - lpirows[r]->constant);
15141  }
15142  }
15143  }
15144 
15145  /* set columns as invalid */
15146  for( c = 0; c < nlpicols; ++c )
15147  {
15148  lpicols[c]->primsol = SCIP_INVALID;
15149  lpicols[c]->redcost = SCIP_INVALID;
15150  lpicols[c]->validredcostlp = -1L;
15151  lpicols[c]->validfarkaslp = -1L;
15152 
15153  if( checkfarkas )
15154  {
15155  assert(farkascoefs != NULL);
15156  assert(SCIPcolGetLPPos(lpicols[c]) == c);
15157 
15158  /* skip coefficients that are too close to zero */
15159  if( SCIPsetIsFeasZero(set, farkascoefs[c]) )
15160  continue;
15161 
15162  /* calculate the maximal activity */
15163  if( farkascoefs[c] > 0.0 )
15164  maxactivity += farkascoefs[c] * SCIPcolGetUb(lpicols[c]);
15165  else
15166  maxactivity += farkascoefs[c] * SCIPcolGetLb(lpicols[c]);
15167  }
15168  }
15169 
15170  /* check whether the farkasproof is valid
15171  * due to numerics, it might happen that the left-hand side of the aggregation is larger/smaller or equal than +/- infinity.
15172  * in that case, we declare the Farkas proof to be invalid.
15173  */
15174  if( checkfarkas && (SCIPsetIsInfinity(set, REALABS(farkaslhs)) || SCIPsetIsGE(set, maxactivity, farkaslhs)) )
15175  {
15176  SCIPsetDebugMsg(set, "farkas proof is invalid: maxactivity=%.12f, lhs=%.12f\n", maxactivity, farkaslhs);
15177 
15178  if( valid != NULL )
15179  *valid = FALSE;
15180  }
15181 
15182  TERMINATE:
15183  /* free temporary memory */
15184  if( checkfarkas )
15185  SCIPsetFreeBufferArray(set, &farkascoefs);
15186 
15187  SCIPsetFreeBufferArray(set, &dualfarkas);
15188 
15189  return SCIP_OKAY;
15190 }
15191 
15192 /** get number of iterations used in last LP solve */
15194  SCIP_LP* lp, /**< current LP data */
15195  int* iterations /**< pointer to store the iteration count */
15196  )
15197 {
15198  assert(lp != NULL);
15199 
15200  SCIP_CALL( SCIPlpiGetIterations(lp->lpi, iterations) );
15201 
15202  return SCIP_OKAY;
15203 }
15204 
15205 /** increases age of columns with solution value 0.0 and basic rows with activity not at its bounds,
15206  * resets age of non-zero columns and sharp rows
15207  */
15209  SCIP_LP* lp, /**< current LP data */
15210  SCIP_STAT* stat /**< problem statistics */
15211  )
15212 {
15213  SCIP_COL** lpicols;
15214  SCIP_ROW** lpirows;
15215  int nlpicols;
15216  int nlpirows;
15217  int c;
15218  int r;
15219 
15220  assert(lp != NULL);
15221  assert(lp->flushed);
15222  assert(lp->solved);
15223  assert(lp->nlpicols == lp->ncols);
15224  assert(lp->nlpirows == lp->nrows);
15225  assert(stat != NULL);
15226  assert(lp->validsollp == stat->lpcount);
15227 
15228  SCIPdebugMessage("updating LP ages\n");
15229 
15230  lpicols = lp->lpicols;
15231  lpirows = lp->lpirows;
15232  nlpicols = lp->nlpicols;
15233  nlpirows = lp->nlpirows;
15234 
15235  for( c = 0; c < nlpicols; ++c )
15236  {
15237  assert(lpicols[c] == lp->cols[c]);
15238  if( lpicols[c]->primsol == 0.0 ) /* non-basic columns to remove are exactly at 0.0 */
15239  lpicols[c]->age++;
15240  else
15241  lpicols[c]->age = 0;
15242  /*SCIPstatDebugMsg(stat, " -> col <%s>: primsol=%f, age=%d\n",
15243  SCIPvarGetName(lpicols[c]->var), lpicols[c]->primsol, lpicols[c]->age);*/
15244  }
15245 
15246  for( r = 0; r < nlpirows; ++r )
15247  {
15248  lpirows[r]->nlpsaftercreation++;
15249  assert(lpirows[r] == lp->rows[r]);
15250 
15251  if( lpirows[r]->dualsol == 0.0 ) /* basic rows to remove are exactly at 0.0 */
15252  {
15253  lpirows[r]->age++;
15254  }
15255  else
15256  {
15257  lpirows[r]->activeinlpcounter++;
15258  lpirows[r]->age = 0;
15259  }
15260  /*debugMsg(scip, " -> row <%s>: activity=%f, age=%d\n", lpirows[r]->name, lpirows[r]->activity, lpirows[r]->age);*/
15261  }
15262 
15263  return SCIP_OKAY;
15264 }
15265 
15266 /* deletes the marked columns from the LP and the LP interface */
15267 static
15269  SCIP_LP* lp, /**< current LP data */
15270  SCIP_SET* set, /**< global SCIP settings */
15271  int* coldstat /**< deletion status of columns: 1 if column should be deleted, 0 if not */
15272  )
15273 {
15274  SCIP_COL* col;
15275  int ncols;
15276  int c;
15277 
15278  assert(lp != NULL);
15279  assert(lp->flushed);
15280  assert(lp->ncols == lp->nlpicols);
15281  assert(!lp->diving);
15282  assert(coldstat != NULL);
15283  assert(lp->nlazycols <= lp->ncols);
15284 
15285  ncols = lp->ncols;
15286 
15287  /* delete columns in LP solver */
15288  SCIP_CALL( SCIPlpiDelColset(lp->lpi, coldstat) );
15289 
15290  /* update LP data respectively */
15291  for( c = 0; c < ncols; ++c )
15292  {
15293  col = lp->cols[c];
15294  assert(col != NULL);
15295  assert(col == lp->lpicols[c]);
15296  assert(coldstat[c] <= c);
15297  col->lppos = coldstat[c];
15298  if( coldstat[c] == -1 )
15299  {
15300  assert(col->removable);
15301 
15302  /* mark column to be deleted from the LPI, update column arrays of all linked rows, and update the objective
15303  * function vector norms
15304  */
15305  markColDeleted(col);
15306  colUpdateDelLP(col, set);
15307  lpUpdateObjNorms(lp, set, col->unchangedobj, 0.0);
15308  col->lpdepth = -1;
15309 
15310  lp->cols[c] = NULL;
15311  lp->lpicols[c] = NULL;
15312  lp->ncols--;
15313  lp->nremovablecols--;
15314  lp->nlpicols--;
15315  }
15316  else if( coldstat[c] < c )
15317  {
15318  assert(lp->cols[coldstat[c]] == NULL);
15319  assert(lp->lpicols[coldstat[c]] == NULL);
15320  lp->cols[coldstat[c]] = col;
15321  lp->lpicols[coldstat[c]] = col;
15322  lp->cols[coldstat[c]]->lppos = coldstat[c];
15323  lp->cols[coldstat[c]]->lpipos = coldstat[c];
15324  lp->cols[c] = NULL;
15325  lp->lpicols[c] = NULL;
15326  }
15327  }
15328 
15329  /* remove columns which are deleted from the lazy column array */
15330  c = 0;
15331  while( c < lp->nlazycols )
15332  {
15333  if( lp->lazycols[c]->lpipos < 0 )
15334  {
15335  lp->lazycols[c] = lp->lazycols[lp->nlazycols-1];
15336  lp->nlazycols--;
15337  }
15338  else
15339  c++;
15340  }
15341 
15342  /* mark LP to be unsolved */
15343  if( lp->ncols < ncols )
15344  {
15345  assert(lp->ncols == lp->nlpicols);
15346  assert(lp->nchgcols == 0);
15347  assert(lp->flushed);
15348 
15349  lp->lpifirstchgcol = lp->nlpicols;
15350 
15351  /* mark the current solution invalid */
15352  lp->solved = FALSE;
15353  lp->primalfeasible = FALSE;
15354  lp->primalchecked = FALSE;
15355  lp->lpobjval = SCIP_INVALID;
15357  }
15358 
15359  checkLazyColArray(lp, set);
15360  checkLinks(lp);
15361 
15362  return SCIP_OKAY;
15363 }
15364 
15365 /* deletes the marked rows from the LP and the LP interface */
15366 static
15368  SCIP_LP* lp, /**< current LP data */
15369  BMS_BLKMEM* blkmem, /**< block memory buffers */
15370  SCIP_SET* set, /**< global SCIP settings */
15371  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15372  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15373  int* rowdstat /**< deletion status of rows: 1 if row should be deleted, 0 if not */
15374  )
15375 {
15376  SCIP_ROW* row;
15377  int nrows;
15378  int r;
15379 
15380  assert(lp != NULL);
15381  assert(lp->flushed);
15382  assert(lp->nrows == lp->nlpirows);
15383  assert(!lp->diving);
15384  assert(rowdstat != NULL);
15385 
15386  nrows = lp->nrows;
15387 
15388  /* delete rows in LP solver */
15389  SCIP_CALL( SCIPlpiDelRowset(lp->lpi, rowdstat) );
15390 
15391  /* update LP data respectively */
15392  for( r = 0; r < nrows; ++r )
15393  {
15394  row = lp->rows[r];
15395  assert(row == lp->lpirows[r]);
15396  assert(rowdstat[r] <= r);
15397  assert(row != NULL);
15398  row->lppos = rowdstat[r];
15399  if( rowdstat[r] == -1 )
15400  {
15401  if( row->removable )
15402  lp->nremovablerows--;
15403 
15404  /* mark row to be deleted from the LPI and update row arrays of all linked columns */
15405  markRowDeleted(row);
15406  rowUpdateDelLP(row);
15407  row->lpdepth = -1;
15408 
15409  /* check, if row deletion events are tracked
15410  * if so, issue ROWDELETEDLP event
15411  */
15412  if( eventfilter->len > 0 && (eventfilter->eventmask & SCIP_EVENTTYPE_ROWDELETEDLP) != 0 )
15413  {
15414  SCIP_EVENT* event;
15415 
15416  SCIP_CALL( SCIPeventCreateRowDeletedLP(&event, blkmem, row) );
15417  SCIP_CALL( SCIPeventqueueAdd(eventqueue, blkmem, set, NULL, NULL, NULL, eventfilter, &event) );
15418  }
15419 
15420  SCIP_CALL( SCIProwRelease(&lp->lpirows[r], blkmem, set, lp) );
15421  SCIProwUnlock(lp->rows[r]);
15422  SCIP_CALL( SCIProwRelease(&lp->rows[r], blkmem, set, lp) );
15423  assert(lp->lpirows[r] == NULL);
15424  assert(lp->rows[r] == NULL);
15425  lp->nrows--;
15426  lp->nlpirows--;
15427  }
15428  else if( rowdstat[r] < r )
15429  {
15430  assert(lp->rows[rowdstat[r]] == NULL);
15431  assert(lp->lpirows[rowdstat[r]] == NULL);
15432  lp->rows[rowdstat[r]] = row;
15433  lp->lpirows[rowdstat[r]] = row;
15434  lp->rows[rowdstat[r]]->lppos = rowdstat[r];
15435  lp->rows[rowdstat[r]]->lpipos = rowdstat[r];
15436  lp->rows[r] = NULL;
15437  lp->lpirows[r] = NULL;
15438  }
15439  }
15440 
15441  /* mark LP to be unsolved */
15442  if( lp->nrows < nrows )
15443  {
15444  assert(lp->nrows == lp->nlpirows);
15445  assert(lp->nchgrows == 0);
15446  assert(lp->flushed);
15447 
15448  lp->lpifirstchgrow = lp->nlpirows;
15449 
15450  /* mark the current solution invalid */
15451  lp->solved = FALSE;
15452  lp->dualfeasible = FALSE;
15453  lp->dualchecked = FALSE;
15454  lp->lpobjval = SCIP_INVALID;
15456  }
15457 
15458  checkLinks(lp);
15459 
15460  return SCIP_OKAY;
15461 }
15462 
15463 /** removes all non-basic columns, that are too old, beginning with the given firstcol */
15464 static
15466  SCIP_LP* lp, /**< current LP data */
15467  SCIP_SET* set, /**< global SCIP settings */
15468  SCIP_STAT* stat, /**< problem statistics */
15469  int firstcol /**< first column to check for clean up */
15470  )
15471 {
15472  SCIP_COL** cols;
15473 #ifndef NDEBUG
15474  SCIP_COL** lpicols;
15475 #endif
15476  int* coldstat;
15477  int ncols;
15478  int ndelcols;
15479  int c;
15480 
15481  assert(lp != NULL);
15482  assert(lp->flushed);
15483  assert(lp->ncols == lp->nlpicols);
15484  assert(lp->nremovablecols <= lp->ncols);
15485  assert(!lp->diving);
15486  assert(set != NULL);
15487  assert(stat != NULL);
15488 
15489  if( lp->nremovablecols == 0 || set->lp_colagelimit == -1 || !lp->solisbasic )
15490  return SCIP_OKAY;
15491 
15492  ncols = lp->ncols;
15493  cols = lp->cols;
15494 #ifndef NDEBUG
15495  lpicols = lp->lpicols;
15496 #endif
15497 
15498  /* get temporary memory */
15499  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15500 
15501  /* mark obsolete columns to be deleted */
15502  ndelcols = 0;
15503  BMSclearMemoryArray(coldstat, ncols);
15504  for( c = firstcol; c < ncols; ++c )
15505  {
15506  assert(cols[c] == lpicols[c]);
15507  assert(cols[c]->lppos == c);
15508  assert(cols[c]->lpipos == c);
15509  if( cols[c]->removable
15510  && 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 */
15511  && cols[c]->age > set->lp_colagelimit
15513  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15514  {
15515  assert(cols[c]->primsol == 0.0);
15516  coldstat[c] = 1;
15517  ndelcols++;
15518  cols[c]->obsoletenode = stat->nnodes;
15519  SCIPsetDebugMsg(set, "removing obsolete col <%s>: primsol=%f, bounds=[%g,%g]\n",
15520  SCIPvarGetName(cols[c]->var), cols[c]->primsol, cols[c]->lb, cols[c]->ub);
15521  }
15522  }
15523 
15524  SCIPsetDebugMsg(set, "removing %d/%d obsolete columns from LP\n", ndelcols, ncols);
15525 
15526  /* delete the marked columns in the LP solver interface, update the LP respectively */
15527  if( ndelcols > 0 )
15528  {
15529  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15530  }
15531  assert(lp->ncols == ncols - ndelcols);
15532 
15533  /* release temporary memory */
15534  SCIPsetFreeBufferArray(set, &coldstat);
15535 
15536  return SCIP_OKAY;
15537 }
15538 
15539 /** removes all basic rows, that are too old, beginning with the given firstrow */
15540 static
15542  SCIP_LP* lp, /**< current LP data */
15543  BMS_BLKMEM* blkmem, /**< block memory buffers */
15544  SCIP_SET* set, /**< global SCIP settings */
15545  SCIP_STAT* stat, /**< problem statistics */
15546  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15547  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15548  int firstrow /**< first row to check for clean up */
15549  )
15550 {
15551  SCIP_ROW** rows;
15552 #ifndef NDEBUG
15553  SCIP_ROW** lpirows;
15554 #endif
15555  int* rowdstat;
15556  int nrows;
15557  int ndelrows;
15558  int r;
15559 
15560  assert(lp != NULL);
15561  assert(lp->flushed);
15562  assert(lp->nrows == lp->nlpirows);
15563  assert(lp->nremovablerows <= lp->nrows);
15564  assert(!lp->diving);
15565  assert(set != NULL);
15566  assert(stat != NULL);
15567 
15568  if( lp->nremovablerows == 0 || set->lp_rowagelimit == -1 || !lp->solisbasic )
15569  return SCIP_OKAY;
15570 
15571  nrows = lp->nrows;
15572  rows = lp->rows;
15573 #ifndef NDEBUG
15574  lpirows = lp->lpirows;
15575 #endif
15576 
15577  /* get temporary memory */
15578  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15579 
15580  /* mark obsolete rows to be deleted */
15581  ndelrows = 0;
15582  BMSclearMemoryArray(rowdstat, nrows);
15583  for( r = firstrow; r < nrows; ++r )
15584  {
15585  assert(rows[r] == lpirows[r]);
15586  assert(rows[r]->lppos == r);
15587  assert(rows[r]->lpipos == r);
15588  if( rows[r]->removable
15589  && 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 */
15590  && rows[r]->age > set->lp_rowagelimit
15592  {
15593  rowdstat[r] = 1;
15594  ndelrows++;
15595  rows[r]->obsoletenode = stat->nnodes;
15596  SCIPsetDebugMsg(set, "removing obsolete row <%s>: activity=%f, sides=[%g,%g]\n",
15597  rows[r]->name, rows[r]->activity, rows[r]->lhs, rows[r]->rhs);
15598  }
15599  }
15600 
15601  SCIPsetDebugMsg(set, "removing %d/%d obsolete rows from LP\n", ndelrows, nrows);
15602 
15603  /* delete the marked rows in the LP solver interface, update the LP respectively */
15604  if( ndelrows > 0 )
15605  {
15606  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15607  }
15608  assert(lp->nrows == nrows - ndelrows);
15609 
15610  /* release temporary memory */
15611  SCIPsetFreeBufferArray(set, &rowdstat);
15612 
15613  return SCIP_OKAY;
15614 }
15615 
15616 /** removes all non-basic columns and basic rows in the part of the LP created at the current node, that are too old */
15618  SCIP_LP* lp, /**< current LP data */
15619  BMS_BLKMEM* blkmem, /**< block memory buffers */
15620  SCIP_SET* set, /**< global SCIP settings */
15621  SCIP_STAT* stat, /**< problem statistics */
15622  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15623  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15624  )
15625 {
15626  assert(lp != NULL);
15627  assert(lp->solved);
15628  assert(!lp->diving);
15630  assert(set != NULL);
15631 
15632  SCIPsetDebugMsg(set, "removing obsolete columns starting with %d/%d, obsolete rows starting with %d/%d\n",
15633  lp->firstnewcol, lp->ncols, lp->firstnewrow, lp->nrows);
15634 
15635  if( lp->firstnewcol < lp->ncols )
15636  {
15637  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, lp->firstnewcol) );
15638  }
15639  if( lp->firstnewrow < lp->nrows )
15640  {
15641  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15642  }
15643 
15644  return SCIP_OKAY;
15645 }
15646 
15647 /** removes all non-basic columns and basic rows in whole LP, that are too old */
15649  SCIP_LP* lp, /**< current LP data */
15650  BMS_BLKMEM* blkmem, /**< block memory buffers */
15651  SCIP_SET* set, /**< global SCIP settings */
15652  SCIP_STAT* stat, /**< problem statistics */
15653  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15654  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15655  )
15656 {
15657  assert(lp != NULL);
15658  assert(lp->solved);
15659  assert(!lp->diving);
15661  assert(set != NULL);
15662 
15663  SCIPsetDebugMsg(set, "removing all obsolete columns and rows\n");
15664 
15665  if( 0 < lp->ncols )
15666  {
15667  SCIP_CALL( lpRemoveObsoleteCols(lp, set, stat, 0) );
15668  }
15669  if( 0 < lp->nrows )
15670  {
15671  SCIP_CALL( lpRemoveObsoleteRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15672  }
15673 
15674  return SCIP_OKAY;
15675 }
15676 
15677 /** removes all non-basic columns at 0.0 beginning with the given firstcol */
15678 static
15680  SCIP_LP* lp, /**< current LP data */
15681  SCIP_SET* set, /**< global SCIP settings */
15682  SCIP_STAT* stat, /**< problem statistics */
15683  int firstcol /**< first column to check for clean up */
15684  )
15685 {
15686  SCIP_COL** cols;
15687  SCIP_COL** lpicols;
15688  int* coldstat;
15689  int ncols;
15690  int ndelcols;
15691  int c;
15692 
15693  assert(lp != NULL);
15694  assert(lp->flushed);
15695  assert(lp->ncols == lp->nlpicols);
15696  assert(!lp->diving);
15697  assert(stat != NULL);
15698  assert(lp->validsollp == stat->lpcount);
15699  assert(0 <= firstcol && firstcol < lp->ncols);
15700 
15701  if( lp->nremovablecols == 0 || !lp->solisbasic )
15702  return SCIP_OKAY;
15703 
15704  ncols = lp->ncols;
15705  cols = lp->cols;
15706  lpicols = lp->lpicols;
15707 
15708  /* get temporary memory */
15709  SCIP_CALL( SCIPsetAllocBufferArray(set, &coldstat, ncols) );
15710 
15711  /* mark unused columns to be deleted */
15712  ndelcols = 0;
15713  BMSclearMemoryArray(coldstat, ncols);
15714  for( c = firstcol; c < ncols; ++c )
15715  {
15716  assert(cols[c] == lpicols[c]);
15717  assert(cols[c]->lppos == c);
15718  assert(cols[c]->lpipos == c);
15719  if( lpicols[c]->removable
15720  && (SCIP_BASESTAT)lpicols[c]->basisstatus != SCIP_BASESTAT_BASIC
15721  && lpicols[c]->primsol == 0.0 /* non-basic columns to remove are exactly at 0.0 */
15722  && SCIPsetIsZero(set, SCIPcolGetBestBound(cols[c])) ) /* bestbd != 0 -> column would be priced in next time */
15723  {
15724  coldstat[c] = 1;
15725  ndelcols++;
15726  }
15727  }
15728 
15729  SCIPsetDebugMsg(set, "removing %d/%d unused columns from LP\n", ndelcols, ncols);
15730 
15731  /* delete the marked columns in the LP solver interface, update the LP respectively */
15732  if( ndelcols > 0 )
15733  {
15734  SCIP_CALL( lpDelColset(lp, set, coldstat) );
15735  }
15736  assert(lp->ncols == ncols - ndelcols);
15737 
15738  /* release temporary memory */
15739  SCIPsetFreeBufferArray(set, &coldstat);
15740 
15741  return SCIP_OKAY;
15742 }
15743 
15744 /** removes all basic rows beginning with the given firstrow */
15745 static
15747  SCIP_LP* lp, /**< current LP data */
15748  BMS_BLKMEM* blkmem, /**< block memory buffers */
15749  SCIP_SET* set, /**< global SCIP settings */
15750  SCIP_STAT* stat, /**< problem statistics */
15751  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15752  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15753  int firstrow /**< first row to check for clean up */
15754  )
15755 {
15756 #ifndef NDEBUG
15757  SCIP_ROW** rows;
15758 #endif
15759  SCIP_ROW** lpirows;
15760  int* rowdstat;
15761  int nrows;
15762  int ndelrows;
15763  int r;
15764 
15765  assert(lp != NULL);
15766  assert(lp->flushed);
15767  assert(lp->ncols == lp->nlpicols);
15768  assert(lp->nrows == lp->nlpirows);
15769  assert(!lp->diving);
15770  assert(stat != NULL);
15771  assert(lp->validsollp == stat->lpcount);
15772  assert(0 <= firstrow && firstrow < lp->nrows);
15773 
15774  if( lp->nremovablerows == 0 || !lp->solisbasic )
15775  return SCIP_OKAY;
15776 
15777 #ifndef NDEBUG
15778  rows = lp->rows;
15779 #endif
15780  nrows = lp->nrows;
15781  lpirows = lp->lpirows;
15782 
15783  /* get temporary memory */
15784  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15785 
15786  /* mark unused rows to be deleted */
15787  ndelrows = 0;
15788  BMSclearMemoryArray(rowdstat, nrows);
15789  for( r = firstrow; r < nrows; ++r )
15790  {
15791  assert(rows[r] == lpirows[r]);
15792  assert(rows[r]->lppos == r);
15793  assert(rows[r]->lpipos == r);
15794  if( lpirows[r]->removable && (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC )
15795  {
15796  rowdstat[r] = 1;
15797  ndelrows++;
15798  }
15799  }
15800 
15801  SCIPsetDebugMsg(set, "removing %d/%d unused rows from LP\n", ndelrows, nrows);
15802 
15803  /* delete the marked rows in the LP solver interface, update the LP respectively */
15804  if( ndelrows > 0 )
15805  {
15806  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15807  }
15808  assert(lp->nrows == nrows - ndelrows);
15809 
15810  /* release temporary memory */
15811  SCIPsetFreeBufferArray(set, &rowdstat);
15812 
15813  return SCIP_OKAY;
15814 }
15815 
15816 /** removes all non-basic columns at 0.0 and basic rows in the part of the LP created at the current node */
15818  SCIP_LP* lp, /**< current LP data */
15819  BMS_BLKMEM* blkmem, /**< block memory buffers */
15820  SCIP_SET* set, /**< global SCIP settings */
15821  SCIP_STAT* stat, /**< problem statistics */
15822  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15823  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15824  SCIP_Bool root /**< are we at the root node? */
15825  )
15826 {
15827  SCIP_Bool cleanupcols;
15828  SCIP_Bool cleanuprows;
15829 
15830  assert(lp != NULL);
15831  assert(lp->solved);
15832  assert(!lp->diving);
15834  assert(set != NULL);
15835 
15836  /* check, if we want to clean up the columns and rows */
15837  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15838  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15839 
15840  SCIPsetDebugMsg(set, "removing unused columns starting with %d/%d (%u), unused rows starting with %d/%d (%u), LP algo: %d, basic sol: %u\n",
15841  lp->firstnewcol, lp->ncols, cleanupcols, lp->firstnewrow, lp->nrows, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15842 
15843  if( cleanupcols && lp->firstnewcol < lp->ncols )
15844  {
15845  SCIP_CALL( lpCleanupCols(lp, set, stat, lp->firstnewcol) );
15846  }
15847  if( cleanuprows && lp->firstnewrow < lp->nrows )
15848  {
15849  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, lp->firstnewrow) );
15850  }
15851 
15852  return SCIP_OKAY;
15853 }
15854 
15855 /** removes all non-basic columns at 0.0 and basic rows in the whole LP */
15857  SCIP_LP* lp, /**< current LP data */
15858  BMS_BLKMEM* blkmem, /**< block memory buffers */
15859  SCIP_SET* set, /**< global SCIP settings */
15860  SCIP_STAT* stat, /**< problem statistics */
15861  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15862  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
15863  SCIP_Bool root /**< are we at the root node? */
15864  )
15865 {
15866  SCIP_Bool cleanupcols;
15867  SCIP_Bool cleanuprows;
15868 
15869  assert(lp != NULL);
15870  assert(lp->solved);
15871  assert(!lp->diving);
15873  assert(set != NULL);
15874 
15875  /* check, if we want to clean up the columns and rows */
15876  cleanupcols = (root ? set->lp_cleanupcolsroot : set->lp_cleanupcols);
15877  cleanuprows = (root ? set->lp_cleanuprowsroot : set->lp_cleanuprows);
15878 
15879  SCIPsetDebugMsg(set, "removing all unused columns (%u) and rows (%u), LP algo: %d, basic sol: %u\n",
15880  cleanupcols, cleanuprows, lp->lastlpalgo, lp->solisbasic);
15881 
15882  if( cleanupcols && 0 < lp->ncols )
15883  {
15884  SCIP_CALL( lpCleanupCols(lp, set, stat, 0) );
15885  }
15886  if( cleanuprows && 0 < lp->nrows )
15887  {
15888  SCIP_CALL( lpCleanupRows(lp, blkmem, set, stat, eventqueue, eventfilter, 0) );
15889  }
15890 
15891  return SCIP_OKAY;
15892 }
15893 
15894 /** removes all redundant rows that were added at the current node */
15896  SCIP_LP* lp, /**< current LP data */
15897  BMS_BLKMEM* blkmem, /**< block memory buffers */
15898  SCIP_SET* set, /**< global SCIP settings */
15899  SCIP_STAT* stat, /**< problem statistics */
15900  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
15901  SCIP_EVENTFILTER* eventfilter /**< global event filter */
15902  )
15903 {
15904 #ifndef NDEBUG
15905  SCIP_ROW** rows;
15906 #endif
15907  SCIP_ROW** lpirows;
15908  int* rowdstat;
15909  int nrows;
15910  int ndelrows;
15911  int r;
15912 
15913  assert(lp != NULL);
15914  assert(lp->flushed);
15915  assert(lp->ncols == lp->nlpicols);
15916  assert(lp->nrows == lp->nlpirows);
15917  assert(!lp->diving);
15918  assert(stat != NULL);
15919  assert(lp->validsollp == stat->lpcount);
15920  assert(lp->firstnewrow <= lp->nrows);
15921 
15922  if( lp->firstnewrow == lp->nrows )
15923  return SCIP_OKAY;
15924 
15925 #ifndef NDEBUG
15926  rows = lp->rows;
15927 #endif
15928  nrows = lp->nrows;
15929  lpirows = lp->lpirows;
15930 
15931  /* get temporary memory */
15932  SCIP_CALL( SCIPsetAllocBufferArray(set, &rowdstat, nrows) );
15933 
15934  /* mark redundant rows to be deleted (only delete basic rows!) */
15935  ndelrows = 0;
15936  BMSclearMemoryArray(rowdstat, nrows);
15937  for( r = lp->firstnewrow; r < nrows; ++r )
15938  {
15939  assert(rows[r] == lpirows[r]);
15940  assert(rows[r]->lppos == r);
15941  assert(rows[r]->lpipos == r);
15942  if( (!lp->solisbasic || (SCIP_BASESTAT)lpirows[r]->basisstatus == SCIP_BASESTAT_BASIC)
15943  && SCIProwIsRedundant(lpirows[r], set, stat) )
15944  {
15945  SCIPsetDebugMsg(set, "basic row <%s> is redundant: sides=[%g,%g], act=[%g,%g]\n",
15946  SCIProwGetName(lpirows[r]), SCIProwGetLhs(lpirows[r]), SCIProwGetRhs(lpirows[r]),
15947  SCIProwGetMinActivity(lpirows[r], set, stat), SCIProwGetMaxActivity(lpirows[r], set, stat));
15948  rowdstat[r] = 1;
15949  ndelrows++;
15950  }
15951  }
15952 
15953  SCIPsetDebugMsg(set, "removing %d/%d redundant basic rows from LP\n", ndelrows, nrows);
15954 
15955  /* delete the marked rows in the LP solver interface, update the LP respectively */
15956  if( ndelrows > 0 )
15957  {
15958  SCIP_CALL( lpDelRowset(lp, blkmem, set, eventqueue, eventfilter, rowdstat) );
15959  }
15960  assert(lp->nrows == nrows - ndelrows);
15961 
15962  /* release temporary memory */
15963  SCIPsetFreeBufferArray(set, &rowdstat);
15964 
15965  return SCIP_OKAY;
15966 }
15967 
15968 /** initiates LP diving */
15970  SCIP_LP* lp, /**< current LP data */
15971  BMS_BLKMEM* blkmem, /**< block memory */
15972  SCIP_SET* set, /**< global SCIP settings */
15973  SCIP_STAT* stat /**< problem statistics */
15974  )
15975 {
15976  int c;
15977  int r;
15978 
15979  assert(lp != NULL);
15980  assert(lp->flushed || !lp->solved);
15981  assert(!lp->diving);
15982  assert(!lp->probing);
15983  assert(lp->divelpistate == NULL);
15984  assert(lp->divelpwasprimfeas);
15985  assert(lp->divelpwasdualfeas);
15986  assert(lp->validsollp <= stat->lpcount);
15987  assert(blkmem != NULL);
15988  assert(set != NULL);
15989  assert(lp->ndivechgsides == 0);
15990 
15991  SCIPsetDebugMsg(set, "diving started (LP flushed: %u, LP solved: %u, solstat: %d)\n",
15992  lp->flushed, lp->solved, SCIPlpGetSolstat(lp));
15993 
15994 #ifndef NDEBUG
15995  for( c = 0; c < lp->ncols; ++c )
15996  {
15997  assert(lp->cols[c] != NULL);
15998  assert(lp->cols[c]->var != NULL);
15999  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16000  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16001  assert(SCIPsetIsFeasEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16002  assert(SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16003  assert(SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16004  }
16005 #endif
16006 
16007  /* save current LPI state (basis information) */
16008  SCIP_CALL( SCIPlpiGetState(lp->lpi, blkmem, &lp->divelpistate) );
16010  lp->divelpwasdualfeas = lp->dualfeasible;
16013 
16014  /* save current LP values dependent on the solution */
16015  SCIP_CALL( lpStoreSolVals(lp, stat, blkmem) );
16016  assert(lp->storedsolvals != NULL);
16017  if( !set->lp_resolverestore && lp->solved )
16018  {
16019  SCIP_Bool store = TRUE;
16020 
16021  switch ( lp->lpsolstat )
16022  {
16024  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16025  assert(lp->validsollp == stat->lpcount);
16026  break;
16028  SCIP_CALL( SCIPlpGetUnboundedSol(lp, set, stat, NULL, NULL) );
16029  assert(lp->validsollp == stat->lpcount);
16030  break;
16034  SCIP_CALL( SCIPlpGetSol(lp, set, stat, NULL, NULL) );
16035  assert(lp->validsollp == stat->lpcount);
16036  break;
16038  SCIP_CALL( SCIPlpGetDualfarkas(lp, set, stat, NULL) );
16039  break;
16041  case SCIP_LPSOLSTAT_ERROR:
16042  default:
16043  store = FALSE;
16044  }
16045 
16046  if ( store )
16047  {
16048  for( c = 0; c < lp->ncols; ++c )
16049  {
16050  SCIP_CALL( colStoreSolVals(lp->cols[c], blkmem) );
16051  }
16052  for( r = 0; r < lp->nrows; ++r )
16053  {
16055  }
16056  }
16057  }
16058 
16059  /* store LPI iteration limit */
16061 
16062  /* remember the number of domain changes */
16063  lp->divenolddomchgs = stat->domchgcount;
16064 
16065  /* store current number of rows */
16066  lp->ndivingrows = lp->nrows;
16067 
16068  /* switch to diving mode */
16069  lp->diving = TRUE;
16070 
16071  return SCIP_OKAY;
16072 }
16073 
16074 /** quits LP diving and resets bounds and objective values of columns to the current node's values */
16076  SCIP_LP* lp, /**< current LP data */
16077  BMS_BLKMEM* blkmem, /**< block memory */
16078  SCIP_SET* set, /**< global SCIP settings */
16079  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16080  SCIP_STAT* stat, /**< problem statistics */
16081  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
16082  SCIP_EVENTFILTER* eventfilter, /**< global event filter */
16083  SCIP_PROB* prob, /**< problem data */
16084  SCIP_VAR** vars, /**< array with all active variables */
16085  int nvars /**< number of active variables */
16086  )
16087 {
16088  SCIP_VAR* var;
16089  int v;
16090 
16091  assert(lp != NULL);
16092  assert(lp->diving);
16093  assert(blkmem != NULL);
16094  assert(nvars == 0 || vars != NULL);
16095 
16096  SCIPsetDebugMsg(set, "diving ended (LP flushed: %u, solstat: %d)\n", lp->flushed, SCIPlpGetSolstat(lp));
16097 
16098  /* reset all columns' objective values and bounds to its original values */
16099  for( v = 0; v < nvars; ++v )
16100  {
16101  var = vars[v];
16102  assert(var != NULL);
16104  {
16105  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, SCIPvarGetObj(var)) );
16106  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, SCIPvarGetLbLocal(var)) );
16107  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, SCIPvarGetUbLocal(var)) );
16108  }
16109  }
16110 
16111  /* remove rows which were added in diving mode */
16112  SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, lp->ndivingrows) );
16113 
16114  /* undo changes to left hand sides and right hand sides */
16115  while( lp->ndivechgsides > 0 )
16116  {
16117  SCIP_Real oldside;
16118  SCIP_SIDETYPE sidetype;
16119  SCIP_ROW* row;
16120 
16121  lp->ndivechgsides--;
16122  oldside = lp->divechgsides[lp->ndivechgsides];
16123  sidetype = lp->divechgsidetypes[lp->ndivechgsides];
16124  row = lp->divechgrows[lp->ndivechgsides];
16125 
16126  if( sidetype == SCIP_SIDETYPE_LEFT )
16127  {
16128  SCIP_CALL( SCIProwChgLhs(row, blkmem, set, eventqueue, lp, oldside) );
16129  }
16130  else
16131  {
16132  SCIP_CALL( SCIProwChgRhs(row, blkmem, set, eventqueue, lp, oldside) );
16133  }
16134  }
16135 
16136  /* restore LPI iteration limit */
16138 
16139  /* reload LPI state saved at start of diving and free it afterwards; it may be NULL, in which case simply nothing
16140  * happens
16141  */
16142  SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lp->divelpistate,
16144  SCIP_CALL( SCIPlpFreeState(lp, blkmem, &lp->divelpistate) );
16145  lp->divelpwasprimfeas = TRUE;
16146  lp->divelpwasdualfeas = TRUE;
16147  lp->divelpwasprimchecked = TRUE;
16148  lp->divelpwasdualchecked = TRUE;
16149  assert(lp->divelpistate == NULL);
16150 
16151  /* switch to standard (non-diving) mode */
16152  lp->diving = FALSE;
16153  lp->divingobjchg = FALSE;
16154 
16155  /* if the LP was solved before starting the dive, but not to optimality (or unboundedness), then we need to solve the
16156  * LP again to reset the solution (e.g. we do not save the Farkas proof for infeasible LPs, because we assume that we
16157  * are not called in this case, anyway); restoring by solving the LP again in either case can be forced by setting
16158  * the parameter resolverestore to TRUE
16159  * restoring an unbounded ray after solve does not seem to work currently (bug 631), so we resolve also in this case
16160  */
16161  assert(lp->storedsolvals != NULL);
16162  if( lp->storedsolvals->lpissolved
16163  && (set->lp_resolverestore || lp->storedsolvals->lpsolstat != SCIP_LPSOLSTAT_OPTIMAL || lp->divenolddomchgs < stat->domchgcount) )
16164  {
16165  SCIP_Bool lperror;
16166 
16167  SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, -1LL, FALSE, FALSE, FALSE, &lperror) );
16168  if( lperror )
16169  {
16170  lpNumericalTroubleMessage(messagehdlr, set, stat, SCIP_VERBLEVEL_FULL, "unresolved when resolving LP after diving");
16171  lp->resolvelperror = TRUE;
16172  }
16177  {
16178  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
16179  "LP was not resolved to a sufficient status after diving\n");
16180  lp->resolvelperror = TRUE;
16181  }
16182  }
16183  /* otherwise, we can just reload the buffered LP solution values at start of diving; this has the advantage that we
16184  * are guaranteed to continue with the same LP status as before diving, while in numerically difficult cases, a
16185  * re-solve as above can lead to a different LP status
16186  */
16187  else
16188  {
16189  int c;
16190  int r;
16191 
16192  /* if there are lazy bounds, remove them from the LP */
16193  if( lp->nlazycols > 0 )
16194  {
16195  /* @todo avoid loosing primal feasibility here after changing the objective already did destroy dual feasibility;
16196  * first resolve LP?
16197  */
16198  SCIP_CALL( updateLazyBounds(lp, set) );
16199  assert(lp->diving == lp->divinglazyapplied);
16200 
16201  /* flush changes to the LP solver */
16202  SCIP_CALL( SCIPlpFlush(lp, blkmem, set, prob, eventqueue) );
16203  }
16204 
16205  /* increment lp counter to ensure that we do not use solution values from the last solved diving lp */
16206  SCIPstatIncrement(stat, set, lpcount);
16207 
16208  /* restore LP solution values in lp data, columns and rows */
16209  if( lp->storedsolvals->lpissolved &&
16216  )
16217  {
16218  SCIP_CALL( lpRestoreSolVals(lp, blkmem, stat->lpcount) );
16219 
16220  for( c = 0; c < lp->ncols; ++c )
16221  {
16222  SCIP_CALL( colRestoreSolVals(lp->cols[c], blkmem, stat->lpcount, set->lp_freesolvalbuffers) );
16223  }
16224  for( r = 0; r < lp->nrows; ++r )
16225  {
16226  SCIP_CALL( rowRestoreSolVals(lp->rows[r], blkmem, stat->lpcount, set->lp_freesolvalbuffers, lp->storedsolvals->lpsolstat == SCIP_LPSOLSTAT_INFEASIBLE) );
16227  }
16228  }
16229  else
16230  {
16231  SCIP_CALL( lpRestoreSolVals(lp, blkmem, -1LL) );
16232  }
16233  }
16234 
16235 #ifndef NDEBUG
16236  {
16237  int c;
16238  for( c = 0; c < lp->ncols; ++c )
16239  {
16240  assert(lp->cols[c] != NULL);
16241  assert(lp->cols[c]->var != NULL);
16242  assert(SCIPvarGetStatus(lp->cols[c]->var) == SCIP_VARSTATUS_COLUMN);
16243  assert(SCIPvarGetCol(lp->cols[c]->var) == lp->cols[c]);
16244  assert(SCIPsetIsEQ(set, SCIPvarGetObj(lp->cols[c]->var), lp->cols[c]->obj));
16245  assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(lp->cols[c]->var), lp->cols[c]->lb));
16246  assert(SCIPsetIsEQ(set, SCIPvarGetUbLocal(lp->cols[c]->var), lp->cols[c]->ub));
16247  }
16248  }
16249 #endif
16250 
16251  return SCIP_OKAY;
16252 }
16253 
16254 #define DIVESTACKGROWFACT 1.5
16255 
16256 /** records a current row side such that any change will be undone after diving */
16258  SCIP_LP* lp, /**< LP data object */
16259  SCIP_ROW* row, /**< row affected by the change */
16260  SCIP_SIDETYPE sidetype /**< side type */
16261  )
16262 {
16263  assert(lp != NULL);
16264  assert(row != NULL);
16265 
16266  if( lp->ndivechgsides == lp->divechgsidessize )
16267  {
16269  }
16270  assert(lp->ndivechgsides < lp->divechgsidessize);
16271 
16272  lp->divechgsides[lp->ndivechgsides] = (sidetype == SCIP_SIDETYPE_LEFT) ? row->lhs : row->rhs;
16273  lp->divechgsidetypes[lp->ndivechgsides] = sidetype;
16274  lp->divechgrows[lp->ndivechgsides] = row;
16275  lp->ndivechgsides++;
16276 
16277  return SCIP_OKAY;
16278 }
16279 
16280 /** informs the LP that probing mode was initiated */
16282  SCIP_LP* lp /**< current LP data */
16283  )
16284 {
16285  assert(lp != NULL);
16286  assert(!lp->probing);
16287  assert(!lp->strongbranching);
16288  assert(!lp->strongbranchprobing);
16289 
16290  lp->probing = TRUE;
16291 
16292  return SCIP_OKAY;
16293 }
16294 
16295 /** informs the LP that probing mode was finished */
16297  SCIP_LP* lp /**< current LP data */
16298  )
16299 {
16300  assert(lp != NULL);
16301  assert(lp->probing);
16302  assert(!lp->strongbranching);
16303  assert(!lp->strongbranchprobing);
16304 
16305  lp->probing = FALSE;
16306 
16307  return SCIP_OKAY;
16308 }
16309 
16310 /** informs the LP that the probing mode is now used for strongbranching */
16312  SCIP_LP* lp /**< current LP data */
16313  )
16314 {
16315  assert(lp != NULL);
16316  assert(lp->probing);
16317  assert(!lp->strongbranching);
16318  assert(!lp->strongbranchprobing);
16319 
16320  lp->strongbranchprobing = TRUE;
16321 }
16322 
16323 /** informs the LP that the probing mode is not used for strongbranching anymore */
16325  SCIP_LP* lp /**< current LP data */
16326  )
16327 {
16328  assert(lp != NULL);
16329  assert(lp->probing);
16330  assert(!lp->strongbranching);
16331  assert(lp->strongbranchprobing);
16332 
16333  lp->strongbranchprobing = FALSE;
16334 }
16335 
16336 /** calculates y*b + min{(c - y*A)*x | lb <= x <= ub} for given vectors y and c;
16337  * the vector b is defined with b[i] = lhs[i] if y[i] >= 0, b[i] = rhs[i] if y[i] < 0
16338  * Calculating this value in interval arithmetics gives a proved lower LP bound for the following reason (assuming,
16339  * we have only left hand sides):
16340  * min{cx | b <= Ax, lb <= x <= ub}
16341  * >= min{cx | yb <= yAx, lb <= x <= ub} (restriction in minimum is relaxed)
16342  * == yb + min{cx - yb | yb <= yAx, lb <= x <= ub} (added yb - yb == 0)
16343  * >= yb + min{cx - yAx | yb <= yAx, lb <= x <= ub} (because yAx >= yb inside minimum)
16344  * >= yb + min{cx - yAx | lb <= x <= ub} (restriction in minimum is relaxed)
16345  */
16346 static
16348  SCIP_LP* lp, /**< current LP data */
16349  SCIP_SET* set, /**< global SCIP settings */
16350  SCIP_Bool usefarkas, /**< use y = dual Farkas and c = 0 instead of y = dual solution and c = obj? */
16351  SCIP_Real* bound /**< result of interval arithmetic minimization */
16352  )
16353 {
16354  SCIP_INTERVAL* yinter;
16355  SCIP_INTERVAL b;
16356  SCIP_INTERVAL ytb;
16357  SCIP_INTERVAL prod;
16358  SCIP_INTERVAL diff;
16359  SCIP_INTERVAL x;
16360  SCIP_INTERVAL minprod;
16361  SCIP_INTERVAL a;
16362  SCIP_ROW* row;
16363  SCIP_COL* col;
16364  SCIP_Real y;
16365  SCIP_Real c;
16366  int i;
16367  int j;
16368 
16369  assert(lp != NULL);
16370  assert(lp->solved);
16371  assert(set != NULL);
16372  assert(bound != NULL);
16373 
16374  /* allocate buffer for storing y in interval arithmetic */
16375  SCIP_CALL( SCIPsetAllocBufferArray(set, &yinter, lp->nrows) );
16376 
16377  /* create y vector in interval arithmetic, setting near zeros to zero; calculate y^Tb */
16378  SCIPintervalSet(&ytb, 0.0);
16379  for( j = 0; j < lp->nrows; ++j )
16380  {
16381  row = lp->rows[j];
16382  assert(row != NULL);
16383 
16384  y = (usefarkas ? row->dualfarkas : row->dualsol);
16385 
16386  if( SCIPsetIsFeasPositive(set, y) )
16387  {
16388  SCIPintervalSet(&yinter[j], y);
16389  SCIPintervalSet(&b, row->lhs - row->constant);
16390  }
16391  else if( SCIPsetIsFeasNegative(set, y) )
16392  {
16393  SCIPintervalSet(&yinter[j], y);
16394  SCIPintervalSet(&b, row->rhs - row->constant);
16395  }
16396  else
16397  {
16398  SCIPintervalSet(&yinter[j], 0.0);
16399  SCIPintervalSet(&b, 0.0);
16400  }
16401 
16402  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[j], b);
16403  SCIPintervalAdd(SCIPsetInfinity(set), &ytb, ytb, prod);
16404  }
16405 
16406  /* calculate min{(c^T - y^TA)x} */
16407  SCIPintervalSet(&minprod, 0.0);
16408  for( j = 0; j < lp->ncols; ++j )
16409  {
16410  col = lp->cols[j];
16411  assert(col != NULL);
16412  assert(col->nunlinked == 0);
16413 
16415 
16416  c = usefarkas ? 0.0 : col->obj;
16417  SCIPintervalSet(&diff, c);
16418 
16419  for( i = 0; i < col->nlprows; ++i )
16420  {
16421  assert(col->rows[i] != NULL);
16422  assert(col->rows[i]->lppos >= 0);
16423  assert(col->linkpos[i] >= 0);
16424  SCIPintervalSet(&a, col->vals[i]);
16425  SCIPintervalMul(SCIPsetInfinity(set), &prod, yinter[col->rows[i]->lppos], a);
16426  SCIPintervalSub(SCIPsetInfinity(set), &diff, diff, prod);
16427  }
16428 
16429 #ifndef NDEBUG
16430  for( i = col->nlprows; i < col->len; ++i )
16431  {
16432  assert(col->rows[i] != NULL);
16433  assert(col->rows[i]->lppos == -1);
16434  assert(col->rows[i]->dualsol == 0.0);
16435  assert(col->rows[i]->dualfarkas == 0.0);
16436  assert(col->linkpos[i] >= 0);
16437  }
16438 #endif
16439 
16440  SCIPintervalSetBounds(&x, col->lb, col->ub);
16441  SCIPintervalMul(SCIPsetInfinity(set), &diff, diff, x);
16442  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, diff);
16443  }
16444 
16445  /* add y^Tb */
16446  SCIPintervalAdd(SCIPsetInfinity(set), &minprod, minprod, ytb);
16447 
16448  /* free buffer for storing y in interval arithmetic */
16449  SCIPsetFreeBufferArray(set, &yinter);
16450 
16451  *bound = SCIPintervalGetInf(minprod);
16452 
16453  return SCIP_OKAY;
16454 }
16455 
16456 /** gets proven lower (dual) bound of last LP solution */
16458  SCIP_LP* lp, /**< current LP data */
16459  SCIP_SET* set, /**< global SCIP settings */
16460  SCIP_Real* bound /**< pointer to store proven dual bound */
16461  )
16462 {
16463  SCIP_CALL( provedBound(lp, set, FALSE, bound) );
16464 
16465  SCIPsetDebugMsg(set, "proved lower bound of LP: %.15g\n", *bound);
16466 
16467  return SCIP_OKAY;
16468 }
16469 
16470 /** gets proven dual bound of last LP solution */
16472  SCIP_LP* lp, /**< current LP data */
16473  SCIP_SET* set, /**< global SCIP settings */
16474  SCIP_Bool* proved /**< pointer to store whether infeasibility is proven */
16475  )
16476 {
16477  SCIP_Real bound;
16478 
16479  assert(proved != NULL);
16480 
16481  SCIP_CALL( provedBound(lp, set, TRUE, &bound) );
16482 
16483  *proved = (bound > 0.0);
16484 
16485  SCIPsetDebugMsg(set, "proved Farkas value of LP: %g -> infeasibility %sproved\n", bound, *proved ? "" : "not ");
16486 
16487  return SCIP_OKAY;
16488 }
16489 
16490 
16491 
16492 /** writes LP to a file */
16494  SCIP_LP* lp, /**< current LP data */
16495  const char* fname /**< file name */
16496  )
16497 {
16498  assert(lp != NULL);
16499  assert(lp->flushed);
16500  assert(fname != NULL);
16501 
16502  SCIP_CALL( SCIPlpiWriteLP(lp->lpi, fname) );
16503 
16504  return SCIP_OKAY;
16505 }
16506 
16507 /** writes MIP relaxation of the current B&B node to a file */
16509  SCIP_LP* lp, /**< current LP data */
16510  SCIP_SET* set, /**< global SCIP settings */
16511  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
16512  const char* fname, /**< file name */
16513  SCIP_Bool genericnames, /**< should generic names like x_i and row_j be used in order to avoid
16514  * troubles with reserved symbols? */
16515  SCIP_Bool origobj, /**< should the original objective function be used? */
16516  SCIP_OBJSENSE objsense, /**< objective sense */
16517  SCIP_Real objscale, /**< objective scaling factor */
16518  SCIP_Real objoffset, /**< objective offset, e.g., caused by variable fixings in presolving */
16519  SCIP_Bool lazyconss /**< output removable rows as lazy constraints? */
16520  )
16521 {
16522  FILE* file;
16523  int i;
16524  int j;
16525  char rowname[SCIP_MAXSTRLEN];
16526  SCIP_Real coeff;
16527 
16528  assert(lp != NULL);
16529  assert(lp->flushed);
16530  assert(fname != NULL);
16531 
16532  SCIPsetDebugMsg(set, "Start to write MIP to file <%s>\n", fname);
16533  file = fopen(fname, "w");
16534  if( file == NULL )
16535  {
16536  SCIPerrorMessage("cannot open file <%s> for writing\n", fname);
16537  SCIPprintSysError(fname);
16538  return SCIP_FILECREATEERROR;
16539  }
16540 
16541  /* print comments */
16542  if( genericnames )
16543  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Original Variable and Constraint Names have been replaced by generic names.\n");
16544  else
16545  {
16546  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Warning: Variable and Constraint Names should not contain special characters like '+', '=' etc.\n");
16547  SCIPmessageFPrintInfo(messagehdlr, file, "\\ If this is the case, the model may be corrupted!\n");
16548  }
16549 
16550  if( origobj && objoffset != 0.0 )
16551  {
16552  SCIPmessageFPrintInfo(messagehdlr, file, "\\ An artificial variable 'objoffset' has been added and fixed to 1.\n");
16553  SCIPmessageFPrintInfo(messagehdlr, file, "\\ Switching this variable to 0 will disable the offset in the objective.\n\n");
16554  }
16555 
16556  /* print objective function */
16557  /**@note the transformed problem in SCIP is always a minimization problem */
16558  if( !origobj || objsense == SCIP_OBJSENSE_MINIMIZE )
16559  SCIPmessageFPrintInfo(messagehdlr, file, "Minimize");
16560  else
16561  SCIPmessageFPrintInfo(messagehdlr, file, "Maximize");
16562 
16563  /* print objective */
16564  SCIPmessageFPrintInfo(messagehdlr, file, "\nObj:");
16565  j = 0;
16566  for( i = 0; i < lp->ncols; ++i )
16567  {
16568  if( lp->cols[i]->obj != 0.0 )
16569  {
16570  coeff = lp->cols[i]->obj;
16571  if( origobj )
16572  {
16573  coeff *= (SCIP_Real) objsense;
16574  coeff *= objscale;
16575  }
16576 
16577  if( genericnames )
16578  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", coeff, lp->cols[i]->lppos);
16579  else
16580  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", coeff, lp->cols[i]->var->name);
16581 
16582  ++j;
16583  if( j % 10 == 0 )
16584  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16585  }
16586  }
16587  /* add artificial variable 'objoffset' to transfer objective offset */
16588  if( origobj && objoffset != 0.0 )
16589  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g objoffset", objoffset * (SCIP_Real) objsense * objscale);
16590 
16591  /* print constraint section */
16592  SCIPmessageFPrintInfo(messagehdlr, file, "\nSubject to\n");
16593  for( i = 0; i < lp->nrows; i++ )
16594  {
16595  char type = 'i';
16596 
16597  /* skip removable rows if we want to write them as lazy constraints */
16598  if ( lazyconss && SCIProwIsRemovable(lp->rows[i]) )
16599  continue;
16600 
16601  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16602  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16603  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16604  * type 'i' means: lhs and rhs are both infinite */
16605  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16606  type = 'r';
16607  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16608  type = 'l';
16609  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16610  type = 'e';
16611  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16612  type = 'b';
16613 
16614  /* print name of row */
16615  if( genericnames )
16616  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16617  else
16618  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16619 
16620  WRITEROW:
16621  switch( type )
16622  {
16623  case 'r':
16624  case 'l':
16625  case 'e':
16626  if( strlen(rowname) > 0 )
16627  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16628  break;
16629  case 'i':
16630  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16631  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16632  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n", lp->rows[i]->name);
16633  type = 'b';
16634  /*lint -fallthrough*/
16635  case 'b':
16636  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16637  break;
16638  default:
16639  assert(type == 'B');
16640  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16641  break;
16642  }
16643 
16644  /* print coefficients and variables */
16645  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16646  {
16647  if( genericnames )
16648  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16649  else
16650  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16651 
16652  if( (j+1) % 10 == 0 )
16653  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16654  }
16655 
16656  /* print right hand side */
16657  switch( type )
16658  {
16659  case 'b':
16660  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16661  type = 'B';
16662  goto WRITEROW;
16663  case 'l':
16664  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16665  break;
16666  case 'B':
16667  case 'r':
16668  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16669  break;
16670  case 'e':
16671  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16672  break;
16673  default:
16674  SCIPerrorMessage("Undefined row type!\n");
16675  fclose(file);
16676  return SCIP_ERROR;
16677  }
16678  }
16679 
16680  if ( lazyconss )
16681  {
16682  /* print lazy constraint section */
16683  SCIPmessageFPrintInfo(messagehdlr, file, "lazy constraints\n");
16684  for( i = 0; i < lp->nrows; i++ )
16685  {
16686  char type = 'i';
16687 
16688  /* skip non-removable rows if we want to write lazy constraints */
16689  if ( ! SCIProwIsRemovable(lp->rows[i]) )
16690  continue;
16691 
16692  /* constraint types: 'l' means: only lhs exists, 'r' means: only rhs exists, 'e' means: both sides exist and are
16693  * equal, 'b' and 'B' mean: both sides exist, if the type is 'b', the lhs will be written, if the type is 'B',
16694  * the rhs will be written. Ergo: set type to b first, change it to 'B' afterwards and go back to WRITEROW.
16695  * type 'i' means: lhs and rhs are both infinite */
16696  if( SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16697  type = 'r';
16698  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16699  type = 'l';
16700  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && SCIPsetIsEQ(set, lp->rows[i]->lhs, lp->rows[i]->rhs) )
16701  type = 'e';
16702  else if( !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->lhs)) && !SCIPsetIsInfinity(set, REALABS(lp->rows[i]->rhs)) )
16703  type = 'b';
16704 
16705  /* print name of row */
16706  if( genericnames )
16707  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "row_%d", lp->rows[i]->lppos);
16708  else
16709  (void) SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s", lp->rows[i]->name);
16710 
16711  WRITELAZYROW:
16712  switch( type )
16713  {
16714  case 'r':
16715  case 'l':
16716  case 'e':
16717  if( strlen(rowname) > 0 )
16718  SCIPmessageFPrintInfo(messagehdlr, file, "%s: ", rowname);
16719  break;
16720  case 'i':
16721  SCIPmessageFPrintInfo(messagehdlr, file, "\\\\ WARNING: The lhs and the rhs of the row with original name <%s>", lp->rows[i]->name);
16722  SCIPmessageFPrintInfo(messagehdlr, file, "are not in a valid range. The following two constraints may be corrupted!\n");
16723  SCIPmessagePrintWarning(messagehdlr, "The lhs and rhs of row <%s> are not in a valid range.\n",lp->rows[i]->name);
16724  type = 'b';
16725  /*lint -fallthrough*/
16726  case 'b':
16727  SCIPmessageFPrintInfo(messagehdlr, file, "%s_lhs: ", rowname);
16728  break;
16729  default:
16730  assert(type == 'B');
16731  SCIPmessageFPrintInfo(messagehdlr, file, "%s_rhs: ", rowname);
16732  break;
16733  }
16734 
16735  /* print coefficients and variables */
16736  for( j = 0; j < lp->rows[i]->nlpcols; ++j )
16737  {
16738  if( genericnames )
16739  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g x_%d", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->lppos);
16740  else
16741  SCIPmessageFPrintInfo(messagehdlr, file, " %+.15g %s", lp->rows[i]->vals[j], lp->rows[i]->cols[j]->var->name);
16742 
16743  if( (j+1) % 10 == 0 )
16744  SCIPmessageFPrintInfo(messagehdlr, file, "\n ");
16745  }
16746 
16747  /* print right hand side */
16748  switch( type )
16749  {
16750  case 'b':
16751  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16752  type = 'B';
16753  goto WRITELAZYROW;
16754  case 'l':
16755  SCIPmessageFPrintInfo(messagehdlr, file, " >= %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16756  break;
16757  case 'B':
16758  case 'r':
16759  SCIPmessageFPrintInfo(messagehdlr, file, " <= %.15g\n", lp->rows[i]->rhs - lp->rows[i]->constant);
16760  break;
16761  case 'e':
16762  SCIPmessageFPrintInfo(messagehdlr, file, " = %.15g\n", lp->rows[i]->lhs - lp->rows[i]->constant);
16763  break;
16764  default:
16765  SCIPerrorMessage("Undefined row type!\n");
16766  fclose(file);
16767  return SCIP_ERROR;
16768  }
16769  }
16770  }
16771 
16772  /* print variable bounds */
16773  SCIPmessageFPrintInfo(messagehdlr, file, "Bounds\n");
16774  for( i = 0; i < lp->ncols; ++i )
16775  {
16776  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) || !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16777  {
16778  /* print lower bound as far this one is not infinity */
16779  if( !SCIPsetIsInfinity(set,-lp->cols[i]->lb) )
16780  SCIPmessageFPrintInfo(messagehdlr, file, " %.15g <=", lp->cols[i]->lb);
16781 
16782  /* print variable name */
16783  if( genericnames )
16784  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16785  else
16786  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16787 
16788  /* print upper bound as far this one is not infinity */
16789  if( !SCIPsetIsInfinity(set,lp->cols[i]->ub) )
16790  SCIPmessageFPrintInfo(messagehdlr, file, "<= %.15g", lp->cols[i]->ub);
16791  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16792  }
16793  }
16794  if( origobj && objoffset != 0.0 )
16795  SCIPmessageFPrintInfo(messagehdlr, file, " objoffset = 1\n");
16796 
16797  /* print integer variables */
16798  SCIPmessageFPrintInfo(messagehdlr, file, "Generals\n");
16799  j = 0;
16800  for( i = 0; i < lp->ncols; ++i )
16801  {
16802  if( SCIPvarIsIntegral(lp->cols[i]->var) )
16803  {
16804  /* print variable name */
16805  if( genericnames )
16806  SCIPmessageFPrintInfo(messagehdlr, file, " x_%d ", lp->cols[i]->lppos);
16807  else
16808  SCIPmessageFPrintInfo(messagehdlr, file, " %s ", lp->cols[i]->var->name);
16809 
16810  j++;
16811  if( j % 10 == 0 )
16812  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
16813  }
16814  }
16815 
16816  SCIPmessageFPrintInfo(messagehdlr, file, "\nEnd");
16817  fclose(file);
16818 
16819  return SCIP_OKAY;
16820 }
16821 
16822 /*
16823  * simple functions implemented as defines
16824  */
16825 
16826 /* In debug mode, the following methods are implemented as function calls to ensure
16827  * type validity.
16828  * In optimized mode, the methods are implemented as defines to improve performance.
16829  * However, we want to have them in the library anyways, so we have to undef the defines.
16830  */
16831 
16832 #undef SCIPcolGetObj
16833 #undef SCIPcolGetLb
16834 #undef SCIPcolGetUb
16835 #undef SCIPcolGetBestBound
16836 #undef SCIPcolGetPrimsol
16837 #undef SCIPcolGetMinPrimsol
16838 #undef SCIPcolGetMaxPrimsol
16839 #undef SCIPcolGetBasisStatus
16840 #undef SCIPcolGetVar
16841 #undef SCIPcolGetIndex
16842 #undef SCIPcolGetVarProbindex
16843 #undef SCIPcolIsIntegral
16844 #undef SCIPcolIsRemovable
16845 #undef SCIPcolGetLPPos
16846 #undef SCIPcolGetLPDepth
16847 #undef SCIPcolIsInLP
16848 #undef SCIPcolGetNNonz
16849 #undef SCIPcolGetNLPNonz
16850 #undef SCIPcolGetRows
16851 #undef SCIPcolGetVals
16852 #undef SCIPcolGetStrongbranchNode
16853 #undef SCIPcolGetNStrongbranchs
16854 #undef SCIPcolGetAge
16855 #undef SCIPboundtypeOpposite
16856 #undef SCIProwGetNNonz
16857 #undef SCIProwGetNLPNonz
16858 #undef SCIProwGetCols
16859 #undef SCIProwGetVals
16860 #undef SCIProwGetConstant
16861 #undef SCIProwGetNorm
16862 #undef SCIProwGetSumNorm
16863 #undef SCIProwGetLhs
16864 #undef SCIProwGetRhs
16865 #undef SCIProwGetDualsol
16866 #undef SCIProwGetDualfarkas
16867 #undef SCIProwGetBasisStatus
16868 #undef SCIProwGetName
16869 #undef SCIProwGetIndex
16870 #undef SCIProwGetAge
16871 #undef SCIProwGetRank
16872 #undef SCIProwIsIntegral
16873 #undef SCIProwIsLocal
16874 #undef SCIProwIsModifiable
16875 #undef SCIProwIsRemovable
16876 #undef SCIProwGetOrigintype
16877 #undef SCIProwGetOriginCons
16878 #undef SCIProwGetOriginConshdlr
16879 #undef SCIProwGetOriginSepa
16880 #undef SCIProwIsInGlobalCutpool
16881 #undef SCIProwGetLPPos
16882 #undef SCIProwGetLPDepth
16883 #undef SCIProwIsInLP
16884 #undef SCIProwGetActiveLPCount
16885 #undef SCIProwGetNLPsAfterCreation
16886 #undef SCIProwChgRank
16887 #undef SCIPlpGetCols
16888 #undef SCIPlpGetNCols
16889 #undef SCIPlpGetRows
16890 #undef SCIPlpGetNRows
16891 #undef SCIPlpGetNewcols
16892 #undef SCIPlpGetNNewcols
16893 #undef SCIPlpGetNewrows
16894 #undef SCIPlpGetNNewrows
16895 #undef SCIPlpGetObjNorm
16896 #undef SCIPlpGetRootObjval
16897 #undef SCIPlpGetRootColumnObjval
16898 #undef SCIPlpGetRootLooseObjval
16899 #undef SCIPlpGetLPI
16900 #undef SCIPlpSetIsRelax
16901 #undef SCIPlpIsRelax
16902 #undef SCIPlpIsSolved
16903 #undef SCIPlpIsSolBasic
16904 #undef SCIPlpDiving
16905 #undef SCIPlpDivingObjChanged
16906 #undef SCIPlpMarkDivingObjChanged
16907 #undef SCIPlpUnmarkDivingObjChanged
16908 #undef SCIPlpDivingRowsChanged
16909 #undef SCIPlpIsFeasEQ
16910 #undef SCIPlpIsFeasLT
16911 #undef SCIPlpIsFeasLE
16912 #undef SCIPlpIsFeasGT
16913 #undef SCIPlpIsFeasGE
16914 #undef SCIPlpIsFeasZero
16915 #undef SCIPlpIsFeasPositive
16916 #undef SCIPlpIsFeasNegative
16917 
16918 /** gets objective value of column */
16920  SCIP_COL* col /**< LP column */
16921  )
16922 {
16923  assert(col != NULL);
16924 
16925  return col->obj;
16926 }
16927 
16928 /** gets lower bound of column */
16930  SCIP_COL* col /**< LP column */
16931  )
16932 {
16933  assert(col != NULL);
16934 
16935  return col->lb;
16936 }
16937 
16938 /** gets upper bound of column */
16940  SCIP_COL* col /**< LP column */
16941  )
16942 {
16943  assert(col != NULL);
16944 
16945  return col->ub;
16946 }
16947 
16948 /** gets best bound of column with respect to the objective function */
16950  SCIP_COL* col /**< LP column */
16951  )
16952 {
16953  assert(col != NULL);
16954 
16955  if( col->obj >= 0.0 )
16956  return col->lb;
16957  else
16958  return col->ub;
16959 }
16960 
16961 /** gets the primal LP solution of a column */
16963  SCIP_COL* col /**< LP column */
16964  )
16965 {
16966  assert(col != NULL);
16967 
16968  if( col->lppos >= 0 )
16969  return col->primsol;
16970  else
16971  return 0.0;
16972 }
16973 
16974 /** gets the minimal LP solution value, this column ever assumed */
16976  SCIP_COL* col /**< LP column */
16977  )
16978 {
16979  assert(col != NULL);
16980 
16981  return col->minprimsol;
16982 }
16983 
16984 /** gets the maximal LP solution value, this column ever assumed */
16986  SCIP_COL* col /**< LP column */
16987  )
16988 {
16989  assert(col != NULL);
16990 
16991  return col->maxprimsol;
16992 }
16993 
16994 /** gets the basis status of a column in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
16995  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_ZERO for columns not in the current SCIP_LP
16996  */
16998  SCIP_COL* col /**< LP column */
16999  )
17000 {
17001  assert(col != NULL);
17002  assert(col->lppos >= 0 || (SCIP_BASESTAT)col->basisstatus == SCIP_BASESTAT_ZERO);
17003 
17004  return (SCIP_BASESTAT)col->basisstatus;
17005 }
17006 
17007 /** gets variable this column represents */
17009  SCIP_COL* col /**< LP column */
17010  )
17011 {
17012  assert(col != NULL);
17013 
17014  return col->var;
17015 }
17016 
17017 /** gets unique index of col */
17019  SCIP_COL* col /**< LP col */
17020  )
17021 {
17022  assert(col != NULL);
17023 
17024  return col->index;
17025 }
17026 
17027 /** gets probindex of corresponding variable */
17029  SCIP_COL* col /**< LP col */
17030  )
17031 {
17032  assert(col != NULL);
17033 
17034  return col->var_probindex;
17035 }
17036 
17037 /** returns whether the associated variable is of integral type (binary, integer, implicit integer) */
17039  SCIP_COL* col /**< LP column */
17040  )
17041 {
17042  assert(col != NULL);
17043  assert(SCIPvarIsIntegral(col->var) == col->integral);
17044 
17045  return col->integral;
17046 }
17047 
17048 /** returns TRUE iff column is removable from the LP (due to aging or cleanup) */
17050  SCIP_COL* col /**< LP column */
17051  )
17052 {
17053  assert(col != NULL);
17054 
17055  return col->removable;
17056 }
17057 
17058 /** gets position of column in current LP, or -1 if it is not in LP */
17060  SCIP_COL* col /**< LP column */
17061  )
17062 {
17063  assert(col != NULL);
17064  assert((col->lppos == -1) == (col->lpdepth == -1));
17065 
17066  return col->lppos;
17067 }
17068 
17069 /** gets depth in the tree where the column entered the LP, or -1 if it is not in LP */
17071  SCIP_COL* col /**< LP column */
17072  )
17073 {
17074  assert(col != NULL);
17075  assert((col->lppos == -1) == (col->lpdepth == -1));
17076 
17077  return col->lpdepth;
17078 }
17079 
17080 /** returns TRUE iff column is member of current LP */
17082  SCIP_COL* col /**< LP column */
17083  )
17084 {
17085  assert(col != NULL);
17086  assert((col->lppos == -1) == (col->lpdepth == -1));
17087 
17088  return (col->lppos >= 0);
17089 }
17090 
17091 /** get number of nonzero entries in column vector */
17093  SCIP_COL* col /**< LP column */
17094  )
17095 {
17096  assert(col != NULL);
17097 
17098  return col->len;
17099 }
17100 
17101 /** get number of nonzero entries in column vector, that correspond to rows currently in the SCIP_LP;
17102  *
17103  * @warning This method is only applicable on columns, that are completely linked to their rows (e.g. a column
17104  * 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
17105  */
17107  SCIP_COL* col /**< LP column */
17108  )
17109 {
17110  assert(col != NULL);
17111  assert(col->nunlinked == 0);
17112 
17113  return col->nlprows;
17114 }
17115 
17116 /** gets array with rows of nonzero entries */
17118  SCIP_COL* col /**< LP column */
17119  )
17120 {
17121  assert(col != NULL);
17122 
17123  return col->rows;
17124 }
17125 
17126 /** gets array with coefficients of nonzero entries */
17128  SCIP_COL* col /**< LP column */
17129  )
17130 {
17131  assert(col != NULL);
17132 
17133  return col->vals;
17134 }
17135 
17136 /** gets node number of the last node in current branch and bound run, where strong branching was used on the
17137  * given column, or -1 if strong branching was never applied to the column in current run
17138  */
17140  SCIP_COL* col /**< LP column */
17141  )
17142 {
17143  assert(col != NULL);
17144 
17145  return col->sbnode;
17146 }
17147 
17148 /** gets number of times, strong branching was applied in current run on the given column */
17150  SCIP_COL* col /**< LP column */
17151  )
17152 {
17153  assert(col != NULL);
17154 
17155  return col->nsbcalls;
17156 }
17157 
17158 /** gets the age of a column, i.e., the total number of successive times a column was in the LP and was 0.0 in the solution */
17160  SCIP_COL* col /**< LP column */
17161  )
17162 {
17163  assert(col != NULL);
17164 
17165  return col->age;
17166 }
17167 
17168 /** gets opposite bound type of given bound type */
17170  SCIP_BOUNDTYPE boundtype /**< type of bound (lower or upper) */
17171  )
17172 {
17173  assert(boundtype == SCIP_BOUNDTYPE_LOWER || boundtype == SCIP_BOUNDTYPE_UPPER);
17174 
17176 }
17177 
17178 /** get number of nonzero entries in row vector */
17180  SCIP_ROW* row /**< LP row */
17181  )
17182 {
17183  assert(row != NULL);
17184 
17185  return row->len;
17186 }
17187 
17188 /** get number of nonzero entries in row vector, that correspond to columns currently in the SCIP_LP;
17189  *
17190  * @warning This method is only applicable on rows, that are completely linked to their columns (e.g. a row
17191  * 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
17192  */
17194  SCIP_ROW* row /**< LP row */
17195  )
17196 {
17197  assert(row != NULL);
17198  assert(row->nunlinked == 0);
17199 
17200  return row->nlpcols;
17201 }
17202 
17203 /** gets array with columns of nonzero entries */
17205  SCIP_ROW* row /**< LP row */
17206  )
17207 {
17208  assert(row != NULL);
17209 
17210  return row->cols;
17211 }
17212 
17213 /** gets array with coefficients of nonzero entries */
17215  SCIP_ROW* row /**< LP row */
17216  )
17217 {
17218  assert(row != NULL);
17219 
17220  return row->vals;
17221 }
17222 
17223 /** gets constant shift of row */
17225  SCIP_ROW* row /**< LP row */
17226  )
17227 {
17228  assert(row != NULL);
17229 
17230  return row->constant;
17231 }
17232 
17233 /** gets Euclidean norm of row vector */
17235  SCIP_ROW* row /**< LP row */
17236  )
17237 {
17238  assert(row != NULL);
17239 
17240  checkRowSqrnorm(row);
17241 
17242  return sqrt(row->sqrnorm);
17243 }
17244 
17245 /** gets sum norm of row vector (sum of absolute values of coefficients) */
17247  SCIP_ROW* row /**< LP row */
17248  )
17249 {
17250  assert(row != NULL);
17251 
17252  checkRowSumnorm(row);
17253 
17254  return row->sumnorm;
17255 }
17256 
17257 /** returns the left hand side of the row */
17259  SCIP_ROW* row /**< LP row */
17260  )
17261 {
17262  assert(row != NULL);
17263 
17264  return row->lhs;
17265 }
17266 
17267 /** returns the right hand side of the row */
17269  SCIP_ROW* row /**< LP row */
17270  )
17271 {
17272  assert(row != NULL);
17273 
17274  return row->rhs;
17275 }
17276 
17277 /** gets the dual LP solution of a row */
17279  SCIP_ROW* row /**< LP row */
17280  )
17281 {
17282  assert(row != NULL);
17283 
17284  if( row->lppos >= 0 )
17285  return row->dualsol;
17286  else
17287  return 0.0;
17288 }
17289 
17290 /** gets the dual Farkas coefficient of a row in an infeasible LP */
17292  SCIP_ROW* row /**< LP row */
17293  )
17294 {
17295  assert(row != NULL);
17296 
17297  if( row->lppos >= 0 )
17298  return row->dualfarkas;
17299  else
17300  return 0.0;
17301 }
17302 
17303 /** gets the basis status of a row in the LP solution; only valid for LPs with status SCIP_LPSOLSTAT_OPTIMAL
17304  * and with SCIPisLPSolBasic(scip) == TRUE; returns SCIP_BASESTAT_BASIC for rows not in the current SCIP_LP
17305  */
17307  SCIP_ROW* row /**< LP row */
17308  )
17309 {
17310  assert(row != NULL);
17311  assert(row->lppos >= 0 || (SCIP_BASESTAT)row->basisstatus == SCIP_BASESTAT_BASIC);
17312 
17313  return (SCIP_BASESTAT)row->basisstatus;
17314 }
17315 
17316 /** returns the name of the row */
17317 const char* SCIProwGetName(
17318  SCIP_ROW* row /**< LP row */
17319  )
17320 {
17321  assert(row != NULL);
17322 
17323  return row->name;
17324 }
17325 
17326 /** gets unique index of row */
17328  SCIP_ROW* row /**< LP row */
17329  )
17330 {
17331  assert(row != NULL);
17332 
17333  return row->index;
17334 }
17335 
17336 /** gets age of row */
17338  SCIP_ROW* row /**< LP row */
17339  )
17340 {
17341  assert(row != NULL);
17342 
17343  return row->age;
17344 }
17345 
17346 /** gets rank of row */
17348  SCIP_ROW* row /**< LP row */
17349  )
17350 {
17351  assert(row != NULL);
17352 
17353  return row->rank;
17354 }
17355 
17356 /** returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution */
17358  SCIP_ROW* row /**< LP row */
17359  )
17360 {
17361  assert(row != NULL);
17362 
17363  return row->integral;
17364 }
17365 
17366 /** returns TRUE iff row is only valid locally */
17368  SCIP_ROW* row /**< LP row */
17369  )
17370 {
17371  assert(row != NULL);
17372 
17373  return row->local;
17374 }
17375 
17376 /** returns TRUE iff row is modifiable during node processing (subject to column generation) */
17378  SCIP_ROW* row /**< LP row */
17379  )
17380 {
17381  assert(row != NULL);
17382 
17383  return row->modifiable;
17384 }
17385 
17386 /** returns TRUE iff row is removable from the LP (due to aging or cleanup) */
17388  SCIP_ROW* row /**< LP row */
17389  )
17390 {
17391  assert(row != NULL);
17392 
17393  return row->removable;
17394 }
17395 
17396 /** returns type of origin that created the row */
17398  SCIP_ROW* row /**< LP row */
17399  )
17400 {
17401  assert( row != NULL );
17402 
17403  return (SCIP_ROWORIGINTYPE) row->origintype;
17404 }
17405 
17406 /** returns origin constraint that created the row (NULL if not available) */
17408  SCIP_ROW* row /**< LP row */
17409  )
17410 {
17411  assert( row != NULL );
17412 
17414  {
17415  assert( row->origin != NULL );
17416  return (SCIP_CONS*) row->origin;
17417  }
17418  return NULL;
17419 }
17420 
17421 /** returns origin constraint handler that created the row (NULL if not available) */
17423  SCIP_ROW* row /**< LP row */
17424  )
17425 {
17426  assert( row != NULL );
17427 
17429  {
17430  assert( row->origin != NULL );
17431  return (SCIP_CONSHDLR*) row->origin;
17432  }
17434  {
17435  assert(row->origin != NULL);
17436  return SCIPconsGetHdlr((SCIP_CONS*)row->origin);
17437  }
17438  return NULL;
17439 }
17440 
17441 /** returns origin separator that created the row (NULL if not available) */
17443  SCIP_ROW* row /**< LP row */
17444  )
17445 {
17446  assert( row != NULL );
17447 
17449  {
17450  assert( row->origin != NULL );
17451  return (SCIP_SEPA*) row->origin;
17452  }
17453  return NULL;
17454 }
17455 
17456 /** returns TRUE iff row is member of the global cut pool */
17458  SCIP_ROW* row /**< LP row */
17459  )
17460 {
17461  assert(row != NULL);
17462 
17463  return row->inglobalcutpool;
17464 }
17465 
17466 /** gets position of row in current LP, or -1 if it is not in LP */
17468  SCIP_ROW* row /**< LP row */
17469  )
17470 {
17471  assert(row != NULL);
17472  assert((row->lppos == -1) == (row->lpdepth == -1));
17473 
17474  return row->lppos;
17475 }
17476 
17477 /** gets depth in the tree where the row entered the LP, or -1 if it is not in LP */
17479  SCIP_ROW* row /**< LP row */
17480  )
17481 {
17482  assert(row != NULL);
17483  assert((row->lppos == -1) == (row->lpdepth == -1));
17484 
17485  return row->lpdepth;
17486 }
17487 
17488 /** returns TRUE iff row is member of current LP */
17490  SCIP_ROW* row /**< LP row */
17491  )
17492 {
17493  assert(row != NULL);
17494  assert((row->lppos == -1) == (row->lpdepth == -1));
17495 
17496  return (row->lppos >= 0);
17497 }
17498 
17499 /** changes the rank of LP row */
17501  SCIP_ROW* row, /**< LP row */
17502  int rank /**< new value for rank */
17503  )
17504 {
17505  assert(row != NULL);
17506 
17507  row->rank = rank;
17508 }
17509 
17510 /** returns the number of times that this row has been sharp in an optimal LP solution */
17512  SCIP_ROW* row /**< row */
17513  )
17514 {
17515  assert(row != NULL);
17516 
17517  return row->activeinlpcounter;
17518 }
17519 
17520 /** returns the number of LPs since this row has been created */
17522  SCIP_ROW* row /**< row */
17523  )
17524 {
17525  assert(row != NULL);
17526 
17527  return row->nlpsaftercreation;
17528 }
17529 
17530 /** gets array with columns of the LP */
17532  SCIP_LP* lp /**< current LP data */
17533  )
17534 {
17535  assert(lp != NULL);
17536 
17537  return lp->cols;
17538 }
17539 
17540 /** gets current number of columns in LP */
17542  SCIP_LP* lp /**< current LP data */
17543  )
17544 {
17545  assert(lp != NULL);
17546 
17547  return lp->ncols;
17548 }
17549 
17550 /** gets current number of unfixed columns in LP */
17552  SCIP_LP* lp, /**< current LP data */
17553  SCIP_Real eps /**< numerical tolerance */
17554  )
17555 {
17556  SCIP_COL** lpcols;
17557  int nlpcols;
17558  int nunfixedcols;
17559  int c;
17560 
17561  assert(lp != NULL);
17562  assert(eps > 0.0);
17563 
17564  lpcols = lp->cols;
17565  nlpcols = lp->ncols;
17566 
17567  nunfixedcols = 0;
17568  for( c = 0; c < nlpcols; ++c )
17569  {
17570  if( lpcols[c]->ub - lpcols[c]->lb > eps )
17571  ++nunfixedcols;
17572  }
17573 
17574  return nunfixedcols;
17575 }
17576 
17577 /** gets array with rows of the LP */
17579  SCIP_LP* lp /**< current LP data */
17580  )
17581 {
17582  assert(lp != NULL);
17583 
17584  return lp->rows;
17585 }
17586 
17587 /** gets current number of rows in LP */
17589  SCIP_LP* lp /**< current LP data */
17590  )
17591 {
17592  assert(lp != NULL);
17593 
17594  return lp->nrows;
17595 }
17596 
17597 /** gets array with newly added columns after the last mark */
17599  SCIP_LP* lp /**< current LP data */
17600  )
17601 {
17602  assert(lp != NULL);
17603  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17604 
17605  return &(lp->cols[lp->firstnewcol]);
17606 }
17607 
17608 /** gets number of newly added columns after the last mark */
17610  SCIP_LP* lp /**< current LP data */
17611  )
17612 {
17613  assert(lp != NULL);
17614  assert(0 <= lp->firstnewcol && lp->firstnewcol <= lp->ncols);
17615 
17616  return lp->ncols - lp->firstnewcol;
17617 }
17618 
17619 /** gets array with newly added rows after the last mark */
17621  SCIP_LP* lp /**< current LP data */
17622  )
17623 {
17624  assert(lp != NULL);
17625  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17626 
17627  return &(lp->rows[lp->firstnewrow]);
17628 }
17629 
17630 /** gets number of newly added rows after the last mark */
17632  SCIP_LP* lp /**< current LP data */
17633  )
17634 {
17635  assert(lp != NULL);
17636  assert(0 <= lp->firstnewrow && lp->firstnewrow <= lp->nrows);
17637 
17638  return lp->nrows - lp->firstnewrow;
17639 }
17640 
17641 /** recalculates Euclidean norm of objective function vector of column variables if it have gotten unreliable during calculation */
17643  SCIP_SET* set, /**< global SCIP settings */
17644  SCIP_LP* lp /**< LP data */
17645  )
17646 {
17647  if( lp->objsqrnormunreliable )
17648  {
17649  SCIP_COL** cols;
17650  int c;
17651 
17652  cols = lp->cols;
17653  assert(cols != NULL || lp->ncols == 0);
17654 
17655  lp->objsqrnorm = 0.0;
17656 
17657  for( c = lp->ncols - 1; c >= 0; --c )
17658  {
17659  lp->objsqrnorm += SQR(cols[c]->unchangedobj); /*lint !e613*/
17660  }
17661  assert(SCIPsetIsGE(set, lp->objsqrnorm, 0.0));
17662 
17663  /* due to numerical troubles it still can appear that lp->objsqrnorm is a little bit smaller than 0 */
17664  lp->objsqrnorm = MAX(lp->objsqrnorm, 0.0);
17665 
17667  }
17668  return;
17669 }
17670 
17671 /** gets Euclidean norm of objective function vector of column variables, only use this method if
17672  * lp->objsqrnormunreliable == FALSE, so probably you have to call SCIPlpRecalculateObjSqrNorm before */
17674  SCIP_LP* lp /**< LP data */
17675  )
17676 {
17677  assert(lp != NULL);
17678  assert(!lp->objsqrnormunreliable);
17679  assert(lp->objsqrnorm >= 0.0);
17680 
17681  return SQRT(lp->objsqrnorm);
17682 }
17683 
17684 /** sets whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17686  SCIP_LP* lp, /**< LP data */
17687  SCIP_Bool isrelax /**< is the root lp a relaxation of the problem? */
17688  )
17689 {
17690  assert(lp != NULL);
17691 
17692  lp->rootlpisrelax = isrelax;
17693 }
17694 
17695 /** returns whether the root lp is a relaxation of the problem and its optimal objective value is a global lower bound */
17697  SCIP_LP* lp /**< LP data */
17698  )
17699 {
17700  assert(lp != NULL);
17701 
17702  return lp->rootlpisrelax;
17703 }
17704 
17705 /** gets the objective value of the root node LP; returns SCIP_INVALID if the root node LP was not (yet) solved */
17707  SCIP_LP* lp /**< LP data */
17708  )
17709 {
17710  assert(lp != NULL);
17711 
17712  return MIN(lp->rootlpobjval + lp->rootlooseobjval, SCIP_INVALID);
17713 }
17714 
17715 /** gets part of the objective value of the root node LP that results from COLUMN variables only;
17716  * returns SCIP_INVALID if the root node LP was not (yet) solved
17717  */
17719  SCIP_LP* lp /**< LP data */
17720  )
17721 {
17722  assert(lp != NULL);
17723 
17724  return lp->rootlpobjval;
17725 }
17726 
17727 /** gets part of the objective value of the root node LP that results from LOOSE variables only;
17728  * returns SCIP_INVALID if the root node LP was not (yet) solved
17729  */
17731  SCIP_LP* lp /**< LP data */
17732  )
17733 {
17734  assert(lp != NULL);
17735 
17736  return lp->rootlooseobjval;
17737 }
17738 
17739 /** gets the LP solver interface */
17741  SCIP_LP* lp /**< current LP data */
17742  )
17743 {
17744  assert(lp != NULL);
17745 
17746  return lp->lpi;
17747 }
17748 
17749 /** sets whether the current LP is a relaxation of the current problem and its optimal objective value is a local lower bound */
17751  SCIP_LP* lp, /**< LP data */
17752  SCIP_Bool relax /**< is the current lp a relaxation? */
17753  )
17754 {
17755  assert(lp != NULL);
17756 
17757  lp->isrelax = relax;
17758 }
17759 
17760 /** returns whether the current LP is a relaxation of the problem for which it has been solved and its
17761  * solution value a valid local lower bound?
17762  */
17764  SCIP_LP* lp /**< LP data */
17765  )
17766 {
17767  assert(lp != NULL);
17768 
17769  return lp->isrelax;
17770 }
17771 
17772 /** returns whether the current LP is flushed and solved */
17774  SCIP_LP* lp /**< current LP data */
17775  )
17776 {
17777  assert(lp != NULL);
17778 
17779  return lp->flushed && lp->solved;
17780 }
17781 
17782 /** return whether the current LP solution passed the primal feasibility check */
17784  SCIP_LP* lp /**< current LP data */
17785  )
17786 {
17787  assert(lp != NULL);
17788 
17789  return (lp->primalchecked && lp->primalfeasible);
17790 }
17791 
17792 /** return whether the current LP solution passed the dual feasibility check */
17794  SCIP_LP* lp /**< current LP data */
17795  )
17796 {
17797  assert(lp != NULL);
17798 
17799  return (lp->dualchecked && lp->dualfeasible);
17800 }
17801 
17802 /** returns whether the current LP solution is a basic solution */
17804  SCIP_LP* lp /**< current LP data */
17805  )
17806 {
17807  assert(lp != NULL);
17808 
17809  return lp->solisbasic;
17810 }
17811 
17812 /** returns whether the LP is in diving mode */
17814  SCIP_LP* lp /**< current LP data */
17815  )
17816 {
17817  assert(lp != NULL);
17818 
17819  return lp->diving;
17820 }
17821 
17822 /** returns whether the LP is in diving mode and the objective value of at least one column was changed */
17824  SCIP_LP* lp /**< current LP data */
17825  )
17826 {
17827  assert(lp != NULL);
17828 
17829  return lp->divingobjchg;
17830 }
17831 
17832 /** marks the diving LP to have a changed objective function */
17834  SCIP_LP* lp /**< current LP data */
17835  )
17836 {
17837  assert(lp != NULL);
17838  assert(lp->diving || lp->probing);
17839 
17840  lp->divingobjchg = TRUE;
17841 }
17842 
17843 /** marks the diving LP to not have a changed objective function anymore */
17845  SCIP_LP* lp /**< current LP data */
17846  )
17847 {
17848  assert(lp != NULL);
17849  assert(lp->diving || lp->probing);
17850 
17851  lp->divingobjchg = FALSE;
17852 }
17853 
17854 /* returns TRUE if at least one left/right hand side of an LP row was changed during diving mode */
17856  SCIP_LP* lp /**< current LP data */
17857  )
17858 {
17859  assert(lp != NULL);
17860  assert(lp->diving || lp->ndivechgsides == 0);
17861 
17862  return (lp->ndivechgsides > 0);
17863 }
17864 
17865 /** compute relative interior point with auxiliary lpi, see SCIPlpComputeRelIntPoint() */
17866 static
17868  SCIP_LPI* lpi, /**< auxiliary LP interface */
17869  SCIP_SET* set, /**< global SCIP settings */
17870  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
17871  SCIP_LP* lp, /**< LP data */
17872  SCIP_PROB* prob, /**< problem data */
17873  SCIP_Bool relaxrows, /**< should the rows be relaxed */
17874  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
17875  SCIP_Real timelimit, /**< time limit for LP solver */
17876  int iterlimit, /**< iteration limit for LP solver */
17877  SCIP_Real* point, /**< array to store relative interior point on exit */
17878  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
17879  )
17880 {
17881  SCIP_RETCODE retcode;
17882  SCIP_Real* primal;
17883  SCIP_Real* obj;
17884  SCIP_Real* lb;
17885  SCIP_Real* ub;
17886  SCIP_Real* matvals;
17887  SCIP_Real* matlhs;
17888  SCIP_Real* matrhs;
17889  SCIP_Real objval;
17890  SCIP_Real alpha;
17891  int* matinds;
17892  int* matbeg;
17893 #ifndef NDEBUG
17894  int nslacks;
17895 #endif
17896  int nnewcols;
17897  int ntotnonz = 0;
17898  int ntotrows = 0;
17899  int matrowidx;
17900  int matidx;
17901  int cnt;
17902  int j;
17903  int i;
17904 
17905  assert(lpi != NULL);
17906 
17907  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_FEASTOL, lp->feastol);
17908  if( retcode != SCIP_OKAY )
17909  {
17910  /* stop execution on error, since result is likely to be unsuable */
17911  SCIPmessagePrintWarning(messagehdlr, "Could not set feasibility tolerance of LP solver for relative interior point computation.\n");
17912  return SCIP_LPERROR;
17913  }
17914 
17916  if( retcode != SCIP_OKAY )
17917  {
17918  /* stop execution on error, since result is likely to be unsuable */
17919  SCIPmessagePrintWarning(messagehdlr, "Could not set dual feasibility tolerance of LP solver for relative interior point computation.\n");
17920  return SCIP_LPERROR;
17921  }
17922 
17923  /* get storage */
17924  nnewcols = 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1;
17925  SCIP_CALL( SCIPsetAllocBufferArray(set, &lb, nnewcols) );
17926  SCIP_CALL( SCIPsetAllocBufferArray(set, &ub, nnewcols) );
17927  SCIP_CALL( SCIPsetAllocBufferArray(set, &obj, nnewcols) );
17928 
17929  /* create original columns (bounds are relaxed below, unless the variable is fixed) */
17930  for( j = 0; j < lp->ncols; ++j )
17931  {
17932  /* note: if the variable is fixed we cannot simply fix the variables (because alpha scales the problem) */
17933  obj[j] = 0.0;
17934  lb[j] = -SCIPlpiInfinity(lpi);
17935  ub[j] = SCIPlpiInfinity(lpi);
17936  /* note: we could also use the original bounds - free variables seem to be faster. */
17937  }
17938 
17939  /* add artificial alpha variable */
17940  nnewcols = lp->ncols;
17941  obj[nnewcols] = 0.0;
17942  lb[nnewcols] = 1.0;
17943  ub[nnewcols] = SCIPlpiInfinity(lpi);
17944  ++nnewcols;
17945 
17946  /* create slacks for rows */
17947  for( i = 0; i < lp->nrows; ++i )
17948  {
17949  SCIP_ROW* row;
17950 
17951  row = lp->rows[i];
17952  assert( row != NULL );
17953 
17954  if( SCIProwIsModifiable(row) )
17955  continue;
17956 
17957  /* make sure row is sorted */
17958  rowSortLP(row);
17959  assert( row->lpcolssorted );
17960 
17961  /* check whether we have an equation */
17962  if( SCIPsetIsEQ(set, row->lhs, row->rhs) )
17963  {
17964  assert( !SCIPsetIsInfinity(set, REALABS(row->lhs)) );
17965  assert( !SCIPsetIsInfinity(set, REALABS(row->rhs)) );
17966  ntotnonz += row->nlpcols + 1;
17967  ++ntotrows;
17968  }
17969  else
17970  {
17971  /* otherwise add slacks for each side if necessary */
17972  if ( ! SCIPsetIsInfinity(set, REALABS(row->lhs)) )
17973  {
17974  if ( relaxrows )
17975  {
17976  lb[nnewcols] = 0.0;
17977  ub[nnewcols] = 1.0;
17978  obj[nnewcols++] = 1.0;
17979  ntotnonz += row->nlpcols + 2;
17980  }
17981  else
17982  ntotnonz += row->nlpcols + 1;
17983  ++ntotrows;
17984  }
17985  if ( ! SCIPsetIsInfinity(set, REALABS(row->rhs)) )
17986  {
17987  if ( relaxrows )
17988  {
17989  lb[nnewcols] = 0.0;
17990  ub[nnewcols] = 1.0;
17991  obj[nnewcols++] = 1.0;
17992  ntotnonz += row->nlpcols + 2;
17993  }
17994  else
17995  ntotnonz += row->nlpcols + 1;
17996  ++ntotrows;
17997  }
17998  }
17999  }
18000 
18001  /* create slacks for objective cutoff row */
18002  if( inclobjcutoff && relaxrows )
18003  {
18004  /* add slacks for right hand side */
18005  lb[nnewcols] = 0.0;
18006  ub[nnewcols] = 1.0;
18007  obj[nnewcols++] = 1.0;
18008  ntotnonz += lp->ncols + 2;
18009  ++ntotrows;
18010  }
18011 
18012  /* create slacks for bounds */
18013  for( j = 0; j < lp->ncols; ++j )
18014  {
18015  SCIP_COL* col;
18016 
18017  col = lp->cols[j];
18018  assert( col != NULL );
18019 
18020  /* no slacks for fixed variables */
18021  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18022  {
18023  ++ntotrows;
18024  ntotnonz += 2;
18025  }
18026  else
18027  {
18028  /* add slacks for each bound if necessary */
18029  if ( ! SCIPsetIsInfinity(set, REALABS(col->lb)) )
18030  {
18031  lb[nnewcols] = 0.0;
18032  ub[nnewcols] = 1.0;
18033  obj[nnewcols++] = 1.0;
18034  ntotnonz += 3;
18035  ++ntotrows;
18036  }
18037  if( ! SCIPsetIsInfinity(set, REALABS(col->ub)) )
18038  {
18039  lb[nnewcols] = 0.0;
18040  ub[nnewcols] = 1.0;
18041  obj[nnewcols++] = 1.0;
18042  ntotnonz += 3;
18043  ++ntotrows;
18044  }
18045  }
18046  }
18047 #ifndef NDEBUG
18048  nslacks = nnewcols - lp->ncols - 1;
18049  assert( nslacks >= 0 );
18050  assert( nnewcols <= 3*lp->ncols + 2*lp->nrows + (inclobjcutoff ? 1 : 0) + 1 );
18051 #endif
18052 
18053  /* add columns */
18054  SCIP_CALL( SCIPlpiAddCols(lpi, nnewcols, obj, lb, ub, NULL, 0, NULL, NULL, NULL) );
18055 
18056  /* free storage */
18057  SCIPsetFreeBufferArray(set, &obj);
18058  SCIPsetFreeBufferArray(set, &ub);
18059  SCIPsetFreeBufferArray(set, &lb);
18060 
18061  /* prepare storage for rows */
18062  SCIP_CALL( SCIPsetAllocBufferArray(set, &matinds, ntotnonz) );
18063  SCIP_CALL( SCIPsetAllocBufferArray(set, &matvals, ntotnonz) );
18064  SCIP_CALL( SCIPsetAllocBufferArray(set, &matbeg, ntotrows) );
18065  SCIP_CALL( SCIPsetAllocBufferArray(set, &matlhs, ntotrows) );
18066  SCIP_CALL( SCIPsetAllocBufferArray(set, &matrhs, ntotrows) );
18067 
18068  /* create rows arising from original rows */
18069  cnt = 0;
18070  matrowidx = 0;
18071  matidx = 0;
18072  for( i = 0; i < lp->nrows; ++i )
18073  {
18074  SCIP_ROW* row;
18075  SCIP_COL** rowcols;
18076  SCIP_Real* rowvals;
18077  SCIP_Real lhs;
18078  SCIP_Real rhs;
18079  int nnonz;
18080 
18081  row = lp->rows[i];
18082  assert( row != NULL );
18083 
18084  if( SCIProwIsModifiable(row) )
18085  continue;
18086  assert( row->lpcolssorted );
18087 
18088  /* get row data */
18089  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18090  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18091  nnonz = row->nlpcols;
18092  assert( nnonz <= lp->ncols );
18093  rowcols = row->cols;
18094  rowvals = row->vals;
18095 
18096  /* if we have an equation */
18097  if( SCIPsetIsEQ(set, lhs, rhs) )
18098  {
18099  /* set up indices */
18100  matbeg[matrowidx] = matidx;
18101  for( j = 0; j < nnonz; ++j )
18102  {
18103  assert( rowcols[j] != NULL );
18104  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18105  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18106  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18107  matinds[matidx] = rowcols[j]->lppos;
18108  matvals[matidx++] = rowvals[j];
18109  assert( matidx <= ntotnonz );
18110  }
18111 
18112  /* add artificial variable */
18113  if ( ! SCIPsetIsZero(set, rhs) )
18114  {
18115  matinds[matidx] = lp->ncols;
18116  matvals[matidx++] = -rhs;
18117  assert( matidx <= ntotnonz );
18118  }
18119 
18120  matlhs[matrowidx] = 0.0;
18121  matrhs[matrowidx++] = 0.0;
18122  assert( matrowidx <= ntotrows );
18123  }
18124  else
18125  {
18126  SCIP_Real abslhs = REALABS(lhs);
18127  SCIP_Real absrhs = REALABS(rhs);
18128 
18129  assert(!SCIPsetIsEQ(set, lhs, rhs));
18130 
18131  /* treat lhs */
18132  if( !SCIPsetIsInfinity(set, abslhs) )
18133  {
18134  /* set up indices */
18135  matbeg[matrowidx] = matidx;
18136  for( j = 0; j < nnonz; ++j )
18137  {
18138  assert( rowcols[j] != NULL );
18139  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18140  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18141  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18142  matinds[matidx] = rowcols[j]->lppos;
18143  matvals[matidx++] = rowvals[j];
18144  assert( matidx <= ntotnonz );
18145  }
18146 
18147  /* add artificial variable */
18148  if ( ! SCIPsetIsZero(set, lhs) )
18149  {
18150  matinds[matidx] = lp->ncols;
18151  matvals[matidx++] = -lhs;
18152  assert( matidx <= ntotnonz );
18153  }
18154 
18155  if( relaxrows )
18156  {
18157  /* add slack variable */
18158  matvals[matidx] = -MAX(1.0, lhs); /*lint !e679*/
18159  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18160  assert( matidx <= ntotnonz );
18161  ++cnt;
18162  }
18163 
18164  matlhs[matrowidx] = 0.0;
18165  matrhs[matrowidx++] = SCIPlpiInfinity(lpi);
18166  assert( matrowidx <= ntotrows );
18167  }
18168 
18169  /* treat rhs */
18170  if( !SCIPsetIsInfinity(set, absrhs) )
18171  {
18172  /* set up indices */
18173  matbeg[matrowidx] = matidx;
18174  for( j = 0; j < nnonz; ++j )
18175  {
18176  assert( rowcols[j] != NULL );
18177  assert( 0 <= rowcols[j]->lppos && rowcols[j]->lppos < lp->ncols );
18178  assert( lp->cols[rowcols[j]->lppos] == rowcols[j] );
18179  assert( ! SCIPsetIsZero(set, rowvals[j]) );
18180  matinds[matidx] = rowcols[j]->lppos;
18181  matvals[matidx++] = rowvals[j];
18182  assert( matidx <= ntotnonz );
18183  }
18184 
18185  /* add artificial variable */
18186  if ( ! SCIPsetIsZero(set, rhs) )
18187  {
18188  matinds[matidx] = lp->ncols;
18189  matvals[matidx++] = -rhs;
18190  assert( matidx <= ntotnonz );
18191  }
18192 
18193  if( relaxrows )
18194  {
18195  /* add slack variable */
18196  matvals[matidx] = MAX(1.0, absrhs); /*lint !e679*/
18197  matinds[matidx++] = lp->ncols + 1 + cnt; /*lint !e679*/
18198  ++cnt;
18199  }
18200 
18201  matlhs[matrowidx] = -SCIPlpiInfinity(lpi);
18202  matrhs[matrowidx++] = 0.0;
18203  assert( matrowidx <= ntotrows );
18204  }
18205  }
18206  }
18207 
18208  /* create row arising from objective cutoff */
18209  if( inclobjcutoff )
18210  {
18211  SCIP_Real rhs;
18212 
18213  /* get row data */
18214  assert(lp->looseobjvalinf == 0);
18215  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18216 
18217  /* set up indices and coefficients */
18218  matbeg[matrowidx] = matidx;
18219  for( j = 0; j < lp->ncols; ++j )
18220  {
18221  assert( lp->cols[j] != NULL );
18222  assert( 0 <= lp->cols[j]->lppos && lp->cols[j]->lppos < lp->ncols );
18223  assert( lp->cols[lp->cols[j]->lppos] == lp->cols[j] );
18224 
18225  if( ! SCIPsetIsZero(set, lp->cols[j]->obj) )
18226  {
18227  matinds[matidx] = lp->cols[j]->lppos;
18228  matvals[matidx++] = lp->cols[j]->obj;
18229  assert( matidx <= ntotnonz );
18230  }
18231  }
18232 
18233  /* treat rhs */
18234 
18235  /* add artificial variable */
18236  if ( ! SCIPsetIsZero(set, rhs) )
18237  {
18238  matinds[matidx] = lp->ncols;
18239  matvals[matidx++] = -rhs;
18240  assert( matidx <= ntotnonz );
18241  }
18242 
18243  if( relaxrows )
18244  {
18245  SCIP_Real absrhs = REALABS(rhs);
18246 
18247  /* add slack variable */
18248  matvals[matidx] = MAX(1.0, absrhs);
18249  matinds[matidx++] = lp->ncols + 1 + cnt;
18250  assert( matidx <= ntotnonz );
18251  ++cnt;
18252  }
18253  matlhs[matrowidx] = -SCIPsetInfinity(set);
18254  matrhs[matrowidx++] = 0.0;
18255  assert( matrowidx <= ntotrows );
18256  }
18257 
18258  /* create rows arising from bounds */
18259  for( j = 0; j < lp->ncols; ++j )
18260  {
18261  SCIP_COL* col;
18262  SCIP_Real abscollb;
18263  SCIP_Real abscolub;
18264 
18265  col = lp->cols[j];
18266  assert( col != NULL );
18267  assert( col->lppos == j );
18268 
18269  /* fixed variable */
18270  if( SCIPsetIsEQ(set, col->lb, col->ub) )
18271  {
18272  /* set up index of column */
18273  matbeg[matrowidx] = matidx;
18274 
18275  matinds[matidx] = j;
18276  matvals[matidx++] = 1.0;
18277  assert( matidx <= ntotnonz );
18278 
18279  /* add artificial variable */
18280  if ( ! SCIPsetIsZero(set, col->ub) )
18281  {
18282  matinds[matidx] = lp->ncols;
18283  matvals[matidx++] = -col->ub;
18284  assert( matidx <= ntotnonz );
18285  }
18286 
18287  matlhs[matrowidx] = 0.0;
18288  matrhs[matrowidx++] = 0.0;
18289  assert( matrowidx <= ntotrows );
18290 
18291  continue;
18292  }
18293 
18294  abscollb = REALABS(col->lb);
18295  abscolub = REALABS(col->ub);
18296 
18297  /* lower bound */
18298  if ( ! SCIPsetIsInfinity(set, abscollb) )
18299  {
18300  /* set up index of column */
18301  matbeg[matrowidx] = matidx;
18302 
18303  matinds[matidx] = j;
18304  matvals[matidx++] = 1.0;
18305  assert( matidx <= ntotnonz );
18306 
18307  /* add artificial variable */
18308  if ( ! SCIPsetIsZero(set, col->lb) )
18309  {
18310  matinds[matidx] = lp->ncols;
18311  matvals[matidx++] = -col->lb;
18312  assert( matidx <= ntotnonz );
18313  }
18314 
18315  /* add slack variable */
18316  matvals[matidx] = -MAX(1.0, abscollb);
18317  matinds[matidx++] = lp->ncols + 1 + cnt;
18318  assert( matidx <= ntotnonz );
18319  ++cnt;
18320 
18321  matlhs[matrowidx] = 0.0;
18322  matrhs[matrowidx++] = SCIPsetInfinity(set);
18323  assert( matrowidx <= ntotrows );
18324  }
18325 
18326  /* upper bound */
18327  if ( ! SCIPsetIsInfinity(set, abscolub) )
18328  {
18329  /* set up index of column */
18330  matbeg[matrowidx] = matidx;
18331 
18332  matinds[matidx] = j;
18333  matvals[matidx++] = 1.0;
18334  assert( matidx <= ntotnonz );
18335 
18336  /* add artificial variable */
18337  if ( ! SCIPsetIsZero(set, col->ub) )
18338  {
18339  matinds[matidx] = lp->ncols;
18340  matvals[matidx++] = -col->ub;
18341  assert( matidx <= ntotnonz );
18342  }
18343 
18344  /* add slack variable */
18345  matvals[matidx] = MAX(1.0, abscolub);
18346  matinds[matidx++] = lp->ncols + 1 + cnt;
18347  assert( matidx <= ntotnonz );
18348  ++cnt;
18349 
18350  matlhs[matrowidx] = -SCIPsetInfinity(set);
18351  matrhs[matrowidx++] = 0.0;
18352  assert( matrowidx <= ntotrows );
18353  }
18354  }
18355  assert( cnt == nslacks );
18356  assert( matrowidx == ntotrows );
18357 
18358  /* add rows */
18359  SCIP_CALL( SCIPlpiAddRows(lpi, ntotrows, matlhs, matrhs, NULL, matidx, matbeg, matinds, matvals) );
18360 
18361  SCIPsetFreeBufferArray(set, &matrhs);
18362  SCIPsetFreeBufferArray(set, &matlhs);
18363  SCIPsetFreeBufferArray(set, &matbeg);
18364  SCIPsetFreeBufferArray(set, &matvals);
18365  SCIPsetFreeBufferArray(set, &matinds);
18366 
18367 #ifdef SCIP_OUTPUT
18368  SCIP_CALL( SCIPlpiWriteLP(lpi, "relativeInterior.lp") );
18369 #endif
18370 
18371 #ifndef NDEBUG
18372  {
18373  int ncols;
18374  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
18375  assert( ncols == nnewcols );
18376  }
18377 #endif
18378 
18379  /* set time limit */
18380  if( SCIPsetIsInfinity(set, timelimit) )
18381  timelimit = SCIPlpiInfinity(lpi);
18382  retcode = SCIPlpiSetRealpar(lpi, SCIP_LPPAR_LPTILIM, timelimit);
18383 
18384  /* check, if parameter is unknown */
18385  if( retcode == SCIP_PARAMETERUNKNOWN )
18386  SCIPmessagePrintWarning(messagehdlr, "Could not set time limit of LP solver for relative interior point computation.\n");
18387  else if ( retcode != SCIP_OKAY )
18388  return retcode;
18389 
18390  /* set iteration limit */
18391  retcode = SCIPlpiSetIntpar(lpi, SCIP_LPPAR_LPITLIM, iterlimit);
18392 
18393  /* check, if parameter is unknown */
18394  if( retcode == SCIP_PARAMETERUNKNOWN )
18395  SCIPmessagePrintWarning(messagehdlr, "Could not set iteration limit of LP solver for relative interior point computation.\n");
18396  else if ( retcode != SCIP_OKAY )
18397  return retcode;
18398 
18399  /* solve and store point */
18400  /* SCIP_CALL( SCIPlpiSolvePrimal(lpi) ); */
18401  SCIP_CALL( SCIPlpiSolveDual(lpi) ); /* dual is usually faster */
18402 
18403 #ifndef NDEBUG
18404  if ( SCIPlpiIsIterlimExc(lpi) )
18405  SCIPmessagePrintWarning(messagehdlr, "Iteration limit exceeded in relative interior point computation.\n");
18406  if ( SCIPlpiIsTimelimExc(lpi) )
18407  SCIPmessagePrintWarning(messagehdlr, "Time limit exceeded in relative interior point computation.\n");
18408 #endif
18409 
18410  if( SCIPlpiIsOptimal(lpi) )
18411  {
18412  /* get primal solution */
18413  SCIP_CALL( SCIPsetAllocBufferArray(set, &primal, nnewcols) );
18414  SCIP_CALL( SCIPlpiGetSol(lpi, &objval, primal, NULL, NULL, NULL) );
18415  alpha = primal[lp->ncols];
18416  assert( SCIPsetIsFeasGE(set, alpha, 1.0) );
18417 
18418  SCIPsetDebugMsg(set, "Solved relative interior lp with objective %g.\n", objval);
18419 
18420  /* construct relative interior point */
18421  for( j = 0; j < lp->ncols; ++j )
18422  point[j] = primal[j]/alpha;
18423 
18424 #ifdef SCIP_DEBUG
18425  /* check whether the point is a relative interior point */
18426  cnt = 0;
18427  if( relaxrows )
18428  {
18429  for( i = 0; i < lp->nrows; ++i )
18430  {
18431  SCIP_ROW* row;
18432  SCIP_COL** rowcols;
18433  SCIP_Real* rowvals;
18434  SCIP_Real lhs;
18435  SCIP_Real rhs;
18436  SCIP_Real sum;
18437  int nnonz;
18438 
18439  row = lp->rows[i];
18440  assert( row != NULL );
18441 
18442  /* get row data */
18443  lhs = row->lhs - (SCIPsetIsInfinity(set, -row->lhs) ? 0.0 : row->constant);
18444  rhs = row->rhs - (SCIPsetIsInfinity(set, row->rhs) ? 0.0 : row->constant);
18445  nnonz = row->nlpcols;
18446  assert( nnonz <= lp->ncols );
18447  rowcols = row->cols;
18448  rowvals = row->vals;
18449 
18450  sum = 0.0;
18451  for( j = 0; j < nnonz; ++j )
18452  sum += rowvals[j] * primal[rowcols[j]->lppos];
18453  sum /= alpha;
18454 
18455  /* if we have an equation */
18456  if( SCIPsetIsEQ(set, lhs, rhs) )
18457  {
18458  assert( SCIPsetIsFeasEQ(set, sum, lhs) );
18459  }
18460  else
18461  {
18462  /* treat lhs */
18463  if( !SCIPsetIsInfinity(set, REALABS(lhs)) )
18464  {
18465  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, sum, lhs) );
18466  ++cnt;
18467  }
18468  /* treat rhs */
18469  if( !SCIPsetIsInfinity(set, REALABS(rhs)) )
18470  {
18471  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18472  ++cnt;
18473  }
18474  }
18475  }
18476  if( inclobjcutoff )
18477  {
18478  SCIP_Real sum;
18479 #ifndef NDEBUG
18480  SCIP_Real rhs;
18481 
18482  rhs = lp->cutoffbound - getFiniteLooseObjval(lp, set, prob);
18483 #endif
18484  sum = 0.0;
18485  for( j = 0; j < lp->ncols; ++j )
18486  sum += lp->cols[j]->obj * primal[lp->cols[j]->lppos];
18487  sum /= alpha;
18488 
18489  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, sum, rhs) );
18490  ++cnt;
18491  }
18492  }
18493  /* check bounds */
18494  for( j = 0; j < lp->ncols; ++j )
18495  {
18496  SCIP_COL* col;
18497 #ifndef NDEBUG
18498  SCIP_Real val;
18499 #endif
18500 
18501  col = lp->cols[j];
18502  assert( col != NULL );
18503 #ifndef NDEBUG
18504  val = primal[col->lppos] / alpha;
18505 #endif
18506  /* if the variable is not fixed */
18507  if( !SCIPsetIsEQ(set, col->lb, col->ub) )
18508  {
18509  /* treat lb */
18510  if( !SCIPsetIsInfinity(set, REALABS(col->lb)) )
18511  {
18512  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasGT(set, val, col->lb) );
18513  ++cnt;
18514  }
18515  /* treat rhs */
18516  if( !SCIPsetIsInfinity(set, REALABS(col->ub)) )
18517  {
18518  assert( SCIPsetIsFeasZero(set, primal[lp->ncols+1+cnt]) || SCIPsetIsFeasLT(set, val, col->ub) );
18519  ++cnt;
18520  }
18521  }
18522  }
18523 #endif
18524 
18525  /* free */
18526  SCIPsetFreeBufferArray(set, &primal);
18527 
18528  *success = TRUE;
18529  }
18530 
18531  return SCIP_OKAY;
18532 }
18533 
18534 /** compute relative interior point
18535  *
18536  * We use the approach of@par
18537  * R. Freund, R. Roundy, M. J. Todd@par
18538  * "Identifying the Set of Always-Active Constraints in a System of Linear Inequalities by a Single Linear Program"@par
18539  * Tech. Rep, No. 1674-85, Sloan School, M.I.T., 1985
18540  *
18541  * to compute a relative interior point for the current LP.
18542  *
18543  * Assume the original LP looks as follows:
18544  * \f[
18545  * \begin{array}{rrl}
18546  * \min & c^T x &\\
18547  * & A x & \geq a\\
18548  * & B x & \leq b\\
18549  * & D x & = d.
18550  * \end{array}
18551  * \f]
18552  * Note that bounds should be included in the system.
18553  *
18554  * To find an interior point the following LP does the job:
18555  * \f[
18556  * \begin{array}{rrl}
18557  * \max & 1^T y &\\
18558  * & A x - y - \alpha a & \geq 0\\
18559  * & B x + y - \alpha b & \leq 0\\
18560  * & D x - \alpha d & = 0\\
18561  * & 0 \leq y & \leq 1\\
18562  * & \alpha & \geq 1.
18563  * \end{array}
18564  * \f]
18565  * If the original LP is feasible, this LP is feasible as well. Any optimal solution yields the relative interior point
18566  * \f$x^*_j/\alpha^*\f$. Note that this will just produce some relative interior point. It does not produce a
18567  * particular relative interior point, e.g., one that maximizes the distance to the boundary in some norm.
18568  */
18570  SCIP_SET* set, /**< global SCIP settings */
18571  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
18572  SCIP_LP* lp, /**< LP data */
18573  SCIP_PROB* prob, /**< problem data */
18574  SCIP_Bool relaxrows, /**< should the rows be relaxed */
18575  SCIP_Bool inclobjcutoff, /**< should a row for the objective cutoff be included */
18576  SCIP_Real timelimit, /**< time limit for LP solver */
18577  int iterlimit, /**< iteration limit for LP solver */
18578  SCIP_Real* point, /**< array to store relative interior point on exit */
18579  SCIP_Bool* success /**< buffer to indicate whether interior point was successfully computed */
18580  )
18581 {
18582  SCIP_LPI* lpi;
18583  SCIP_RETCODE retcode;
18584 
18585  assert(set != NULL);
18586  assert(lp != NULL);
18587  assert(point != NULL);
18588  assert(success != NULL);
18589 
18590  *success = FALSE;
18591 
18592  /* check time and iteration limits */
18593  if ( timelimit <= 0.0 || iterlimit <= 0 )
18594  return SCIP_OKAY;
18595 
18596  /* exit if there are no columns */
18597  assert(lp->nrows >= 0);
18598  assert(lp->ncols >= 0);
18599  if( lp->ncols == 0 )
18600  return SCIP_OKAY;
18601 
18602  /* disable objective cutoff if we have none */
18603  if( inclobjcutoff && (SCIPsetIsInfinity(set, lp->cutoffbound) || lp->looseobjvalinf > 0 || lp->looseobjval == SCIP_INVALID) ) /*lint !e777 */
18604  inclobjcutoff = FALSE;
18605 
18606  SCIPsetDebugMsg(set, "Computing relative interior point to current LP.\n");
18607 
18608  /* if there are no rows, we return the zero point */
18609  if( lp->nrows == 0 && !inclobjcutoff )
18610  {
18611  /* create zero point */
18612  BMSclearMemoryArray(point, lp->ncols);
18613  *success = TRUE;
18614 
18615  return SCIP_OKAY;
18616  }
18617 
18618  /* create auxiliary LP */
18619  SCIP_CALL( SCIPlpiCreate(&lpi, messagehdlr, "relativeInterior", SCIP_OBJSEN_MAXIMIZE) );
18620 
18621  /* catch return code and ensure that lpi is freed, anyway */
18622  retcode = computeRelIntPoint(lpi, set, messagehdlr, lp, prob, relaxrows, inclobjcutoff, timelimit, iterlimit, point, success);
18623 
18624  SCIP_CALL( SCIPlpiFree(&lpi) );
18625 
18626  /* return error, unless we obtained an LP error */
18627  if ( retcode != SCIP_OKAY && retcode != SCIP_LPERROR )
18628  {
18629  SCIP_CALL( retcode );
18630  }
18631 
18632  return SCIP_OKAY;
18633 }
18634 
18635 /** computes two measures for dual degeneracy (dual degeneracy rate and variable-constraint ratio)
18636  * based on the changes applied when reducing the problem to the optimal face
18637  *
18638  * returns the dual degeneracy rate, i.e., the share of nonbasic variables with reduced cost 0
18639  * and the variable-constraint ratio, i.e., the number of unfixed variables in relation to the basis size
18640  */
18642  SCIP_LP* lp, /**< LP data */
18643  SCIP_SET* set, /**< global SCIP settings */
18644  SCIP_STAT* stat, /**< problem statistics */
18645  SCIP_Real* degeneracy, /**< pointer to store the dual degeneracy rate */
18646  SCIP_Real* varconsratio /**< pointer to store the variable-constraint ratio */
18647  )
18648 {
18649  assert(lp != NULL);
18650  assert(lp->solved);
18651  assert(lp->flushed);
18652 
18653  if( lp->validdegeneracylp != stat->nlps )
18654  {
18655  lp->validdegeneracylp = stat->nlps;
18656 
18657  /* if the LP was solved to optimality, we determine the dual degeneracy */
18659  {
18660  SCIP_COL** cols;
18661  SCIP_ROW** rows;
18662  SCIP_COL* col;
18663  int ncols;
18664  int nrows;
18665  int nfixedcols = 0;
18666  int nalreadyfixedcols = 0;
18667  int nfixedrows = 0;
18668  int nimplicitfixedrows = 0;
18669  int nineq = 0;
18670  int c;
18671  int r;
18672  int nbasicequalities = 0;
18673 
18674  cols = lp->cols;
18675  rows = lp->rows;
18676  ncols = lp->ncols;
18677  nrows = lp->nrows;
18678 
18679  /* count number of columns that will be fixed when reducing the LP to the optimal face */
18680  for( c = ncols - 1 ; c >= 0; --c )
18681  {
18682  col = cols[c];
18683  assert(SCIPcolIsInLP(col));
18684 
18685  /* column is not basic and not fixed already */
18687  {
18688  /* variable with nonzero reduced costs are fixed */
18689  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18690  if( !SCIPsetIsZero(set, SCIPcolGetRedcost(col, stat, lp)) )
18691  ++nfixedcols;
18692  else if( SCIPsetIsEQ(set, SCIPcolGetLb(col), SCIPcolGetUb(col)) )
18693  ++nalreadyfixedcols;
18694  }
18695  }
18696 
18697  /* count number of rows that will be turned into equations when reducing the LP to the optimal face */
18698  for( r = nrows - 1; r >= 0; --r )
18699  {
18700  SCIP_ROW* row = rows[r];
18701 
18702  assert(SCIProwIsInLP(row));
18703 
18704  if( !SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetRhs(row)) )
18705  {
18706  SCIP_Real dualsol = SCIProwGetDualsol(row);
18707 
18708  ++nineq;
18709 
18711  {
18712  /* rows with nonzero dual solution are turned into equations */
18713  /* @todo which tolerance should be used here? epsilon or dualfeastol? */
18714  if( !SCIPsetIsZero(set, dualsol) )
18715  {
18716  if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18717  {
18718  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasNegative(set, dualsol));
18719  ++nfixedrows;
18720  }
18721  else if( SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetLPActivity(row, set, stat, lp)) )
18722  {
18723  assert(!SCIPlpIsDualReliable(lp) || !SCIPsetIsDualfeasPositive(set, dualsol));
18724  ++nfixedrows;
18725  }
18726  }
18727  else if( SCIPsetIsEQ(set, SCIProwGetLhs(row), SCIProwGetMaxActivity(row, set, stat))
18728  || SCIPsetIsEQ(set, SCIProwGetRhs(row), SCIProwGetMinActivity(row, set, stat)) )
18729  {
18730  ++nimplicitfixedrows;
18731  }
18732  }
18733  }
18734  else if( SCIProwGetBasisStatus(row) == SCIP_BASESTAT_BASIC )
18735  ++nbasicequalities;
18736  }
18737  assert(nfixedcols + nfixedrows <= ncols + nineq + nbasicequalities - nrows - nalreadyfixedcols - nimplicitfixedrows);
18738 
18739  if( ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols > 0 )
18740  lp->degeneracy = 1.0 - 1.0 * (nfixedcols + nfixedrows) / (ncols + nineq - nrows + nbasicequalities - nalreadyfixedcols);
18741  else
18742  lp->degeneracy = 0.0;
18743 
18744  if( nrows > 0 )
18745  lp->varconsratio = 1.0 * (ncols + nineq + nbasicequalities - nfixedcols - nfixedrows - nalreadyfixedcols) / nrows;
18746  else
18747  lp->varconsratio = 1.0; /* @todo should this rather be set to a large value? */
18748  assert(lp->degeneracy >= 0);
18749  assert(SCIPsetIsLE(set, lp->degeneracy, 1.0));
18750  assert(SCIPsetIsGE(set, lp->varconsratio, 1.0));
18751  }
18752  else
18753  {
18754  lp->degeneracy = 0.0;
18755  lp->varconsratio = 0.0;
18756  }
18757  }
18758 
18759  *degeneracy = lp->degeneracy;
18760  *varconsratio = lp->varconsratio;
18761 
18762  return SCIP_OKAY;
18763 }
18764 
18765 /** checks, if absolute difference of values is in range of LP primal feastol */
18767  SCIP_SET* set, /**< global SCIP settings */
18768  SCIP_LP* lp, /**< current LP data */
18769  SCIP_Real val1, /**< first value to be compared */
18770  SCIP_Real val2 /**< second value to be compared */
18771  )
18772 {
18773  assert(set != NULL);
18774  assert(lp != NULL);
18775 
18776  /* avoid to compare two different infinities; the reason for that is
18777  * that such a comparison can lead to unexpected results */
18778  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18779  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18780  || val1 == val2 ); /*lint !e777*/
18781 
18782  return EPSEQ(val1, val2, lp->feastol);
18783 }
18784 
18785 /** checks, if absolute difference of val1 and val2 is lower than LP primal feastol */
18787  SCIP_SET* set, /**< global SCIP settings */
18788  SCIP_LP* lp, /**< current LP data */
18789  SCIP_Real val1, /**< first value to be compared */
18790  SCIP_Real val2 /**< second value to be compared */
18791  )
18792 {
18793  assert(set != NULL);
18794  assert(lp != NULL);
18795 
18796  /* avoid to compare two different infinities; the reason for that is
18797  * that such a comparison can lead to unexpected results */
18798  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18799  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18800  || val1 == val2 ); /*lint !e777*/
18801 
18802  return EPSLT(val1, val2, lp->feastol);
18803 }
18804 
18805 /** checks, if absolute difference of val1 and val2 is not greater than LP primal feastol */
18807  SCIP_SET* set, /**< global SCIP settings */
18808  SCIP_LP* lp, /**< current LP data */
18809  SCIP_Real val1, /**< first value to be compared */
18810  SCIP_Real val2 /**< second value to be compared */
18811  )
18812 {
18813  assert(set != NULL);
18814  assert(lp != NULL);
18815 
18816  /* avoid to compare two different infinities; the reason for that is
18817  * that such a comparison can lead to unexpected results */
18818  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18819  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18820  || val1 == val2 ); /*lint !e777*/
18821 
18822  return EPSLE(val1, val2, lp->feastol);
18823 }
18824 
18825 /** checks, if absolute difference of val1 and val2 is greater than LP primal feastol */
18827  SCIP_SET* set, /**< global SCIP settings */
18828  SCIP_LP* lp, /**< current LP data */
18829  SCIP_Real val1, /**< first value to be compared */
18830  SCIP_Real val2 /**< second value to be compared */
18831  )
18832 {
18833  assert(set != NULL);
18834  assert(lp != NULL);
18835 
18836  /* avoid to compare two different infinities; the reason for that is
18837  * that such a comparison can lead to unexpected results */
18838  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18839  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18840  || val1 == val2 ); /*lint !e777*/
18841 
18842  return EPSGT(val1, val2, lp->feastol);
18843 }
18844 
18845 /** checks, if absolute difference of val1 and val2 is not lower than -LP primal feastol */
18847  SCIP_SET* set, /**< global SCIP settings */
18848  SCIP_LP* lp, /**< current LP data */
18849  SCIP_Real val1, /**< first value to be compared */
18850  SCIP_Real val2 /**< second value to be compared */
18851  )
18852 {
18853  assert(set != NULL);
18854  assert(lp != NULL);
18855 
18856  /* avoid to compare two different infinities; the reason for that is
18857  * that such a comparison can lead to unexpected results */
18858  assert( ((!SCIPsetIsInfinity(set, val1) || !SCIPsetIsInfinity(set, val2))
18859  && (!SCIPsetIsInfinity(set, -val1) || !SCIPsetIsInfinity(set, -val2)))
18860  || val1 == val2 ); /*lint !e777*/
18861 
18862  return EPSGE(val1, val2, lp->feastol);
18863 }
18864 
18865 /** checks, if value is in range LP primal feasibility tolerance of 0.0 */
18867  SCIP_LP* lp, /**< current LP data */
18868  SCIP_Real val /**< value to process */
18869  )
18870 {
18871  assert(lp != NULL);
18872 
18873  return EPSZ(val, lp->feastol);
18874 }
18875 
18876 /** checks, if value is greater than LP primal feasibility tolerance */
18878  SCIP_LP* lp, /**< current LP data */
18879  SCIP_Real val /**< value to process */
18880  )
18881 {
18882  assert(lp != NULL);
18883 
18884  return EPSP(val, lp->feastol);
18885 }
18886 
18887 /** checks, if value is lower than -LP primal feasibility tolerance */
18889  SCIP_LP* lp, /**< current LP data */
18890  SCIP_Real val /**< value to process */
18891  )
18892 {
18893  assert(lp != NULL);
18894 
18895  return EPSN(val, lp->feastol);
18896 }
static SCIP_RETCODE lpRestoreSolVals(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_Longint validlp)
Definition: lp.c:401
SCIP_Bool SCIPsetIsUpdateUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: set.c:7323
SCIP_Longint nprimallps
Definition: struct_stat.h:185
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17387
SCIP_Bool solisbasic
Definition: struct_lp.h:363
SCIP_Real lazyub
Definition: struct_lp.h:134
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1812
SCIP_Longint ndualresolvelpiterations
Definition: struct_stat.h:61
SCIP_Bool lpissolved
Definition: struct_lp.h:116
int nunlinked
Definition: struct_lp.h:228
static SCIP_RETCODE computeRelIntPoint(SCIP_LPI *lpi, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_LP *lp, SCIP_PROB *prob, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_Real *point, SCIP_Bool *success)
Definition: lp.c:17867
void SCIPcolMarkNotRemovableLocal(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4746
int firstnewrow
Definition: struct_lp.h:327
SCIP_RETCODE SCIPlpGetProvedLowerbound(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *bound)
Definition: lp.c:16457
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6503
SCIP_Real sbup
Definition: struct_lp.h:145
void SCIPlpInvalidateRootObjval(SCIP_LP *lp)
Definition: lp.c:13171
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:4702
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3262
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:93
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_clp.cpp:1408
void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:10276
int nsbcalls
Definition: struct_lp.h:167
SCIP_Bool primalchecked
Definition: struct_lp.h:112
static SCIP_RETCODE lpStoreSolVals(SCIP_LP *lp, SCIP_STAT *stat, BMS_BLKMEM *blkmem)
Definition: lp.c:367
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6206
SCIP_Bool SCIPsetIsSumGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6509
static SCIP_RETCODE lpSetBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value, SCIP_Bool *success)
Definition: lp.c:2536
static SCIP_RETCODE lpSetFastmip(SCIP_LP *lp, int fastmip, SCIP_Bool *success)
Definition: lp.c:2855
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6698
SCIP_RETCODE SCIPcolGetStrongbranch(SCIP_COL *col, SCIP_Bool integral, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LP *lp, int itlim, SCIP_Bool updatecol, SCIP_Bool updatestat, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *lperror)
Definition: lp.c:4294
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:461
static SCIP_RETCODE lpSetDualfeastol(SCIP_LP *lp, SCIP_Real dualfeastol, SCIP_Bool *success)
Definition: lp.c:2743
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:13705
SCIP_Real maxactivity
Definition: struct_lp.h:209
static void colUpdateDelLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8932
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:885
internal methods for managing events
SCIP_RETCODE SCIPlpFreeNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10172
SCIP_Real obj
Definition: struct_lp.h:128
SCIP_Bool SCIPlpDivingRowsChanged(SCIP_LP *lp)
Definition: lp.c:17855
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_clp.cpp:634
static SCIP_RETCODE lpSetFromscratch(SCIP_LP *lp, SCIP_Bool fromscratch, SCIP_Bool *success)
Definition: lp.c:2830
static int SCIProwGetDiscreteScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7360
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6264
int SCIPlpGetNNewrows(SCIP_LP *lp)
Definition: lp.c:17631
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6714
SCIP_Longint validdegeneracylp
Definition: struct_lp.h:305
internal methods for storing primal CIP solutions
static SCIP_RETCODE lpSetRowrepswitch(SCIP_LP *lp, SCIP_Real rowrepswitch, SCIP_Bool *success)
Definition: lp.c:2961
SCIP_Real SCIProwGetScalarProduct(SCIP_ROW *row1, SCIP_ROW *row2)
Definition: lp.c:7003
void * origin
Definition: struct_lp.h:216
SCIP_EVENTFILTER * eventfilter
Definition: struct_lp.h:222
static SCIP_RETCODE rowScale(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Real scaleval, SCIP_Bool integralcontvars, SCIP_Real minrounddelta, SCIP_Real maxrounddelta)
Definition: lp.c:4935
SCIP_RETCODE SCIPlpUpdateAddVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14008
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3415
SCIP_STATUS status
Definition: struct_stat.h:177
SCIP_Longint nlpiterations
Definition: struct_stat.h:53
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:17813
SCIP_Real farkascoef
Definition: struct_lp.h:141
unsigned int ubchanged
Definition: struct_lp.h:175
static SCIP_RETCODE colChgCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:1855
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_RETCODE SCIPlpShrinkRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int newnrows)
Definition: lp.c:9700
int nummaxval
Definition: struct_lp.h:236
void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
Definition: lp.c:17750
SCIP_Longint validactivitylp
Definition: struct_lp.h:223
int lpifirstchgrow
Definition: struct_lp.h:312
static SCIP_RETCODE colUnlink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2388
SCIP_Bool SCIPsetIsSumZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6527
static SCIP_Bool isNewValueUnreliable(SCIP_SET *set, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: lp.c:3639
int SCIProwGetAge(SCIP_ROW *row)
Definition: lp.c:17337
static void rowSwapCoefs(SCIP_ROW *row, int pos1, int pos2)
Definition: lp.c:1392
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17442
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:101
SCIP_Longint nnumtroublelpmsgs
Definition: struct_stat.h:201
SCIP_Real SCIPsetFeastol(SCIP_SET *set)
Definition: set.c:6113
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6682
enum SCIP_LPAlgo SCIP_LPALGO
Definition: type_lp.h:79
int * cols_index
Definition: struct_lp.h:219
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_clp.cpp:3596
void SCIPlpEndStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16324
int nremovablecols
Definition: struct_lp.h:322
char * name
Definition: struct_var.h:226
unsigned int SCIPsetInitializeRandomSeed(SCIP_SET *set, unsigned int initialseedvalue)
Definition: set.c:7400
static SCIP_RETCODE lpCleanupCols(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, int firstcol)
Definition: lp.c:15679
SCIP_Bool primalfeasible
Definition: struct_lp.h:359
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:18569
static SCIP_Real getFiniteLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:896
static SCIP_RETCODE lpSetConditionLimit(SCIP_LP *lp, SCIP_Real condlimit, SCIP_Bool *success)
Definition: lp.c:3110
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:904
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_clp.cpp:2843
int nchgrows
Definition: struct_lp.h:316
static SCIP_RETCODE ensureLpirowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:228
SCIP_RETCODE SCIPlpGetBInvCol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9867
char * name
Definition: struct_lp.h:217
SCIP_Real SCIPvarGetUbLazy(SCIP_VAR *var)
Definition: var.c:18058
SCIP_Real SCIProwGetRelaxFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6269
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:3508
int nlpicols
Definition: struct_lp.h:308
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6604
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1992
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_clp.cpp:2774
static SCIP_RETCODE rowStoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Bool infeasible)
Definition: lp.c:535
enum SCIP_BaseStat SCIP_BASESTAT
Definition: type_lpi.h:87
SCIP_RETCODE SCIPlpRemoveAllObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15648
SCIP_Real SCIProwGetPseudoActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6417
void SCIPlpSetRootLPIsRelax(SCIP_LP *lp, SCIP_Bool isrelax)
Definition: lp.c:17685
SCIP_Longint nlps
Definition: struct_stat.h:183
SCIP_Longint activeinlpcounter
Definition: struct_lp.h:213
SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
Definition: event.c:2231
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
SCIP_Bool SCIProwIsRedundant(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6635
SCIP_LPALGO lastlpalgo
Definition: struct_lp.h:345
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_clp.cpp:3678
#define SCIP_MAXSTRLEN
Definition: def.h:293
static SCIP_RETCODE lpFlushAddCols(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8000
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition: lp.c:16997
void SCIProwRecalcLPActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6167
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1796
void SCIPlpRecalculateObjSqrNorm(SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:17642
enum SCIP_RowOriginType SCIP_ROWORIGINTYPE
Definition: type_lp.h:69
internal methods for clocks and timing issues
SCIP_RETCODE SCIPlpInterrupt(SCIP_LP *lp, SCIP_Bool interrupt)
Definition: lp.c:10112
unsigned int origintype
Definition: struct_lp.h:256
static void getObjvalDeltaUb(SCIP_SET *set, SCIP_Real obj, SCIP_Real oldub, SCIP_Real newub, SCIP_Real *deltaval, int *deltainf)
Definition: lp.c:13582
int lpdepth
Definition: struct_lp.h:232
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17127
SCIP_Longint SCIPcolGetStrongbranchNode(SCIP_COL *col)
Definition: lp.c:17139
SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6329
static long bound
#define debugRowPrint(x, y)
Definition: lp.c:117
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17179
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_clp.cpp:2953
SCIP_Real objsumnorm
Definition: struct_lp.h:284
SCIP_Longint ndivinglps
Definition: struct_stat.h:198
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: event.c:1970
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_ROW ** chgrows
Definition: struct_lp.h:291
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5334
SCIP_COL ** chgcols
Definition: struct_lp.h:290
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:5580
static SCIP_RETCODE lpDelColset(SCIP_LP *lp, SCIP_SET *set, int *coldstat)
Definition: lp.c:15268
SCIP_RETCODE SCIPlpGetIterations(SCIP_LP *lp, int *iterations)
Definition: lp.c:15193
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_clp.cpp:1158
static void adjustLPobjval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: lp.c:11989
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17317
int rank
Definition: struct_lp.h:239
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_clp.cpp:3634
static void rowSortLP(SCIP_ROW *row)
Definition: lp.c:1024
interface methods for specific LP solvers
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
void SCIPintervalSub(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:6071
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_clp.cpp:2907
static void colMoveCoef(SCIP_COL *col, int oldpos, int newpos)
Definition: lp.c:1259
int rowssize
Definition: struct_lp.h:324
static void rowUpdateAddLP(SCIP_ROW *row)
Definition: lp.c:8897
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3693
static void markColDeleted(SCIP_COL *col)
Definition: lp.c:7892
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17511
SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13250
SCIP_RETCODE SCIPlpGetDualfarkas(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *valid)
Definition: lp.c:15018
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13899
static SCIP_RETCODE lpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14187
SCIP_RETCODE SCIProwEnsureSize(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:620
static void lpNumericalTroubleMessage(SCIP_MESSAGEHDLR *messagehdlr, SCIP_SET *set, SCIP_STAT *stat, SCIP_VERBLEVEL verblevel, const char *formatstr,...)
Definition: lp.c:11492
unsigned int nonlprowssorted
Definition: struct_lp.h:172
int nclockskipsleft
Definition: struct_stat.h:266
SCIP_COL ** cols
Definition: struct_lp.h:292
SCIP_RETCODE SCIPlpFreeState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10095
static void colSwapCoefs(SCIP_COL *col, int pos1, int pos2)
Definition: lp.c:1295
int nlpirows
Definition: struct_lp.h:311
#define lpCutoffDisabled(set, prob)
Definition: lp.c:2641
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:105
#define SCIP_EVENTTYPE_ROWCHANGED
Definition: type_event.h:139
int soldirectionsize
Definition: struct_lp.h:318
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition: lp.c:17193
#define debugColPrint(x, y)
Definition: lp.c:150
SCIP_RETCODE SCIPcolCreate(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var, int len, SCIP_ROW **rows, SCIP_Real *vals, SCIP_Bool removable)
Definition: lp.c:3274
static const int nscalars
Definition: lp.c:5739
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:10291
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
enum SCIP_ClockType SCIP_CLOCKTYPE
Definition: type_clock.h:38
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13872
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17258
SCIP_ROW ** rows
Definition: struct_lp.h:152
#define FALSE
Definition: def.h:87
int lppos
Definition: struct_lp.h:163
SCIP_Real lazylb
Definition: struct_lp.h:132
void SCIPsortIntPtrIntReal(int *intarray1, void **ptrarray, int *intarray2, SCIP_Real *realarray, int len)
SCIP_RETCODE SCIPlpWrite(SCIP_LP *lp, const char *fname)
Definition: lp.c:16493
#define EPSEQ(x, y, eps)
Definition: def.h:202
#define EPSISINT(x, eps)
Definition: def.h:214
int pseudoobjvalinf
Definition: struct_lp.h:331
SCIP_Bool SCIPlpIsSolBasic(SCIP_LP *lp)
Definition: lp.c:17803
static SCIP_RETCODE ensureLazycolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:294
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13940
datastructures for managing events
SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6747
static void recomputeLooseObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:770
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition: lp.c:17038
static SCIP_RETCODE insertColChgcols(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:3614
int divinglpiitlim
Definition: struct_lp.h:335
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition: lp.c:16939
SCIP_Bool solved
Definition: struct_lp.h:358
static SCIP_RETCODE colAddCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real val, int linkpos)
Definition: lp.c:1689
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11063
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
SCIP_Longint nrootlps
Definition: struct_stat.h:184
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition: lp.c:17306
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
Definition: lp.c:16919
SCIP_Bool dualchecked
Definition: struct_lp.h:362
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6318
SCIP_RETCODE SCIPlpIsInfeasibilityProved(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool *proved)
Definition: lp.c:16471
#define TRUE
Definition: def.h:86
#define SCIPdebug(x)
Definition: pub_message.h:84
static SCIP_RETCODE lpFlushAddRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8223
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Bool lpifromscratch
Definition: struct_lp.h:376
unsigned int basisstatus
Definition: struct_lp.h:241
static SCIP_RETCODE lpSetBarrierconvtol(SCIP_LP *lp, SCIP_Real barrierconvtol, SCIP_Bool *success)
Definition: lp.c:2786
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6803
SCIP_RETCODE SCIPlpGetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lp.c:10028
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_clp.cpp:3819
SCIP_Real SCIPlpGetRootColumnObjval(SCIP_LP *lp)
Definition: lp.c:17718
#define EPSP(x, eps)
Definition: def.h:208
void SCIPlpStartStrongbranchProbing(SCIP_LP *lp)
Definition: lp.c:16311
SCIP_Real dualsol
Definition: struct_lp.h:98
static SCIP_RETCODE lpSetObjlim(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real objlim, SCIP_Bool *success)
Definition: lp.c:2648
SCIP_Real redcost
Definition: struct_lp.h:140
#define SCIPsetAllocBufferArray(set, ptr, num)
Definition: set.h:1725
#define BMSfreeBlockMemoryNull(mem, ptr)
Definition: memory.h:459
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2454
static SCIP_RETCODE lpCheckIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value)
Definition: lp.c:2576
SCIP_RETCODE SCIProwChgCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val)
Definition: lp.c:5471
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17600
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3578
SCIP_Bool SCIPlpIsFeasLE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18806
SCIP_Bool pseudoobjvalid
Definition: struct_lp.h:351
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:16254
unsigned int delaysort
Definition: struct_lp.h:244
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5785
#define SCIP_UNUSED(x)
Definition: def.h:438
unsigned int basisstatus
Definition: struct_lp.h:170
int SCIPcolGetLPDepth(SCIP_COL *col)
Definition: lp.c:17070
SCIP_Real lpidualfeastol
Definition: struct_lp.h:279
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
SCIP_RETCODE SCIPlpRemoveNewObsoletes(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15617
SCIP_Real sbsolval
Definition: struct_lp.h:146
SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6415
static SCIP_RETCODE lpSetLPInfo(SCIP_LP *lp, SCIP_Bool lpinfo)
Definition: lp.c:3087
static void freeDiveChgSideArrays(SCIP_LP *lp)
Definition: lp.c:9053
SCIP_Real sumnorm
Definition: struct_lp.h:200
int lpifastmip
Definition: struct_lp.h:337
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_clp.cpp:1426
public methods for problem variables
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
SCIP_Real SCIProwGetNLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6959
static void rowAddNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool updateidxvals)
Definition: lp.c:1899
SCIP_RETCODE SCIPlpEndDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_VAR **vars, int nvars)
Definition: lp.c:16075
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:5976
int index
Definition: struct_lp.h:158
SCIP_Real relpseudoobjval
Definition: struct_lp.h:272
static SCIP_RETCODE lpSetPresolving(SCIP_LP *lp, SCIP_Bool presolving, SCIP_Bool *success)
Definition: lp.c:2936
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
SCIP_Real dualfarkas
Definition: struct_lp.h:206
#define EPSGE(x, y, eps)
Definition: def.h:206
SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool *lperror)
Definition: lp.c:12404
SCIP_Real minprimsol
Definition: struct_lp.h:142
SCIP_CLOCK * barrierlptime
Definition: struct_stat.h:158
static SCIP_RETCODE updateLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12322
SCIP_Real SCIPsetRelaxfeastol(SCIP_SET *set)
Definition: set.c:6185
SCIP_Real pseudoobjval
Definition: struct_lp.h:270
SCIP_ROW ** SCIPlpGetRows(SCIP_LP *lp)
Definition: lp.c:17578
SCIP_Bool diving
Definition: struct_lp.h:371
#define SCIPdebugMessage
Definition: pub_message.h:87
static SCIP_RETCODE lpFlushDelCols(SCIP_LP *lp)
Definition: lp.c:7914
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:13623
SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13282
SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
Definition: lp.c:6746
SCIP_Real rootlooseobjval
Definition: struct_lp.h:274
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_clp.cpp:1700
SCIP_RETCODE SCIPcolIncCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row, SCIP_Real incval)
Definition: lp.c:3559
int firstnewcol
Definition: struct_lp.h:323
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:15856
SCIP_CONS * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17407
SCIP_RETCODE SCIPcolDelCoef(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_ROW *row)
Definition: lp.c:3463
SCIP_Real SCIPlpGetCutoffbound(SCIP_LP *lp)
Definition: lp.c:10186
unsigned int coefchanged
Definition: struct_lp.h:176
SCIP_RETCODE SCIPlpUpdateAges(SCIP_LP *lp, SCIP_STAT *stat)
Definition: lp.c:15208
void SCIPintervalAdd(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
unsigned int integral
Definition: struct_lp.h:249
static SCIP_RETCODE colStoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem)
Definition: lp.c:461
SCIP_RETCODE SCIPlpSetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lp.c:10152
static int colSearchCoef(SCIP_COL *col, const SCIP_ROW *row)
Definition: lp.c:1128
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:102
SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6340
SCIP_ROWORIGINTYPE SCIProwGetOrigintype(SCIP_ROW *row)
Definition: lp.c:17397
static SCIP_RETCODE lpSetPricing(SCIP_LP *lp, SCIP_PRICING pricing)
Definition: lp.c:3022
static void rowSortNonLP(SCIP_ROW *row)
Definition: lp.c:1057
#define SCIP_LONGINT_MAX
Definition: def.h:163
static SCIP_RETCODE ensureChgcolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:159
int lpifirstchgcol
Definition: struct_lp.h:309
int index
Definition: struct_lp.h:224
#define SCIPsetFreeBufferArray(set, ptr)
Definition: set.h:1732
unsigned int basisstatus
Definition: struct_lp.h:100
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:42
#define BMSfreeMemory(ptr)
Definition: memory.h:138
SCIP_RETCODE SCIPlpEndProbing(SCIP_LP *lp)
Definition: lp.c:16296
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_clp.cpp:471
static SCIP_RETCODE lpSetRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value, SCIP_Bool *success)
Definition: lp.c:2548
#define checkRow(row)
Definition: lp.c:686
SCIP_Real SCIPsetSumFloor(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6560
int maxdepth
Definition: struct_stat.h:227
static SCIP_RETCODE reallocDiveChgSideArrays(SCIP_LP *lp, int minsize, SCIP_Real growfact)
Definition: lp.c:9027
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
int looseobjvalinf
Definition: struct_lp.h:328
SCIP_Real obj
Definition: struct_var.h:200
SCIP_Bool flushdeletedcols
Definition: struct_lp.h:352
unsigned int rhschanged
Definition: struct_lp.h:247
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:5523
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17278
int nlpcols
Definition: struct_lp.h:227
SCIP_COL ** lpicols
Definition: struct_lp.h:288
unsigned int lprowssorted
Definition: struct_lp.h:171
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13083
static SCIP_RETCODE ensureSoldirectionSize(SCIP_LP *lp, int num)
Definition: lp.c:274
#define SCIPstatIncrement(stat, set, field)
Definition: stat.h:251
SCIP_Longint SCIPcolGetStrongbranchLPAge(SCIP_COL *col, SCIP_STAT *stat)
Definition: lp.c:4734
internal methods for LP management
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_clp.cpp:522
int lazycolssize
Definition: struct_lp.h:320
static SCIP_RETCODE lpUpdateVarColumnProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14100
Definition: heur_padm.c:123
static void recomputeGlbPseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:854
SCIP_Real objprod
Definition: struct_lp.h:201
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3300
SCIP_Bool SCIPlpIsRootLPRelax(SCIP_LP *lp)
Definition: lp.c:17696
int colssize
Definition: struct_lp.h:317
SCIP_Bool objsqrnormunreliable
Definition: struct_lp.h:346
SCIP_RETCODE SCIPlpRecordOldRowSideDive(SCIP_LP *lp, SCIP_ROW *row, SCIP_SIDETYPE sidetype)
Definition: lp.c:16257
SCIP_Bool lpihasfastmip
Definition: struct_lp.h:382
SCIP_Bool divelpwasdualfeas
Definition: struct_lp.h:392
SCIP_Bool lpipresolving
Definition: struct_lp.h:377
int nremovablerows
Definition: struct_lp.h:326
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:749
SCIP_Bool primalchecked
Definition: struct_lp.h:360
real eps
SCIP_Bool strongbranching
Definition: struct_lp.h:368
SCIP_Real SCIPsolGetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_VAR *var)
Definition: sol.c:1338
SCIP_Bool dualfeasible
Definition: struct_lp.h:113
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2474
#define checkLinks(lp)
Definition: lp.c:1615
int lpithreads
Definition: struct_lp.h:338
int ndivechgsides
Definition: struct_lp.h:333
int SCIPlpGetNCols(SCIP_LP *lp)
Definition: lp.c:17541
static void checkLazyBounds(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:12295
int * linkpos
Definition: struct_lp.h:221
#define FEASTOLTIGHTFAC
Definition: lp.c:11571
#define SCIP_DEFAULT_EPSILON
Definition: def.h:183
static SCIP_RETCODE lpSolveStable(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_LPALGO lpalgo, int itlim, int harditlim, SCIP_Bool resolve, int fastmip, SCIP_Bool tightprimfeastol, SCIP_Bool tightdualfeastol, SCIP_Bool fromscratch, SCIP_Bool keepsol, SCIP_Bool *timelimit, SCIP_Bool *lperror)
Definition: lp.c:11574
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6300
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2738
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17489
SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
Definition: set.c:7068
static SCIP_RETCODE colLink(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2344
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int integral
Definition: struct_lp.h:177
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:9295
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:4304
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:1871
int nloosevars
Definition: struct_lp.h:329
static void rowDelNorms(SCIP_ROW *row, SCIP_SET *set, SCIP_COL *col, SCIP_Real val, SCIP_Bool forcenormupdate, SCIP_Bool updateindex, SCIP_Bool updateval)
Definition: lp.c:1976
SCIP_Bool SCIPlpIsFeasEQ(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18766
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2633
SCIP_Real SCIPlpGetRootObjval(SCIP_LP *lp)
Definition: lp.c:17706
SCIP_Real SCIPcolCalcRedcost(SCIP_COL *col, SCIP_Real *dualsol)
Definition: lp.c:3842
static void rowCalcIdxsAndVals(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4825
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
int lppos
Definition: struct_lp.h:230
void SCIProwForceSort(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6154
int divechgsidessize
Definition: struct_lp.h:334
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6246
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:15817
int * linkpos
Definition: struct_lp.h:157
SCIP_Bool rootlpisrelax
Definition: struct_lp.h:364
SCIP_Bool SCIPsetIsSumLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6473
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_clp.cpp:905
SCIP_Real flushedlb
Definition: struct_lp.h:137
SCIP_Real inf
Definition: intervalarith.h:46
int lpiitlim
Definition: struct_lp.h:336
SCIP_Real lb
Definition: struct_lp.h:129
SCIP_Real dualsol
Definition: struct_lp.h:204
SCIP_RETCODE SCIProwCatchEvent(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: lp.c:7828
int SCIPcolGetAge(SCIP_COL *col)
Definition: lp.c:17159
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_clp.cpp:3987
SCIP_Real lpibarrierconvtol
Definition: struct_lp.h:280
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:3442
int glbpseudoobjvalinf
Definition: struct_lp.h:330
#define EPSN(x, eps)
Definition: def.h:209
int SCIPlpGetNNewcols(SCIP_LP *lp)
Definition: lp.c:17609
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13967
SCIP_Real SCIProwGetSumNorm(SCIP_ROW *row)
Definition: lp.c:17246
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:455
static SCIP_RETCODE rowUnlink(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:2470
static SCIP_RETCODE lpUpdateVarLooseProved(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14232
static SCIP_RETCODE colRestoreSolVals(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer)
Definition: lp.c:488
SCIP_RETCODE SCIPlpStartDive(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:15969
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:16962
SCIP_Real sbdown
Definition: struct_lp.h:144
int SCIProwGetMinidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6714
SCIP_RETCODE SCIPlpStartProbing(SCIP_LP *lp)
Definition: lp.c:16281
SCIP_RETCODE SCIProwChgLhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real lhs)
Definition: lp.c:5661
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6011
int lpirefactorinterval
Definition: struct_lp.h:342
SCIP_ROW ** divechgrows
Definition: struct_lp.h:299
SCIP_Real lpirowrepswitch
Definition: struct_lp.h:388
SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue)
Definition: lp.c:8666
static SCIP_RETCODE lpFlushDelRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: lp.c:8174
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: event.c:1877
SCIP_RETCODE SCIPlpWriteMip(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *fname, SCIP_Bool genericnames, SCIP_Bool origobj, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_Bool lazyconss)
Definition: lp.c:16508
SCIP_Bool installing
Definition: struct_lp.h:367
SCIP_Bool divelpwasdualchecked
Definition: struct_lp.h:393
SCIP_Bool SCIPlpIsPrimalReliable(SCIP_LP *lp)
Definition: lp.c:17783
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17169
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:4895
#define SCIPerrorMessage
Definition: pub_message.h:55
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:669
static SCIP_RETCODE lpSetSolutionPolishing(SCIP_LP *lp, SCIP_Bool polishing, SCIP_Bool *success)
Definition: lp.c:3224
void SCIPlpDecNLoosevars(SCIP_LP *lp)
Definition: lp.c:14310
interval arithmetics for provable bounds
SCIP_Bool SCIPlpIsDualReliable(SCIP_LP *lp)
Definition: lp.c:17793
SCIP_Real sqrnorm
Definition: struct_lp.h:199
SCIP_Longint lpcount
Definition: struct_stat.h:181
SCIP_Bool lpilpinfo
Definition: struct_lp.h:378
void SCIPsortPtrRealInt(void **ptrarray, SCIP_Real *realarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17117
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_clp.cpp:3175
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2290
SCIP_Real pseudoactivity
Definition: struct_lp.h:207
SCIP_PRICING lpipricing
Definition: struct_lp.h:343
SCIP_RETCODE SCIPlpAddCol(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, int depth)
Definition: lp.c:9445
SCIP_Bool dualchecked
Definition: struct_lp.h:114
SCIP_COL ** cols
Definition: struct_lp.h:218
static void colSortNonLP(SCIP_COL *col)
Definition: lp.c:993
SCIP_RETCODE SCIPlpShrinkCols(SCIP_LP *lp, SCIP_SET *set, int newncols)
Definition: lp.c:9628
SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
Definition: lp.c:17531
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17367
SCIP_Bool adjustlpval
Definition: struct_lp.h:375
SCIP_Real minval
Definition: struct_lp.h:203
static SCIP_Real colCalcInternalFarkasCoef(SCIP_COL *col)
Definition: lp.c:4077
SCIP_Real flushedub
Definition: struct_lp.h:138
SCIP_ROW ** lpirows
Definition: struct_lp.h:289
unsigned int sbupvalid
Definition: struct_lp.h:181
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3489
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:189
SCIP_Longint validsoldirlp
Definition: struct_lp.h:304
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:15746
static SCIP_RETCODE lpCopyIntegrality(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8618
SCIP_RETCODE SCIProwChgLocal(SCIP_ROW *row, SCIP_Bool local)
Definition: lp.c:5725
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_Longint validfarkaslp
Definition: struct_lp.h:303
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:9942
SCIP_Longint validactivitybdsdomchg
Definition: struct_lp.h:211
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2488
void SCIPlpMarkSize(SCIP_LP *lp)
Definition: lp.c:9785
SCIP_Real SCIPsetBarrierconvtol(SCIP_SET *set)
Definition: set.c:6141
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition: lp.c:16929
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:104
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:164
int nuses
Definition: struct_lp.h:229
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
int lpiscaling
Definition: struct_lp.h:341
static SCIP_RETCODE rowAddCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col, SCIP_Real val, int linkpos)
Definition: lp.c:2034
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:429
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:17357
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2269
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
SCIP_Real SCIProwGetNLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6331
SCIP_RETCODE SCIPlpGetUnboundedSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *rayfeasible)
Definition: lp.c:14634
SCIP_Real SCIPintervalGetInf(SCIP_INTERVAL interval)
SCIP_RETCODE SCIPlpSetState(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue, SCIP_LPISTATE *lpistate, SCIP_Bool wasprimfeas, SCIP_Bool wasprimchecked, SCIP_Bool wasdualfeas, SCIP_Bool wasdualchecked)
Definition: lp.c:10052
void SCIProwDelaySort(SCIP_ROW *row)
Definition: lp.c:6143
SCIP_Real cutoffbound
Definition: struct_lp.h:275
SCIP_Real SCIProwGetPseudoFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6445
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:9504
internal miscellaneous methods
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_Bool isrelax
Definition: struct_lp.h:365
SCIP_Real SCIPlpGetObjNorm(SCIP_LP *lp)
Definition: lp.c:17673
SCIP_Longint nprimalresolvelpiterations
Definition: struct_stat.h:60
SCIP_Bool SCIPsetIsDualfeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6881
int numintcols
Definition: struct_lp.h:235
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2336
SCIP_Bool userinterrupt
Definition: struct_stat.h:269
#define REALABS(x)
Definition: def.h:201
int maxidx
Definition: struct_lp.h:234
SCIP_LPSOLVALS * storedsolvals
Definition: struct_lp.h:300
static SCIP_RETCODE lpSetFeastol(SCIP_LP *lp, SCIP_Real feastol, SCIP_Bool *success)
Definition: lp.c:2700
SCIP_Bool looseobjvalid
Definition: struct_lp.h:349
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:384
void SCIPlpSetFeastol(SCIP_LP *lp, SCIP_SET *set, SCIP_Real newfeastol)
Definition: lp.c:10251
SCIP_Real activity
Definition: struct_lp.h:99
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6692
SCIP_Real SCIPvarGetLbLazy(SCIP_VAR *var)
Definition: var.c:18048
static void rowCalcActivityBounds(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6521
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_clp.cpp:2391
int SCIPlpGetNRows(SCIP_LP *lp)
Definition: lp.c:17588
int lpirandomseed
Definition: struct_lp.h:340
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:585
SCIP_Longint nlpsaftercreation
Definition: struct_lp.h:214
void SCIPlpMarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17833
SCIP_Longint nduallpiterations
Definition: struct_stat.h:57
SCIP_Bool flushaddedrows
Definition: struct_lp.h:355
SCIP_Bool resolvelperror
Definition: struct_lp.h:374
unsigned int removable
Definition: struct_lp.h:178
#define SCIPstatAdd(stat, set, field, val)
Definition: stat.h:271
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17268
static SCIP_RETCODE lpFlushChgCols(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8371
#define MAXNUMTROUBLELPMSGS
Definition: lp.c:11483
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_clp.cpp:3609
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_clp.cpp:977
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6228
int lpicolssize
Definition: struct_lp.h:307
SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
Definition: lp.c:17740
SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13099
SCIP_LPI * lpi
Definition: struct_lp.h:287
SCIP_Bool SCIPlpIsFeasNegative(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18888
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5294
static SCIP_RETCODE rowLink(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:2427
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17377
static SCIP_RETCODE colDelCoefPos(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, int pos)
Definition: lp.c:1810
SCIP_Real glbpseudoobjval
Definition: struct_lp.h:267
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6648
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:17204
SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
Definition: lp.c:6903
SCIP_Longint nprimalresolvelps
Definition: struct_stat.h:192
SCIP_SIDETYPE * divechgsidetypes
Definition: struct_lp.h:298
static SCIP_RETCODE rowSideChanged(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp, SCIP_SIDETYPE sidetype)
Definition: lp.c:2291
SCIP_RETCODE SCIPlpStartStrongbranch(SCIP_LP *lp)
Definition: lp.c:4175
int SCIProwGetNumIntCols(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6730
SCIP_CLOCK * divinglptime
Definition: struct_stat.h:160
static SCIP_RETCODE rowEventSideChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1515
static SCIP_RETCODE allocDiveChgSideArrays(SCIP_LP *lp, int initsize)
Definition: lp.c:9005
static void colUpdateAddLP(SCIP_COL *col, SCIP_SET *set)
Definition: lp.c:8857
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5347
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:12020
SCIP_Longint nduallps
Definition: struct_stat.h:187
SCIP_RETCODE SCIPlpGetDualDegeneracy(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
Definition: lp.c:18641
SCIP_RETCODE SCIPlpReset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9410
SCIP_Real SCIProwGetSolActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6461
int SCIPcolGetIndex(SCIP_COL *col)
Definition: lp.c:17018
SCIP_Real sblpobjval
Definition: struct_lp.h:147
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
SCIP_Real SCIPlpGetFeastol(SCIP_LP *lp)
Definition: lp.c:10241
internal methods for problem variables
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2436
static void computeLPBounds(SCIP_LP *lp, SCIP_SET *set, SCIP_COL *col, SCIP_Real lpiinf, SCIP_Real *lb, SCIP_Real *ub)
Definition: lp.c:7965
#define SCIP_UNKNOWN
Definition: def.h:198
SCIP_RETCODE SCIPlpGetBasisInd(SCIP_LP *lp, int *basisind)
Definition: lp.c:9811
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6351
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_clp.cpp:2752
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:17214
int nchgcols
Definition: struct_lp.h:314
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:1009
public data structures and miscellaneous methods
SCIP_Bool SCIPlpIsFeasGT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18826
int len
Definition: struct_lp.h:160
SCIP_Real * soldirection
Definition: struct_lp.h:295
SCIP_Real SCIPlpGetRootLooseObjval(SCIP_LP *lp)
Definition: lp.c:17730
SCIP_RETCODE SCIPlpClear(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:9766
SCIP_Bool SCIPlpIsFeasGE(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18846
#define SCIP_Bool
Definition: def.h:84
void SCIPlpRecomputeLocalAndGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13182
SCIP_Real redcost
Definition: struct_lp.h:87
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_clp.cpp:3508
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_clp.cpp:828
SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
Definition: set.c:6103
SCIP_Longint ndualresolvelps
Definition: struct_stat.h:193
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:447
int numminval
Definition: struct_lp.h:237
int lpipos
Definition: struct_lp.h:231
int size
Definition: struct_lp.h:225
unsigned int modifiable
Definition: struct_lp.h:251
static void recomputePseudoObjectiveValue(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:812
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:3905
void SCIPprintSysError(const char *message)
Definition: misc.c:10664
static SCIP_RETCODE lpDelRowset(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int *rowdstat)
Definition: lp.c:15367
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:9365
SCIP_Real SCIPcolGetBestBound(SCIP_COL *col)
Definition: lp.c:16949
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2595
static void rowMerge(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6044
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:103
static SCIP_Real colCalcInternalRedcost(SCIP_COL *col)
Definition: lp.c:3894
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:971
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_clp.cpp:3375
SCIP_RETCODE SCIPconsRelease(SCIP_CONS **cons, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: cons.c:6203
int chgrowssize
Definition: struct_lp.h:315
int SCIPlpGetNUnfixedCols(SCIP_LP *lp, SCIP_Real eps)
Definition: lp.c:17551
SCIP_ROW ** SCIPlpGetNewrows(SCIP_LP *lp)
Definition: lp.c:17620
SCIP_Real SCIPvarGetNLPSol(SCIP_VAR *var)
Definition: var.c:18297
SCIP_Longint validfarkaslp
Definition: struct_lp.h:155
static SCIP_RETCODE ensureRowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:317
unsigned int lbchanged
Definition: struct_lp.h:174
SCIP_Bool divingobjchg
Definition: struct_lp.h:372
SCIP_RETCODE SCIPlpGetBInvRow(SCIP_LP *lp, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9845
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:460
SCIP_Longint sbnode
Definition: struct_lp.h:148
SCIP_Bool SCIPlpDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17823
SCIP_Real feastol
Definition: struct_lp.h:276
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3752
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3423
#define MAX(x, y)
Definition: tclique_def.h:83
static int colSearchCoefPart(SCIP_COL *col, const SCIP_ROW *row, int minpos, int maxpos)
Definition: lp.c:1092
unsigned int basisstatus
Definition: struct_lp.h:88
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8105
static SCIP_RETCODE lpSetMarkowitz(SCIP_LP *lp, SCIP_Real threshhold, SCIP_Bool *success)
Definition: lp.c:3135
SCIP_Real degeneracy
Definition: struct_lp.h:285
SCIP_Bool updateintegrality
Definition: struct_lp.h:356
SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17768
public methods for LP management
#define DIVESTACKINITSIZE
Definition: lp.c:9070
#define SCIPsetDebugMsg
Definition: set.h:1761
SCIP_Real unchangedobj
Definition: struct_lp.h:131
SCIP_Bool lpihaspolishing
Definition: struct_lp.h:386
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:4205
int minidx
Definition: struct_lp.h:233
SCIP_Bool SCIPcolIsRemovable(SCIP_COL *col)
Definition: lp.c:17049
static SCIP_RETCODE rowDelCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos)
Definition: lp.c:2175
SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
Definition: prob.c:2300
SCIP_Bool divelpwasprimchecked
Definition: struct_lp.h:391
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17758
#define EPSLE(x, y, eps)
Definition: def.h:204
int nlprows
Definition: struct_lp.h:161
SCIP_RETCODE SCIProwDelCoef(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_COL *col)
Definition: lp.c:5425
SCIP_RETCODE SCIPlpCreate(SCIP_LP **lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, const char *name)
Definition: lp.c:9073
SCIP_RETCODE SCIPlpGetBase(SCIP_LP *lp, int *cstat, int *rstat)
Definition: lp.c:9828
unsigned int lpcolssorted
Definition: struct_lp.h:242
SCIP_Bool divinglazyapplied
Definition: struct_lp.h:373
SCIP_Longint validsollp
Definition: struct_lp.h:302
SCIP_RETCODE SCIPsetSetCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, const char *name, char value)
Definition: set.c:3460
void SCIPlpSetSizeMark(SCIP_LP *lp, int nrows, int ncols)
Definition: lp.c:9797
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17291
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17621
SCIP_CLOCK * resolveinstablelptime
Definition: struct_stat.h:159
static void colSortLP(SCIP_COL *col)
Definition: lp.c:960
SCIP_Real SCIPvarGetRelaxSol(SCIP_VAR *var, SCIP_SET *set)
Definition: var.c:13922
datastructures for problem statistics
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6860
SCIP_Real SCIProwGetRelaxEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6919
static SCIP_RETCODE ensureColsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:251
SCIP_Real ub
Definition: struct_lp.h:130
SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
Definition: lp.c:15895
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6626
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2609
SCIP_Bool SCIPsetIsSumEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6437
SCIP_ROW ** rows
Definition: struct_lp.h:294
SCIP_SOL * validsoldirsol
Definition: struct_lp.h:301
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:3797
static int rowSearchCoef(SCIP_ROW *row, const SCIP_COL *col)
Definition: lp.c:1206
SCIP_LPISTATE * divelpistate
Definition: struct_lp.h:296
SCIP_RETCODE SCIPlpGetNorms(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lp.c:10128
SCIP_RETCODE SCIPsetGetCharParam(SCIP_SET *set, const char *name, char *value)
Definition: set.c:3215
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:7852
SCIP_RETCODE SCIPcolFree(SCIP_COL **col, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
Definition: lp.c:3372
void SCIPcolPrint(SCIP_COL *col, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:3402
static int lpGetResolveItlim(SCIP_SET *set, SCIP_STAT *stat, int itlim)
Definition: lp.c:12384
static int rowSearchCoefPart(SCIP_ROW *row, const SCIP_COL *col, int minpos, int maxpos)
Definition: lp.c:1167
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:923
SCIP_Real flushedrhs
Definition: struct_lp.h:198
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition: lp.c:17422
int SCIProwGetRank(SCIP_ROW *row)
Definition: lp.c:17347
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:13410
SCIP_CLOCK * lexduallptime
Definition: struct_stat.h:157
SCIP_Real SCIPcolGetMinPrimsol(SCIP_COL *col)
Definition: lp.c:16975
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_clp.cpp:1075
SCIP_RETCODE 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:4479
#define SCIP_REAL_MAX
Definition: def.h:178
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5373
SCIP_Real maxval
Definition: struct_lp.h:202
SCIP_Bool SCIPsetIsDualfeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6936
SCIP_Real minactivity
Definition: struct_lp.h:208
SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6614
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:13541
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:11263
SCIP_Longint nrootlpiterations
Definition: struct_stat.h:54
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2722
SCIP_Real SCIProwGetParallelism(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7719
#define checkRowObjprod(row)
Definition: lp.c:761
SCIP_Real SCIPlpGetLooseObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13138
static SCIP_RETCODE provedBound(SCIP_LP *lp, SCIP_SET *set, SCIP_Bool usefarkas, SCIP_Real *bound)
Definition: lp.c:16347
static void markRowDeleted(SCIP_ROW *row)
Definition: lp.c:8158
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:13312
unsigned int removable
Definition: struct_lp.h:252
static SCIP_RETCODE rowRestoreSolVals(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_Longint validlp, SCIP_Bool freebuffer, SCIP_Bool infeasible)
Definition: lp.c:572
unsigned int lhschanged
Definition: struct_lp.h:246
SCIP_Real * r
Definition: circlepacking.c:50
static SCIP_RETCODE lpCheckRealpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Real value)
Definition: lp.c:2612
#define EPSLT(x, y, eps)
Definition: def.h:203
SCIP_CLOCK * strongbranchtime
Definition: struct_stat.h:161
methods for sorting joint arrays of various types
SCIP_COL ** lazycols
Definition: struct_lp.h:293
static SCIP_RETCODE rowEventCoefChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1457
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_clp.cpp:2315
SCIP_Real relglbpseudoobjval
Definition: struct_lp.h:269
#define EPSGT(x, y, eps)
Definition: def.h:205
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:17224
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:15465
SCIP_VAR ** b
Definition: circlepacking.c:56
void SCIPlpStoreRootObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:13158
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_clp.cpp:1948
SCIP_Real lpimarkowitz
Definition: struct_lp.h:282
int SCIPcolGetNNonz(SCIP_COL *col)
Definition: lp.c:17092
SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
Definition: lp.c:6844
int age
Definition: struct_lp.h:168
SCIP_Longint validpsactivitydomchg
Definition: struct_lp.h:210
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3410
SCIP_COLSOLVALS * storedsolvals
Definition: struct_lp.h:150
void SCIPconsCapture(SCIP_CONS *cons)
Definition: cons.c:6191
SCIP_Real * vals
Definition: struct_lp.h:153
SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
Definition: lp.c:6593
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_clp.cpp:2818
SCIP_Bool strongbranchprobing
Definition: struct_lp.h:370
SCIP_Real rellooseobjval
Definition: struct_lp.h:265
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:109
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2004
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:17008
static void rowUpdateDelLP(SCIP_ROW *row)
Definition: lp.c:8971
SCIP_RETCODE SCIPlpSetCutoffbound(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob, SCIP_Real cutoffbound)
Definition: lp.c:10196
void SCIPintervalMul(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
static const SCIP_Real scalars[]
Definition: lp.c:5738
int lpipos
Definition: struct_lp.h:164
int chgcolssize
Definition: struct_lp.h:313
int lpitiming
Definition: struct_lp.h:339
internal methods for main solving loop and node processing
void SCIPmessageVFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr, va_list ap)
Definition: message.c:624
SCIP_Longint domchgcount
Definition: struct_stat.h:105
SCIP_ROWSOLVALS * storedsolvals
Definition: struct_lp.h:215
SCIP_Real * divechgsides
Definition: struct_lp.h:297
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:17500
SCIP_RETCODE SCIPlpMarkFlushed(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8729
static void coefChanged(SCIP_ROW *row, SCIP_COL *col, SCIP_LP *lp)
Definition: lp.c:1624
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_clp.cpp:1731
SCIP_Real rootlpobjval
Definition: struct_lp.h:273
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1837
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:143
unsigned int coefchanged
Definition: struct_lp.h:248
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:151
SCIP_Longint nbarrierlps
Definition: struct_stat.h:190
SCIP_Bool flushed
Definition: struct_lp.h:357
static SCIP_RETCODE lpFlushChgRows(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:8519
SCIP_CLOCK * primallptime
Definition: struct_stat.h:155
SCIP_Bool SCIPlpIsFeasPositive(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18877
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13818
SCIP_Real SCIPsetSumCeil(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6571
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:139
int lpdepth
Definition: struct_lp.h:165
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2542
unsigned int inglobalcutpool
Definition: struct_lp.h:253
int nrows
Definition: struct_lp.h:325
#define checkRowSqrnorm(row)
Definition: lp.c:759
static SCIP_RETCODE lpRemoveObsoleteRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, int firstrow)
Definition: lp.c:15541
#define SCIP_DEFAULT_SUMEPSILON
Definition: def.h:184
static SCIP_RETCODE lpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14053
static SCIP_RETCODE ensureChgrowsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:182
public methods for message output
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3335
data structures for LP management
static void rowCalcNorms(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:4766
SCIP_Bool divelpwasprimfeas
Definition: struct_lp.h:390
#define SCIPstatUpdate(stat, set, field, val)
Definition: stat.h:230
SCIP_VAR * a
Definition: circlepacking.c:57
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6249
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6282
datastructures for problem variables
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_clp.cpp:1677
int SCIPcolGetNStrongbranchs(SCIP_COL *col)
Definition: lp.c:17149
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17370
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2676
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17467
int ndivingrows
Definition: struct_lp.h:332
void SCIPintervalSetBounds(SCIP_INTERVAL *resultant, SCIP_Real inf, SCIP_Real sup)
SCIP_Longint divenolddomchgs
Definition: struct_lp.h:306
SCIP_Real lpobjval
Definition: struct_lp.h:262
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:10316
SCIP_Real primsol
Definition: struct_lp.h:86
#define SCIP_Real
Definition: def.h:177
internal methods for problem statistics
SCIP_Bool solisbasic
Definition: struct_lp.h:115
SCIP_VAR ** vars
Definition: struct_prob.h:55
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2507
SCIP_Real flushedobj
Definition: struct_lp.h:136
SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
Definition: lp.c:17773
int size
Definition: struct_lp.h:159
SCIP_Real SCIProwGetObjParallelism(SCIP_ROW *row, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:7795
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6725
SCIP_Longint validsblp
Definition: struct_lp.h:156
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:4028
SCIP_Real lpiobjlim
Definition: struct_lp.h:277
SCIP_VAR ** y
Definition: circlepacking.c:55
SCIP_Real SCIPsetDualfeastol(SCIP_SET *set)
Definition: set.c:6123
#define SCIPsetDebugMsgPrint
Definition: set.h:1762
int lpirowssize
Definition: struct_lp.h:310
SCIP_RETCODE SCIProwCreate(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, const char *name, int len, SCIP_COL **cols, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_ROWORIGINTYPE origintype, void *origin, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: lp.c:5105
int nunlinked
Definition: struct_lp.h:162
SCIP_Real SCIPcolGetFarkasValue(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4156
#define BMSallocMemory(ptr)
Definition: memory.h:111
SCIP_RETCODE SCIPlpUpdateVarLoose(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14289
#define SCIP_INVALID
Definition: def.h:197
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:120
internal methods for constraints and constraint handlers
SCIP_RETCODE SCIProwChgRhs(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real rhs)
Definition: lp.c:5693
SCIP_Real primsol
Definition: struct_lp.h:139
SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
Definition: lp.c:17763
SCIP_CLOCK * duallptime
Definition: struct_stat.h:156
SCIP_Real maxprimsol
Definition: struct_lp.h:143
#define SCIP_Longint
Definition: def.h:162
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18022
SCIP_Bool SCIPsetIsDualfeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6925
static const char * lpalgoName(SCIP_LPALGO lpalgo)
Definition: lp.c:10293
static SCIP_RETCODE lpSetPricingChar(SCIP_LP *lp, char pricingchar)
Definition: lp.c:3045
int SCIProwGetLPDepth(SCIP_ROW *row)
Definition: lp.c:17478
SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
Definition: lp.c:14957
SCIP_Longint nprimallpiterations
Definition: struct_stat.h:56
static SCIP_RETCODE lpSetIterationLimit(SCIP_LP *lp, int itlim)
Definition: lp.c:2986
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:5742
SCIP_Real varconsratio
Definition: struct_lp.h:286
SCIP_Bool lpisolutionpolishing
Definition: struct_lp.h:348
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6670
SCIP_VAR * var
Definition: struct_lp.h:151
SCIP_RETCODE SCIPlpGetBInvARow(SCIP_LP *lp, int r, SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9893
void SCIProwMarkNotRemovableLocal(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:7873
int nlazycols
Definition: struct_lp.h:321
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_clp.cpp:1231
int SCIProwGetIndex(SCIP_ROW *row)
Definition: lp.c:17327
static SCIP_RETCODE colEnsureSize(SCIP_COL *col, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: lp.c:340
SCIP_Bool dualfeasible
Definition: struct_lp.h:361
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6666
SCIP_Real SCIPcolGetFarkasCoef(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4130
SCIP_Real SCIProwGetLPActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6219
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:11545
unsigned int nlocks
Definition: struct_lp.h:255
static SCIP_RETCODE lpSetScaling(SCIP_LP *lp, int scaling, SCIP_Bool *success)
Definition: lp.c:2886
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_clp.cpp:3881
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_clp.cpp:2706
SCIP_Bool SCIPsetIsDualfeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6947
void SCIPcolSort(SCIP_COL *col)
Definition: lp.c:3430
SCIP_Bool SCIPlpIsFeasZero(SCIP_LP *lp, SCIP_Real val)
Definition: lp.c:18866
SCIP_Real SCIPcolGetFeasibility(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3971
SCIP_Longint obsoletenode
Definition: struct_lp.h:149
SCIP_DECL_SORTPTRCOMP(SCIProwComp)
Definition: lp.c:941
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIP_RETCODE SCIPlpGetBInvACol(SCIP_LP *lp, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lp.c:9918
SCIP_RETCODE SCIPlpUpdateVarColumn(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14165
SCIP_Longint obsoletenode
Definition: struct_lp.h:212
SCIP_Longint nnodes
Definition: struct_stat.h:73
SCIP_Real lpifeastol
Definition: struct_lp.h:278
SCIP_Real SCIPlpGetModifiedProvedPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: lp.c:13352
static SCIP_Real getFinitePseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
Definition: lp.c:918
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
void SCIPcolInvalidateStrongbranchData(SCIP_COL *col, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:4259
SCIP_RETCODE SCIPlpUpdateDelVar(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var)
Definition: lp.c:14029
SCIP_Bool SCIPlpIsFeasLT(SCIP_SET *set, SCIP_LP *lp, SCIP_Real val1, SCIP_Real val2)
Definition: lp.c:18786
static SCIP_RETCODE rowEventConstantChanged(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_Real oldval, SCIP_Real newval)
Definition: lp.c:1487
#define SCIP_CALL_ABORT(x)
Definition: def.h:363
static SCIP_RETCODE lpSetRandomseed(SCIP_LP *lp, int randomseed, SCIP_Bool *success)
Definition: lp.c:3194
SCIP_COL ** SCIPlpGetNewcols(SCIP_LP *lp)
Definition: lp.c:17598
SCIP_Real SCIPcolGetMaxPrimsol(SCIP_COL *col)
Definition: lp.c:16985
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:5404
SCIP_Bool primalfeasible
Definition: struct_lp.h:111
unsigned int validminmaxidx
Definition: struct_lp.h:245
SCIP_Real SCIPcolGetRedcost(SCIP_COL *col, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:3947
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_clp.cpp:3227
SCIP_RETCODE SCIPlpGetSol(SCIP_LP *lp, SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lp.c:14328
#define SCIP_ALLOC(x)
Definition: def.h:395
SCIP_Real SCIPlpGetColumnObjval(SCIP_LP *lp)
Definition: lp.c:13127
void SCIProwRecalcPseudoActivity(SCIP_ROW *row, SCIP_STAT *stat)
Definition: lp.c:6390
#define SCIPABORT()
Definition: def.h:356
static SCIP_RETCODE lpSetThreads(SCIP_LP *lp, int threads, SCIP_Bool *success)
Definition: lp.c:2911
SCIP_Bool SCIPsetIsRelGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:7171
static SCIP_RETCODE ensureLpicolsSize(SCIP_LP *lp, SCIP_SET *set, int num)
Definition: lp.c:205
SCIP_LPSOLSTAT lpsolstat
Definition: struct_lp.h:344
static SCIP_RETCODE rowChgCoefPos(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, int pos, SCIP_Real val)
Definition: lp.c:2235
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:17106
SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6837
static SCIP_RETCODE lpSetIntpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, int value, SCIP_Bool *success)
Definition: lp.c:2509
unsigned int nonlpcolssorted
Definition: struct_lp.h:243
int SCIPcolGetLPPos(SCIP_COL *col)
Definition: lp.c:17059
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17442
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:445
SCIP_Bool flushaddedcols
Definition: struct_lp.h:353
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:10665
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17521
SCIP_Bool glbpseudoobjvalid
Definition: struct_lp.h:350
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:10474
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9022
int ncols
Definition: struct_lp.h:319
static SCIP_RETCODE lpCheckBoolpar(SCIP_LP *lp, SCIP_LPPARAM lpparam, SCIP_Bool value)
Definition: lp.c:2601
datastructures for global SCIP settings
SCIP_RETCODE SCIPlpEndStrongbranch(SCIP_LP *lp)
Definition: lp.c:4190
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:17234
SCIP_Real lpobjval
Definition: struct_lp.h:110
void SCIPlpUnmarkDivingObjChanged(SCIP_LP *lp)
Definition: lp.c:17844
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:451
SCIP_Real objsqrnorm
Definition: struct_lp.h:283
SCIP_Real SCIPsetLPFeastolFactor(SCIP_SET *set)
Definition: set.c:6133
static void rowMoveCoef(SCIP_ROW *row, int oldpos, int newpos)
Definition: lp.c:1355
static void lpUpdateObjNorms(SCIP_LP *lp, SCIP_SET *set, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:3657
SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
Definition: lp.c:17081
unsigned int local
Definition: struct_lp.h:250
#define EPSZ(x, eps)
Definition: def.h:207
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_clp.cpp:1638
SCIP_Real activity
Definition: struct_lp.h:205
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_clp.cpp:3782
SCIP_RETCODE SCIProwFree(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5254
SCIP_Bool probing
Definition: struct_lp.h:369
SCIP_Bool flushdeletedrows
Definition: struct_lp.h:354
SCIP_Real looseobjval
Definition: struct_lp.h:263
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238
SCIP_Real SCIProwGetOrthogonality(SCIP_ROW *row1, SCIP_ROW *row2, char orthofunc)
Definition: lp.c:7783
SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6736
static SCIP_RETCODE lpSetRefactorInterval(SCIP_LP *lp, int refactor, SCIP_Bool *success)
Definition: lp.c:3247
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:12206
static void checkLazyColArray(SCIP_LP *lp, SCIP_SET *set)
Definition: lp.c:9575
int SCIPcolGetVarProbindex(SCIP_COL *col)
Definition: lp.c:17028
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:11400
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_clp.cpp:859
SCIP_RETCODE SCIProwAddConstant(SCIP_ROW *row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_Real addval)
Definition: lp.c:5635
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:948
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5388
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:4183
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:142
SCIP_Real SCIPcolCalcFarkasCoef(SCIP_COL *col, SCIP_Real *dualfarkas)
Definition: lp.c:4025
SCIP_Real lpiconditionlimit
Definition: struct_lp.h:281
static SCIP_RETCODE lpSetTiming(SCIP_LP *lp, SCIP_CLOCKTYPE timing, SCIP_Bool enabled, SCIP_Bool *success)
Definition: lp.c:3160
SCIP_Bool SCIProwIsInGlobalCutpool(SCIP_ROW *row)
Definition: lp.c:17457
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58
#define checkRowSumnorm(row)
Definition: lp.c:760